diff --git a/DEPS b/DEPS
index c2105aa4..dc62341 100644
--- a/DEPS
+++ b/DEPS
@@ -205,10 +205,12 @@
   # 1 Choose a version that's not newer than the Ash side so it's thoroughly
   #   tested:
   #   https://chromium-review.googlesource.com/q/%2522Automated+Commit:+LKGM%2522+status:merged
-  # 2 Run additional a few optional tryjobs:
-  #   lacros-amd64-generic-chrome-skylab
-  #   lacros-arm-generic-chrome-skylab
-  'lacros_sdk_version': '14803.0.0',
+  # 2 CL description:
+  # Lacros SDK: Update version <version>
+  #
+  # CQ_INCLUDE_TRYBOTS=luci.chrome.try:lacros-amd64-generic-chrome-skylab
+  # CQ_INCLUDE_TRYBOTS=luci.chrome.try:lacros-arm-generic-chrome-skylab
+  'lacros_sdk_version': '14844.0.0',
 
   # Generate location tag metadata to include in tests result data uploaded
   # to ResultDB. This isn't needed on some configs and the tool that generates
@@ -269,7 +271,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'fb7f03aeac6eddfea329c91ceb1bce1a71e9f902',
+  'skia_revision': 'd3cbea4114aabd84958d6ec9662c2f80c405dc59',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -277,7 +279,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': 'e4a517c923d5b4809e1a8f7c75be5e593c40790f',
+  'angle_revision': '2db4297ad0fb70cfa1f18ac86b3548448ccf14b0',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -296,7 +298,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Fuchsia sdk
   # and whatever else without interference from each other.
-  'fuchsia_version': 'version:8.20220522.3.1',
+  'fuchsia_version': 'version:8.20220523.1.1',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling google-toolbox-for-mac
   # and whatever else without interference from each other.
@@ -348,7 +350,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': 'a2e55b403896db8f13e82c583160b4dd5507789c',
+  'devtools_frontend_revision': 'e2040405a1dcaf52613c0e8ad9d0fc330b276d43',
   # 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.
@@ -1133,7 +1135,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '4e6aa2530fbfa4d8ae2c5d29678079c7e482eeca',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '964f8124b630dec44dae9dbd0a79bf468356578c',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
@@ -1530,7 +1532,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '370def59dcc5b6423f805754160cab7c5b772c2d',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '5a9d84436fccfcb0eaaad6f8c40c851b12c24420',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1705,7 +1707,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '9618103c4aa25ea342ddad65848ff8bb0c1cee9a',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'd91996dd00e1daa060942d18be5a5e10f29a280b',
+    Var('webrtc_git') + '/src.git' + '@' + 'c3fa7c38b2b74cf7b5dd2cc323ccaa8473b50e80',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1778,7 +1780,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@ad19ab17a11480b1a6e0779728a67ac91a79eeaa',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@4169a9720b7c7aad9f7478c9c272a68749bca591',
     'condition': 'checkout_src_internal',
   },
 
@@ -1819,7 +1821,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': '6RkqT0Gy8h6rQBA8h1dG46N_7Iy_5L9CNNdsm7ps5KYC',
+        'version': 'VW8OLMUzhVZlvxnnmL-162Mk66yVLTxDMIuFrZc2HjIC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -1830,7 +1832,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/projector_app/app',
-        'version': 'qJq23XcKB1Y1d24mJ8I7L4SwVgxw6WhfhGFTn7FPx38C',
+        'version': 'LmSSJqjR5Vm1KHfkGZFFVnw5ntNeKIU5LcxHqcFlF_YC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
index a08990f..4c5b393 100644
--- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
+++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -195,6 +195,12 @@
             Flag.baseFeature(AutofillFeatures.AUTOFILL_RATIONALIZE_STREET_ADDRESS_AND_ADDRESS_LINE,
                     "Rationalizes (street address, address line 2) field sequences to "
                             + "(address line1, address line 2)."),
+            Flag.baseFeature(AutofillFeatures.AUTOFILL_FILL_CREDIT_CARD_AS_PER_FORMAT_STRING,
+                    "When enabled, Autofill tries to infer the credit card expiry date format "
+                            + "from the label and placeholder."),
+            Flag.baseFeature(AutofillFeatures.AUTOFILL_CONSIDER_PLACEHOLDER_FOR_PARSING,
+                    "When enabled, Autofill local heuristics consider the placeholder attribute "
+                            + "for determining field types."),
             Flag.baseFeature(FeatureConstants.KEYBOARD_ACCESSORY_PAYMENT_VIRTUAL_CARD_FEATURE,
                     "When enabled, merchant bound virtual cards will be offered in the keyboard "
                             + "accessory."),
diff --git a/ash/components/arc/session/arc_container_client_adapter.cc b/ash/components/arc/session/arc_container_client_adapter.cc
index 1d11471f..bd5b0c1 100644
--- a/ash/components/arc/session/arc_container_client_adapter.cc
+++ b/ash/components/arc/session/arc_container_client_adapter.cc
@@ -122,8 +122,6 @@
     request.set_dalvik_memory_profile(
         ToLoginManagerDalvikMemoryProfile(params.dalvik_memory_profile));
     request.set_arc_custom_tabs_experiment(params.arc_custom_tabs_experiment);
-    request.set_disable_system_default_app(
-        params.arc_disable_system_default_app);
     request.set_disable_media_store_maintenance(
         params.disable_media_store_maintenance);
     request.set_disable_download_provider(params.disable_download_provider);
diff --git a/ash/components/arc/session/arc_session_impl.cc b/ash/components/arc/session/arc_session_impl.cc
index 434c0f6..3756016 100644
--- a/ash/components/arc/session/arc_session_impl.cc
+++ b/ash/components/arc/session/arc_session_impl.cc
@@ -489,12 +489,6 @@
     }
   }
 
-  params.arc_disable_system_default_app =
-      base::CommandLine::ForCurrentProcess()->HasSwitch(
-          ash::switches::kArcDisableSystemDefaultApps);
-  if (params.arc_disable_system_default_app)
-    VLOG(1) << "System default app(s) are disabled";
-
   params.disable_media_store_maintenance =
       base::CommandLine::ForCurrentProcess()->HasSwitch(
           ash::switches::kArcDisableMediaStoreMaintenance);
diff --git a/ash/components/arc/session/arc_start_params.h b/ash/components/arc/session/arc_start_params.h
index 9b083c1..e329370 100644
--- a/ash/components/arc/session/arc_start_params.h
+++ b/ash/components/arc/session/arc_start_params.h
@@ -69,9 +69,6 @@
   // Experiment flag for ARC Custom Tabs.
   bool arc_custom_tabs_experiment = false;
 
-  // Flag to disable system default apps.
-  bool arc_disable_system_default_app = false;
-
   // Flag to disable scheduling of media store periodic maintenance tasks.
   bool disable_media_store_maintenance = false;
 
diff --git a/ash/components/arc/session/arc_vm_client_adapter.cc b/ash/components/arc/session/arc_vm_client_adapter.cc
index a122e31..8005d1f 100644
--- a/ash/components/arc/session/arc_vm_client_adapter.cc
+++ b/ash/components/arc/session/arc_vm_client_adapter.cc
@@ -115,21 +115,6 @@
   return chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
 }
 
-std::string GetChromeOsChannelFromLsbRelease() {
-  constexpr const char kChromeOsReleaseTrack[] = "CHROMEOS_RELEASE_TRACK";
-  constexpr const char kUnknown[] = "unknown";
-  const std::string kChannelSuffix = "-channel";
-
-  std::string value;
-  base::SysInfo::GetLsbReleaseValue(kChromeOsReleaseTrack, &value);
-
-  if (!base::EndsWith(value, kChannelSuffix, base::CompareCase::SENSITIVE)) {
-    LOG(ERROR) << "Unknown ChromeOS channel: \"" << value << "\"";
-    return kUnknown;
-  }
-  return value.erase(value.find(kChannelSuffix), kChannelSuffix.size());
-}
-
 ArcBinaryTranslationType IdentifyBinaryTranslationType(
     const StartParams& start_params) {
   const auto* command_line = base::CommandLine::ForCurrentProcess();
@@ -195,9 +180,7 @@
 std::vector<std::string> GenerateKernelCmdline(
     const StartParams& start_params,
     const FileSystemStatus& file_system_status,
-    bool is_dev_mode,
-    bool is_host_on_vm,
-    const std::string& channel) {
+    bool is_host_on_vm) {
   std::string native_bridge;
   switch (IdentifyBinaryTranslationType(start_params)) {
     case ArcBinaryTranslationType::NONE:
@@ -216,8 +199,6 @@
 
   std::vector<std::string> result = {
       base::StringPrintf("androidboot.native_bridge=%s", native_bridge.c_str()),
-      base::StringPrintf("androidboot.dev_mode=%d", is_dev_mode),
-      base::StringPrintf("androidboot.disable_runas=%d", !is_dev_mode),
       base::StringPrintf("androidboot.host_is_in_vm=%d", is_host_on_vm),
       base::StringPrintf("androidboot.lcd_density=%d",
                          start_params.lcd_density),
@@ -228,9 +209,6 @@
       base::StringPrintf(
           "androidboot.keyboard_shortcut_helper_integration=%d",
           start_params.enable_keyboard_shortcut_helper_integration),
-      base::StringPrintf("androidboot.disable_system_default_app=%d",
-                         start_params.arc_disable_system_default_app),
-      "androidboot.chromeos_channel=" + channel,
       base::StringPrintf("androidboot.iioservice_present=%d",
                          BUILDFLAG(USE_IIOSERVICE)),
       base::StringPrintf("androidboot.enable_notifications_refresh=%d",
@@ -254,11 +232,6 @@
       break;
   }
 
-  // We run vshd under a restricted domain on non-test images.
-  // (go/arcvm-android-sh-restricted)
-  if (channel == "testimage")
-    result.push_back("androidboot.vshd_service_override=vshd_for_test");
-
   // Only add boot property if flag to disable media store maintenance is set.
   if (start_params.disable_media_store_maintenance)
     result.push_back("androidboot.disable_media_store_maintenance=1");
@@ -632,7 +605,7 @@
                            public ash::ConciergeClient::Observer,
                            public ConnectionObserver<arc::mojom::AppInstance> {
  public:
-  // Initializing |is_host_on_vm_| and |is_dev_mode_| is not always very fast.
+  // Initializing |is_host_on_vm_| is not always very fast.
   // Try to initialize them in the constructor and in StartMiniArc respectively.
   // They usually run when the system is not busy.
   ArcVmClientAdapter() : ArcVmClientAdapter(FileSystemStatusRewriter{}) {}
@@ -702,12 +675,26 @@
     }
 
     start_params_ = std::move(params);
-    base::ThreadPool::PostTaskAndReplyWithResult(
-        FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
+    std::vector<std::string> enviroment;
+    if (start_params_.disable_ureadahead)
+      enviroment.emplace_back("DISABLE_UREADAHEAD=1");
+    std::deque<JobDesc> jobs{
+        // Note: the first Upstart job is a task, and the callback for the start
+        // request won't be called until the task finishes. When the callback is
+        // called with true, it is ensured that the per-board features files
+        // exist.
+        JobDesc{kArcVmPerBoardFeaturesJobName, UpstartOperation::JOB_START, {}},
+        JobDesc{
+            kArcVmPostVmStartServicesJobName, UpstartOperation::JOB_STOP, {}},
+        JobDesc{kArcVmPostLoginServicesJobName, UpstartOperation::JOB_STOP, {}},
+        JobDesc{kArcVmPreLoginServicesJobName,
+                UpstartOperation::JOB_STOP_AND_START, std::move(enviroment)},
+    };
+    ConfigureUpstartJobs(
+        std::move(jobs),
         base::BindOnce(
-            []() { return GetSystemPropertyInt("cros_debug") == 1; }),
-        base::BindOnce(&ArcVmClientAdapter::OnIsDevMode,
-                       weak_factory_.GetWeakPtr(), std::move(callback)));
+            &ArcVmClientAdapter::OnConfigureUpstartJobsOnStartMiniArc,
+            weak_factory_.GetWeakPtr(), std::move(callback)));
   }
 
   void UpgradeArc(UpgradeParams params,
@@ -855,31 +842,6 @@
                                 weak_factory_.GetWeakPtr()));
   }
 
-  void OnIsDevMode(chromeos::VoidDBusMethodCallback callback,
-                   bool is_dev_mode) {
-    is_dev_mode_ = is_dev_mode;
-    std::vector<std::string> enviroment;
-    if (start_params_.disable_ureadahead)
-      enviroment.emplace_back("DISABLE_UREADAHEAD=1");
-    std::deque<JobDesc> jobs{
-        // Note: the first Upstart job is a task, and the callback for the start
-        // request won't be called until the task finishes. When the callback is
-        // called with true, it is ensured that the per-board features files
-        // exist.
-        JobDesc{kArcVmPerBoardFeaturesJobName, UpstartOperation::JOB_START, {}},
-        JobDesc{
-            kArcVmPostVmStartServicesJobName, UpstartOperation::JOB_STOP, {}},
-        JobDesc{kArcVmPostLoginServicesJobName, UpstartOperation::JOB_STOP, {}},
-        JobDesc{kArcVmPreLoginServicesJobName,
-                UpstartOperation::JOB_STOP_AND_START, std::move(enviroment)},
-    };
-    ConfigureUpstartJobs(
-        std::move(jobs),
-        base::BindOnce(
-            &ArcVmClientAdapter::OnConfigureUpstartJobsOnStartMiniArc,
-            weak_factory_.GetWeakPtr(), std::move(callback)));
-  }
-
   void OnConfigureUpstartJobsOnStartMiniArc(
       chromeos::VoidDBusMethodCallback callback,
       bool result) {
@@ -1055,8 +1017,7 @@
     DCHECK_LT(0, cpus);
 
     std::vector<std::string> kernel_cmdline = GenerateKernelCmdline(
-        start_params_, file_system_status, *is_dev_mode_, is_host_on_vm_,
-        GetChromeOsChannelFromLsbRelease());
+        start_params_, file_system_status, is_host_on_vm_);
     auto start_request = CreateStartArcVmRequest(
         user_id_hash_, cpus, demo_session_apps_path, data_image_path,
         file_system_status, use_per_vm_core_scheduling,
@@ -1249,7 +1210,6 @@
 
   std::unique_ptr<ArcVmClientAdapterDelegate> delegate_;
 
-  absl::optional<bool> is_dev_mode_;
   // True when the *host* is running on a VM.
   const bool is_host_on_vm_;
   // A cryptohome ID of the primary profile.
diff --git a/ash/components/arc/session/arc_vm_client_adapter_unittest.cc b/ash/components/arc/session/arc_vm_client_adapter_unittest.cc
index 6aab62e7..51232448 100644
--- a/ash/components/arc/session/arc_vm_client_adapter_unittest.cc
+++ b/ash/components/arc/session/arc_vm_client_adapter_unittest.cc
@@ -1313,17 +1313,6 @@
                              "ro.boot.arc_demo_mode=1"));
 }
 
-TEST_F(ArcVmClientAdapterTest, StartMiniArc_DisableSystemDefaultApp) {
-  StartParams start_params(GetPopulatedStartParams());
-  start_params.arc_disable_system_default_app = true;
-  StartMiniArcWithParams(true, std::move(start_params));
-  EXPECT_GE(GetTestConciergeClient()->start_arc_vm_call_count(), 1);
-  EXPECT_FALSE(is_system_shutdown().has_value());
-  EXPECT_TRUE(
-      base::Contains(GetTestConciergeClient()->start_arc_vm_request().params(),
-                     "androidboot.disable_system_default_app=1"));
-}
-
 TEST_F(ArcVmClientAdapterTest, StartUpgradeArc_DisableMediaStoreMaintenance) {
   StartParams start_params(GetPopulatedStartParams());
   start_params.disable_media_store_maintenance = true;
@@ -1543,28 +1532,6 @@
   CreateArcVmClientAdapter();
 }
 
-TEST_F(ArcVmClientAdapterTest, ChromeOsChannelStable) {
-  base::test::ScopedChromeOSVersionInfo info(
-      "CHROMEOS_RELEASE_TRACK=stable-channel", base::Time::Now());
-
-  StartParams start_params(GetPopulatedStartParams());
-  StartMiniArcWithParams(true, std::move(start_params));
-  EXPECT_TRUE(
-      base::Contains(GetTestConciergeClient()->start_arc_vm_request().params(),
-                     "androidboot.chromeos_channel=stable"));
-}
-
-TEST_F(ArcVmClientAdapterTest, ChromeOsChannelUnknown) {
-  base::test::ScopedChromeOSVersionInfo info("CHROMEOS_RELEASE_TRACK=invalid",
-                                             base::Time::Now());
-
-  StartParams start_params(GetPopulatedStartParams());
-  StartMiniArcWithParams(true, std::move(start_params));
-  EXPECT_TRUE(
-      base::Contains(GetTestConciergeClient()->start_arc_vm_request().params(),
-                     "androidboot.chromeos_channel=unknown"));
-}
-
 TEST_F(ArcVmClientAdapterTest, DefaultBlockSize) {
   base::test::ScopedFeatureList feature_list;
   feature_list.InitWithFeatureState(arc::kUseDefaultBlockSize, true /* use */);
@@ -1669,18 +1636,6 @@
       base::Contains(req.params(), "androidboot.arcvm_virtio_blk_data=1"));
 }
 
-TEST_F(ArcVmClientAdapterTest, VshdForTest) {
-  base::test::ScopedChromeOSVersionInfo info(
-      "CHROMEOS_RELEASE_TRACK=testimage-channel", base::Time::Now());
-
-  StartParams start_params(GetPopulatedStartParams());
-  StartMiniArcWithParams(true, std::move(start_params));
-  UpgradeArc(true);
-  EXPECT_TRUE(
-      base::Contains(GetTestConciergeClient()->start_arc_vm_request().params(),
-                     "androidboot.vshd_service_override=vshd_for_test"));
-}
-
 TEST_F(ArcVmClientAdapterTest, VshdForRelease) {
   base::test::ScopedChromeOSVersionInfo info(
       "CHROMEOS_RELEASE_TRACK=stable-channel", base::Time::Now());
diff --git a/ash/constants/ash_switches.cc b/ash/constants/ash_switches.cc
index 45f3ff3b..adaa940 100644
--- a/ash/constants/ash_switches.cc
+++ b/ash/constants/ash_switches.cc
@@ -101,10 +101,6 @@
 // apps silently. Used in autotests to resolve racy conditions.
 const char kArcDisablePlayAutoInstall[] = "arc-disable-play-auto-install";
 
-// Used for development of Android app that are included into ARC as system
-// default apps in order to be able to install them via adb.
-const char kArcDisableSystemDefaultApps[] = "arc-disable-system-default-apps";
-
 // Flag that disables ureadahead completely, including host and guest parts.
 // See also |kArcVmUreadaheadMode|.
 const char kArcDisableUreadahead[] = "arc-disable-ureadahead";
diff --git a/ash/constants/ash_switches.h b/ash/constants/ash_switches.h
index b6c4037..9f2fd73 100644
--- a/ash/constants/ash_switches.h
+++ b/ash/constants/ash_switches.h
@@ -40,8 +40,6 @@
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const char kArcDisableMediaStoreMaintenance[];
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kArcDisablePlayAutoInstall[];
-COMPONENT_EXPORT(ASH_CONSTANTS)
-extern const char kArcDisableSystemDefaultApps[];
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kArcDisableUreadahead[];
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const char kArcEnableNativeBridge64BitSupportExperiment[];
diff --git a/ash/login/login_screen_test_api.cc b/ash/login/login_screen_test_api.cc
index 0d90056d..eec4b32 100644
--- a/ash/login/login_screen_test_api.cc
+++ b/ash/login/login_screen_test_api.cc
@@ -276,6 +276,14 @@
 }
 
 // static
+bool LoginScreenTestApi::IsKioskInstructionBubbleShown() {
+  LoginShelfView* view = GetLoginShelfView();
+  return view->GetKioskInstructionBubbleForTesting() &&
+         view->GetKioskInstructionBubbleForTesting()->GetWidget() &&
+         view->GetKioskInstructionBubbleForTesting()->GetWidget()->IsVisible();
+}
+
+// static
 bool LoginScreenTestApi::IsPasswordFieldShown(const AccountId& account_id) {
   if (GetFocusedUser() != account_id) {
     ADD_FAILURE() << "The user " << account_id.Serialize() << " is not focused";
diff --git a/ash/public/cpp/login_screen_test_api.h b/ash/public/cpp/login_screen_test_api.h
index 2e02868..dd67910 100644
--- a/ash/public/cpp/login_screen_test_api.h
+++ b/ash/public/cpp/login_screen_test_api.h
@@ -43,6 +43,7 @@
   static bool IsWarningBubbleShown();
   static bool IsUserAddingScreenIndicatorShown();
   static bool IsSystemInfoShown();
+  static bool IsKioskInstructionBubbleShown();
   static bool IsPasswordFieldShown(const AccountId& account_id);
   static bool IsDisplayPasswordButtonShown(const AccountId& account_id);
   static bool IsManagedIconShown(const AccountId& account_id);
diff --git a/ash/webui/camera_app_ui/camera_app_ui.cc b/ash/webui/camera_app_ui/camera_app_ui.cc
index f1c83c4..0827131 100644
--- a/ash/webui/camera_app_ui/camera_app_ui.cc
+++ b/ash/webui/camera_app_ui/camera_app_ui.cc
@@ -10,6 +10,9 @@
 #include "ash/webui/camera_app_ui/url_constants.h"
 #include "ash/webui/grit/ash_camera_app_resources_map.h"
 #include "base/bind.h"
+#include "base/feature_list.h"
+#include "base/files/file_util.h"
+#include "base/memory/ref_counted_memory.h"
 #include "base/strings/string_util.h"
 #include "components/arc/intent_helper/arc_intent_helper_bridge.h"
 #include "components/content_settings/core/common/content_settings_types.h"
@@ -35,6 +38,11 @@
 
 namespace {
 
+const base::Feature kCCALocalOverride{"CCALocalOverride",
+                                      base::FEATURE_DISABLED_BY_DEFAULT};
+const base::FilePath::CharType kCCALocalOverrideDirectoryPath[] =
+    FILE_PATH_LITERAL("/etc/camera/cca");
+
 content::WebUIDataSource* CreateCameraAppUIHTMLSource(
     CameraAppUIDelegate* delegate) {
   content::WebUIDataSource* source =
@@ -54,6 +62,41 @@
 
   source->UseStringsJs();
 
+  if (base::FeatureList::IsEnabled(kCCALocalOverride)) {
+    source->SetRequestFilter(
+        base::BindRepeating([](const std::string& url) {
+          // Only override files that are copied locally with cca.py deploy.
+          if (!(base::StartsWith(url, "js/") || base::StartsWith(url, "css/") ||
+                base::StartsWith(url, "images/") ||
+                base::StartsWith(url, "views/") ||
+                base::StartsWith(url, "sounds/"))) {
+            return false;
+          }
+          // This file is written by `cca.py deploy` and contains version
+          // information of deployed file.
+          base::FilePath version_path =
+              base::FilePath(kCCALocalOverrideDirectoryPath)
+                  .Append("js/deployed_version.js");
+          if (!base::PathExists(version_path)) {
+            return false;
+          }
+          return true;
+        }),
+        base::BindRepeating(
+            [](const std::string& url,
+               content::WebUIDataSource::GotDataCallback callback) {
+              base::FilePath path =
+                  base::FilePath(kCCALocalOverrideDirectoryPath).Append(url);
+              std::string result;
+              if (base::ReadFileToString(path, &result)) {
+                std::move(callback).Run(
+                    base::RefCountedString::TakeString(&result));
+              } else {
+                std::move(callback).Run(nullptr);
+              }
+            }));
+  }
+
   source->OverrideContentSecurityPolicy(
       network::mojom::CSPDirectiveName::WorkerSrc,
       std::string("worker-src 'self';"));
diff --git a/ash/webui/camera_app_ui/resources/css/focus_ring.css b/ash/webui/camera_app_ui/resources/css/focus_ring.css
index 96c32f9..1b7ec5a0 100644
--- a/ash/webui/camera_app_ui/resources/css/focus_ring.css
+++ b/ash/webui/camera_app_ui/resources/css/focus_ring.css
@@ -2,7 +2,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file. */
 
-body:not(.keyboard-navigation) #focus-ring {
+body:not(.show-focus-ring) #focus-ring {
   visibility: hidden;
 }
 
diff --git a/ash/webui/camera_app_ui/resources/css/main.css b/ash/webui/camera_app_ui/resources/css/main.css
index 23488606..471e505c 100644
--- a/ash/webui/camera_app_ui/resources/css/main.css
+++ b/ash/webui/camera_app_ui/resources/css/main.css
@@ -596,7 +596,7 @@
   --option-item-vpadding: 12px;
   --switch-device-gap: 32px;
   bottom: calc(var(--bottom-line) + (var(--big-icon) / 2) + var(--switch-device-gap) - var(--option-item-vpadding));
-  flex-direction: column-reverse;
+  flex-direction: column;
   transition: bottom var(--fast1-duration);
 }
 
diff --git a/ash/webui/camera_app_ui/resources/js/focus_ring.ts b/ash/webui/camera_app_ui/resources/js/focus_ring.ts
index 85f126a..60fe2328 100644
--- a/ash/webui/camera_app_ui/resources/js/focus_ring.ts
+++ b/ash/webui/camera_app_ui/resources/js/focus_ring.ts
@@ -5,6 +5,7 @@
 import {assert} from './assert.js';
 import {cssStyle} from './css.js';
 import * as dom from './dom.js';
+import * as state from './state.js';
 import {getStyleValueInPx} from './util.js';
 
 /**
@@ -85,12 +86,24 @@
 }
 
 /**
+ * Check visibility of the focus ring.
+ */
+export function checkFocusRingVisibility(): void {
+  const showFocusRing =
+      document.activeElement?.hasAttribute('tabindex') === true &&
+      state.get(state.State.KEYBOARD_NAVIGATION);
+  state.set(state.State.SHOW_FOCUS_RING, showFocusRing);
+}
+
+/**
  * Initializes DOM elements and observers used for focus ring.
  */
 export function initialize(): void {
   ring = dom.get('#focus-ring', HTMLElement);
   ringCSSStyle = cssStyle('#focus-ring');
 
+  window.addEventListener('focus', checkFocusRingVisibility, true);
+
   for (const el of dom.getAll('[tabindex]', HTMLElement)) {
     setup(el);
   }
diff --git a/ash/webui/camera_app_ui/resources/js/nav.ts b/ash/webui/camera_app_ui/resources/js/nav.ts
index 7d4ee361..865fa4c 100644
--- a/ash/webui/camera_app_ui/resources/js/nav.ts
+++ b/ash/webui/camera_app_ui/resources/js/nav.ts
@@ -4,6 +4,7 @@
 
 import {assert} from './assert.js';
 import {toggleExpertMode} from './expert.js';
+import {checkFocusRingVisibility} from './focus_ring.js';
 import * as state from './state.js';
 import * as toast from './toast.js';
 import {ViewName} from './type.js';
@@ -39,10 +40,14 @@
  */
 export function setup(views: View[]): void {
   allViews = views.flatMap((v) => [...getRecursiveViews(v)]);
-  document.addEventListener(
-      'pointerdown', () => state.set(state.State.KEYBOARD_NAVIGATION, false));
-  document.addEventListener(
-      'keydown', () => state.set(state.State.KEYBOARD_NAVIGATION, true));
+  document.addEventListener('pointerdown', () => {
+    state.set(state.State.KEYBOARD_NAVIGATION, false);
+    checkFocusRingVisibility();
+  });
+  document.addEventListener('keydown', () => {
+    state.set(state.State.KEYBOARD_NAVIGATION, true);
+    checkFocusRingVisibility();
+  });
 }
 
 /**
diff --git a/ash/webui/camera_app_ui/resources/js/state.ts b/ash/webui/camera_app_ui/resources/js/state.ts
index f0c1abd8..55b5e6e 100644
--- a/ash/webui/camera_app_ui/resources/js/state.ts
+++ b/ash/webui/camera_app_ui/resources/js/state.ts
@@ -56,6 +56,7 @@
   SAVE_METADATA = 'save-metadata',
   SHOULD_HANDLE_INTENT_RESULT = 'should-handle-intent-result',
   SHOW_ALL_RESOLUTIONS = 'show-all-resolutions',
+  SHOW_FOCUS_RING = 'show-focus-ring',
   SHOW_GIF_RECORDING_OPTION = 'show-gif-recording-option',
   SHOW_METADATA = 'show-metadata',
   SHOW_SCAN_MODE = 'show-scan-mode',
diff --git a/ash/webui/camera_app_ui/resources/views/main.html b/ash/webui/camera_app_ui/resources/views/main.html
index 46b76acc..2a1aac0 100644
--- a/ash/webui/camera_app_ui/resources/views/main.html
+++ b/ash/webui/camera_app_ui/resources/views/main.html
@@ -118,70 +118,29 @@
           </div>
         </div>
       </div>
-      <div id="video-snapshot-holder" class="buttons right-stripe circle">
-        <button id="video-snapshot" tabindex="0"
-                i18n-label="take_video_snapshot_button"></button>
+      <div class="top-stripe left-stripe buttons circle">
+        <button id="open-settings" tabindex="0"
+                i18n-label="settings_button" aria-haspopup="true"></button>
       </div>
-      <div id="shutters-group" class="buttons right-stripe circle">
-        <button id="recordvideo" class="shutter" tabindex="0"
-                i18n-label="record_video_start_button">
-          <div class="red-dot"></div>
-          <div class="white-square"></div>
-          <svg id="shutter-progress-bar">
-            <circle></circle>
-          </svg>
+      <div class="top-stripe right-stripe circle buttons">
+        <input id="toggle-mic" type="checkbox" tabindex="0"
+               i18n-label="toggle_mic_button" data-state="mic"
+               i18n-aria="aria_mute_off" data-key="toggleMic" checked>
+      </div>
+      <div class="top-stripe right-stripe circle buttons">
+        <input id="toggle-barcode" type="checkbox" tabindex="0"
+               i18n-label="toggle_barcode_button">
+      </div>
+      <div id="options-group" class="left-stripe buttons circle">
+        <button id="open-mirror-panel" tabindex="0" aria-haspopup="true">
         </button>
-        <button id="start-takephoto" class="shutter" tabindex="0"
-                i18n-label="take_photo_button"></button>
-        <button id="stop-takephoto" class="shutter" tabindex="0"
-                i18n-label="take_photo_cancel_button"></button>
-      </div>
-      <div id="pause-recordvideo-holder" class="buttons right-stripe circle">
-        <button id="pause-recordvideo" tabindex="0"
-                i18n-label="record_video_pause_button">
-          <div class="red-dot"></div>
-          <div class="two-bars"></div>
+        <button id="open-grid-panel" tabindex="0" aria-haspopup="true"></button>
+        <button id="open-timer-panel" tabindex="0" aria-haspopup="true">
+        <button id="open-ptz-panel" tabindex="0" aria-haspopup="true"
+                i18n-label="open_ptz_panel_button"
+                i18n-new-feature="new_control_toast"></button>
         </button>
       </div>
-      <div class="bottom-stripe right-stripe buttons circle">
-        <button id="gallery-enter" tabindex="0"
-                i18n-label="gallery_button" hidden>
-          <img>
-        </button>
-      </div>
-      <div id="mode-selector" class="bottom-stripe">
-        <div id="modes-group" class="buttons" role="radiogroup"
-             i18n-aria="aria_camera_mode_group">
-          <div class="mode-item">
-            <input type="radio" name="mode"
-                 data-mode="video" tabindex="0"
-                 i18n-aria="switch_record_video_button">
-            <span i18n-text="label_switch_record_video_button"
-                  aria-hidden="true"></span>
-          </div>
-          <div class="mode-item">
-            <input type="radio" name="mode"
-                 data-mode="photo" tabindex="0"
-                 i18n-aria="switch_take_photo_button">
-            <span i18n-text="label_switch_take_photo_button"
-                  aria-hidden="true"></span>
-          </div>
-          <div class="mode-item" i18n-new-feature="new_document_scan_toast">
-            <input type="radio" name="mode"
-                 data-mode="scan" tabindex="0"
-                 i18n-aria="switch_scan_mode_button">
-            <span i18n-text="label_switch_scan_mode_button"
-                  aria-hidden="true"></span>
-          </div>
-          <div class="mode-item">
-            <input type="radio" name="mode"
-                 data-mode="portrait" tabindex="0"
-                 i18n-aria="switch_take_portrait_bokeh_photo_button">
-            <span i18n-text="label_switch_take_portrait_bokeh_photo_button"
-                  aria-hidden="true"></span>
-          </div>
-        </div>
-      </div>
       <div id="scan-modes-group" class="mode-subgroup" role="radiogroup"
            i18n-aria="aria_scan_type_group">
         <div id="scan-document-option" class="item">
@@ -216,39 +175,79 @@
                aria-hidden="true"></div>
         </div>
       </div>
+      <div id="video-snapshot-holder" class="buttons right-stripe circle">
+        <button id="video-snapshot" tabindex="0"
+                i18n-label="take_video_snapshot_button"></button>
+      </div>
+      <div id="shutters-group" class="buttons right-stripe circle">
+        <button id="recordvideo" class="shutter" tabindex="0"
+                i18n-label="record_video_start_button">
+          <div class="red-dot"></div>
+          <div class="white-square"></div>
+          <svg id="shutter-progress-bar">
+            <circle></circle>
+          </svg>
+        </button>
+        <button id="start-takephoto" class="shutter" tabindex="0"
+                i18n-label="take_photo_button"></button>
+        <button id="stop-takephoto" class="shutter" tabindex="0"
+                i18n-label="take_photo_cancel_button"></button>
+      </div>
+      <div id="pause-recordvideo-holder" class="buttons right-stripe circle">
+        <button id="pause-recordvideo" tabindex="0"
+                i18n-label="record_video_pause_button">
+          <div class="red-dot"></div>
+          <div class="two-bars"></div>
+        </button>
+      </div>
       <div class="bottom-stripe left-stripe buttons circle">
         <button id="switch-device" tabindex="0"
                 i18n-label="switch_camera_button"></button>
       </div>
-
-      <div id="options-group" class="left-stripe buttons circle">
-        <button id="open-ptz-panel" tabindex="0" aria-haspopup="true"
-                i18n-label="open_ptz_panel_button"
-                i18n-new-feature="new_control_toast"></button>
-        <button id="open-timer-panel" tabindex="0" aria-haspopup="true">
-        </button>
-        <button id="open-grid-panel" tabindex="0" aria-haspopup="true"></button>
-        <button id="open-mirror-panel" tabindex="0" aria-haspopup="true">
-        </button>
+      <div id="mode-selector" class="bottom-stripe">
+        <div id="modes-group" class="buttons" role="radiogroup"
+             i18n-aria="aria_camera_mode_group">
+          <div class="mode-item">
+            <input type="radio" name="mode"
+                 data-mode="video" tabindex="0"
+                 i18n-aria="switch_record_video_button">
+            <span i18n-text="label_switch_record_video_button"
+                  aria-hidden="true"></span>
+          </div>
+          <div class="mode-item">
+            <input type="radio" name="mode"
+                 data-mode="photo" tabindex="0"
+                 i18n-aria="switch_take_photo_button">
+            <span i18n-text="label_switch_take_photo_button"
+                  aria-hidden="true"></span>
+          </div>
+          <div class="mode-item" i18n-new-feature="new_document_scan_toast">
+            <input type="radio" name="mode"
+                 data-mode="scan" tabindex="0"
+                 i18n-aria="switch_scan_mode_button">
+            <span i18n-text="label_switch_scan_mode_button"
+                  aria-hidden="true"></span>
+          </div>
+          <div class="mode-item">
+            <input type="radio" name="mode"
+                 data-mode="portrait" tabindex="0"
+                 i18n-aria="switch_take_portrait_bokeh_photo_button">
+            <span i18n-text="label_switch_take_portrait_bokeh_photo_button"
+                  aria-hidden="true"></span>
+          </div>
+        </div>
       </div>
-      <div class="top-stripe left-stripe buttons circle">
-        <button id="open-settings" tabindex="0"
-                i18n-label="settings_button" aria-haspopup="true"></button>
+      <div class="bottom-stripe right-stripe buttons circle">
+        <button id="gallery-enter" tabindex="0"
+                i18n-label="gallery_button" hidden>
+          <img>
+        </button>
       </div>
       <div id="record-time" class="top-stripe horizontal-center-stripe" hidden>
         <div class="icon"></div>
         <div id="paused-msg" i18n-text="record_video_paused_msg"></div>
         <div id="record-time-msg"></div>
       </div>
-      <div class="top-stripe right-stripe circle buttons">
-        <input id="toggle-mic" type="checkbox" tabindex="0"
-               i18n-label="toggle_mic_button" data-state="mic"
-               i18n-aria="aria_mute_off" data-key="toggleMic" checked>
-      </div>
-      <div class="top-stripe right-stripe circle buttons">
-        <input id="toggle-barcode" type="checkbox" tabindex="0"
-               i18n-label="toggle_barcode_button">
-      </div>
       <div class="centered-overlay">
         <div id="timer-tick-msg"></div>
       </div>
diff --git a/base/allocator/partition_allocator/BUILD.gn b/base/allocator/partition_allocator/BUILD.gn
index 559a733..a9105b0f 100644
--- a/base/allocator/partition_allocator/BUILD.gn
+++ b/base/allocator/partition_allocator/BUILD.gn
@@ -75,6 +75,8 @@
     "partition_alloc_base/atomic_ref_count.h",
     "partition_alloc_base/bit_cast.h",
     "partition_alloc_base/bits.h",
+    "partition_alloc_base/check.cc",
+    "partition_alloc_base/check.h",
     "partition_alloc_base/compiler_specific.h",
     "partition_alloc_base/cpu.cc",
     "partition_alloc_base/cpu.h",
diff --git a/base/allocator/partition_allocator/DEPS b/base/allocator/partition_allocator/DEPS
index 0f186c8..d05f961 100644
--- a/base/allocator/partition_allocator/DEPS
+++ b/base/allocator/partition_allocator/DEPS
@@ -6,8 +6,6 @@
 include_rules = [
     "+base/allocator/buildflags.h",
     "+base/base_export.h",
-    "+base/check.h",
-    "+base/check_op.h",
     "+base/compiler_specific.h",
     "+base/dcheck_is_on.h",
     "+base/logging_buildflags.h",
diff --git a/base/allocator/partition_allocator/address_space_randomization_unittest.cc b/base/allocator/partition_allocator/address_space_randomization_unittest.cc
index 6b221ef..88d91d3 100644
--- a/base/allocator/partition_allocator/address_space_randomization_unittest.cc
+++ b/base/allocator/partition_allocator/address_space_randomization_unittest.cc
@@ -8,8 +8,8 @@
 #include <vector>
 
 #include "base/allocator/partition_allocator/page_allocator.h"
+#include "base/allocator/partition_allocator/partition_alloc_check.h"
 #include "base/allocator/partition_allocator/random.h"
-#include "base/check_op.h"
 #include "base/dcheck_is_on.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -190,7 +190,7 @@
       // For k=2 probability of Chi^2 < 35 is p=3.338e-9. This condition is
       // tested ~19000 times, so probability of it failing randomly per one
       // base_unittests run is (1 - (1 - p) ^ 19000) ~= 6e-5.
-      CHECK_LE(chi_squared, 35.0);
+      PA_CHECK(chi_squared <= 35.0);
       // If the predictor bit is a fixed 0 or 1 then it makes no sense to
       // repeat the test with a different age.
       if (predictor_bit < 0)
diff --git a/base/allocator/partition_allocator/partition_alloc_base/check.cc b/base/allocator/partition_allocator/partition_alloc_base/check.cc
new file mode 100644
index 0000000..c687549
--- /dev/null
+++ b/base/allocator/partition_allocator/partition_alloc_base/check.cc
@@ -0,0 +1,103 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/allocator/partition_allocator/partition_alloc_base/check.h"
+
+#include "build/build_config.h"
+
+// check.h is a widely included header and its size has significant impact on
+// build time. Try not to raise this limit unless absolutely necessary. See
+// https://chromium.googlesource.com/chromium/src/+/HEAD/docs/wmax_tokens.md
+#ifndef NACL_TC_REV
+#pragma clang max_tokens_here 17000
+#endif
+
+#include "base/allocator/partition_allocator/partition_alloc_base/logging.h"
+#include "build/build_config.h"
+
+namespace partition_alloc::internal::logging {
+
+// TODO(1151236): Make CheckError not to allocate memory. So we can use
+// CHECK() inside PartitionAllocator when PartitionAllocator-Everywhere is
+// enabled. (Also need to modify LogMessage).
+CheckError CheckError::Check(const char* file,
+                             int line,
+                             const char* condition) {
+  CheckError check_error(new LogMessage(file, line, LOGGING_FATAL));
+  check_error.stream() << "Check failed: " << condition << ". ";
+  return check_error;
+}
+
+CheckError CheckError::DCheck(const char* file,
+                              int line,
+                              const char* condition) {
+  CheckError check_error(new LogMessage(file, line, LOGGING_DCHECK));
+  check_error.stream() << "Check failed: " << condition << ". ";
+  return check_error;
+}
+
+CheckError CheckError::PCheck(const char* file,
+                              int line,
+                              const char* condition) {
+  SystemErrorCode err_code = logging::GetLastSystemErrorCode();
+#if BUILDFLAG(IS_WIN)
+  CheckError check_error(
+      new Win32ErrorLogMessage(file, line, LOGGING_FATAL, err_code));
+#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
+  CheckError check_error(
+      new ErrnoLogMessage(file, line, LOGGING_FATAL, err_code));
+#endif
+  check_error.stream() << "Check failed: " << condition << ". ";
+  return check_error;
+}
+
+CheckError CheckError::PCheck(const char* file, int line) {
+  return PCheck(file, line, "");
+}
+
+CheckError CheckError::DPCheck(const char* file,
+                               int line,
+                               const char* condition) {
+  SystemErrorCode err_code = logging::GetLastSystemErrorCode();
+#if BUILDFLAG(IS_WIN)
+  CheckError check_error(
+      new Win32ErrorLogMessage(file, line, LOGGING_DCHECK, err_code));
+#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
+  CheckError check_error(
+      new ErrnoLogMessage(file, line, LOGGING_DCHECK, err_code));
+#endif
+  check_error.stream() << "Check failed: " << condition << ". ";
+  return check_error;
+}
+
+CheckError CheckError::NotImplemented(const char* file,
+                                      int line,
+                                      const char* function) {
+  CheckError check_error(new LogMessage(file, line, LOGGING_ERROR));
+  check_error.stream() << "Not implemented reached in " << function;
+  return check_error;
+}
+
+std::ostream& CheckError::stream() {
+  return log_message_->stream();
+}
+
+CheckError::~CheckError() {
+  // Note: This function ends up in crash stack traces. If its full name
+  // changes, the crash server's magic signature logic needs to be updated.
+  // See cl/306632920.
+  delete log_message_;
+}
+
+CheckError::CheckError(LogMessage* log_message) : log_message_(log_message) {}
+
+void RawCheck(const char* message) {
+  RawLog(LOGGING_FATAL, message);
+}
+
+void RawError(const char* message) {
+  RawLog(LOGGING_ERROR, message);
+}
+
+}  // namespace partition_alloc::internal::logging
diff --git a/base/allocator/partition_allocator/partition_alloc_base/check.h b/base/allocator/partition_allocator/partition_alloc_base/check.h
new file mode 100644
index 0000000..50f46e71
--- /dev/null
+++ b/base/allocator/partition_allocator/partition_alloc_base/check.h
@@ -0,0 +1,178 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_BASE_CHECK_H_
+#define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_BASE_CHECK_H_
+
+#include <iosfwd>
+
+#include "base/allocator/partition_allocator/partition_alloc_base/immediate_crash.h"
+#include "base/base_export.h"
+#include "base/compiler_specific.h"
+#include "base/dcheck_is_on.h"
+
+// This header defines the CHECK, DCHECK, and DPCHECK macros.
+//
+// CHECK dies with a fatal error if its condition is not true. It is not
+// controlled by NDEBUG, so the check will be executed regardless of compilation
+// mode.
+//
+// DCHECK, the "debug mode" check, is enabled depending on NDEBUG and
+// DCHECK_ALWAYS_ON, and its severity depends on DCHECK_IS_CONFIGURABLE.
+//
+// (D)PCHECK is like (D)CHECK, but includes the system error code (c.f.
+// perror(3)).
+//
+// Additional information can be streamed to these macros and will be included
+// in the log output if the condition doesn't hold (you may need to include
+// <ostream>):
+//
+//   CHECK(condition) << "Additional info.";
+//
+// The condition is evaluated exactly once. Even in build modes where e.g.
+// DCHECK is disabled, the condition and any stream arguments are still
+// referenced to avoid warnings about unused variables and functions.
+//
+// For the (D)CHECK_EQ, etc. macros, see base/check_op.h. However, that header
+// is *significantly* larger than check.h, so try to avoid including it in
+// header files.
+
+namespace partition_alloc::internal::logging {
+
+// Class used to explicitly ignore an ostream, and optionally a boolean value.
+class VoidifyStream {
+ public:
+  VoidifyStream() = default;
+  explicit VoidifyStream(bool ignored) {}
+
+  // This operator has lower precedence than << but higher than ?:
+  void operator&(std::ostream&) {}
+};
+
+// Helper macro which avoids evaluating the arguments to a stream if the
+// condition is false.
+#define PA_LAZY_CHECK_STREAM(stream, condition) \
+  !(condition)                                  \
+      ? (void)0                                 \
+      : ::partition_alloc::internal::logging::VoidifyStream() & (stream)
+
+// Macro which uses but does not evaluate expr and any stream parameters.
+#define PA_EAT_CHECK_STREAM_PARAMS(expr)                             \
+  true ? (void)0                                                     \
+       : ::partition_alloc::internal::logging::VoidifyStream(expr) & \
+             (*::partition_alloc::internal::logging::g_swallow_stream)
+BASE_EXPORT extern std::ostream* g_swallow_stream;
+
+class LogMessage;
+
+// Class used for raising a check error upon destruction.
+class BASE_EXPORT CheckError {
+ public:
+  static CheckError Check(const char* file, int line, const char* condition);
+
+  static CheckError DCheck(const char* file, int line, const char* condition);
+
+  static CheckError PCheck(const char* file, int line, const char* condition);
+  static CheckError PCheck(const char* file, int line);
+
+  static CheckError DPCheck(const char* file, int line, const char* condition);
+
+  static CheckError NotImplemented(const char* file,
+                                   int line,
+                                   const char* function);
+
+  // Stream for adding optional details to the error message.
+  std::ostream& stream();
+
+  NOMERGE ~CheckError();
+
+  CheckError(const CheckError& other) = delete;
+  CheckError& operator=(const CheckError& other) = delete;
+  CheckError(CheckError&& other) = default;
+  CheckError& operator=(CheckError&& other) = default;
+
+ private:
+  explicit CheckError(LogMessage* log_message);
+
+  LogMessage* log_message_;
+};
+
+#if defined(OFFICIAL_BUILD) && defined(NDEBUG)
+
+// Discard log strings to reduce code bloat.
+//
+// This is not calling BreakDebugger since this is called frequently, and
+// calling an out-of-line function instead of a noreturn inline macro prevents
+// compiler optimizations.
+#define PA_BASE_CHECK(condition) \
+  UNLIKELY(!(condition)) ? PA_IMMEDIATE_CRASH() : PA_EAT_CHECK_STREAM_PARAMS()
+
+// TODO(1151236): base/test/gtest_util.h uses CHECK_WILL_STREAM(). After
+// copying (or removing) gtest_util.h and removing gtest_uti.h from partition
+// allocator's DEPS, rename or remove CHECK_WILL_STREAM().
+#define CHECK_WILL_STREAM() false
+
+#define PA_BASE_PCHECK(condition)                                        \
+  PA_LAZY_CHECK_STREAM(                                                  \
+      ::partition_alloc::internal::logging::CheckError::PCheck(__FILE__, \
+                                                               __LINE__) \
+          .stream(),                                                     \
+      UNLIKELY(!(condition)))
+
+#else
+
+#define PA_BASE_CHECK(condition)                               \
+  PA_LAZY_CHECK_STREAM(                                        \
+      ::partition_alloc::internal::logging::CheckError::Check( \
+          __FILE__, __LINE__, #condition)                      \
+          .stream(),                                           \
+      !ANALYZER_ASSUME_TRUE(condition))
+
+#define CHECK_WILL_STREAM() true
+
+#define PA_BASE_PCHECK(condition)                               \
+  PA_LAZY_CHECK_STREAM(                                         \
+      ::partition_alloc::internal::logging::CheckError::PCheck( \
+          __FILE__, __LINE__, #condition)                       \
+          .stream(),                                            \
+      !ANALYZER_ASSUME_TRUE(condition))
+
+#endif
+
+#if DCHECK_IS_ON()
+
+#define PA_BASE_DCHECK(condition)                               \
+  PA_LAZY_CHECK_STREAM(                                         \
+      ::partition_alloc::internal::logging::CheckError::DCheck( \
+          __FILE__, __LINE__, #condition)                       \
+          .stream(),                                            \
+      !ANALYZER_ASSUME_TRUE(condition))
+
+#define PA_BASE_DPCHECK(condition)                               \
+  PA_LAZY_CHECK_STREAM(                                          \
+      ::partition_alloc::internal::logging::CheckError::DPCheck( \
+          __FILE__, __LINE__, #condition)                        \
+          .stream(),                                             \
+      !ANALYZER_ASSUME_TRUE(condition))
+
+#else
+
+#define PA_BASE_DCHECK(condition) PA_EAT_CHECK_STREAM_PARAMS(!(condition))
+#define PA_BASE_DPCHECK(condition) PA_EAT_CHECK_STREAM_PARAMS(!(condition))
+
+#endif
+
+// Async signal safe checking mechanism.
+BASE_EXPORT void RawCheck(const char* message);
+BASE_EXPORT void RawError(const char* message);
+#define PA_RAW_CHECK(condition)                       \
+  do {                                                \
+    if (!(condition))                                 \
+      ::partition_alloc::internal::logging::RawCheck( \
+          "Check failed: " #condition "\n");          \
+  } while (0)
+
+}  // namespace partition_alloc::internal::logging
+
+#endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_BASE_CHECK_H_
diff --git a/base/allocator/partition_allocator/partition_alloc_base/files/file_path.cc b/base/allocator/partition_allocator/partition_alloc_base/files/file_path.cc
index 17233aba..3a1560d 100644
--- a/base/allocator/partition_allocator/partition_alloc_base/files/file_path.cc
+++ b/base/allocator/partition_allocator/partition_alloc_base/files/file_path.cc
@@ -16,7 +16,7 @@
 #include <string.h>
 #include <algorithm>
 
-#include "base/check_op.h"
+#include "base/allocator/partition_allocator/partition_alloc_check.h"
 #include "build/build_config.h"
 
 #if BUILDFLAG(IS_WIN)
@@ -103,7 +103,7 @@
     appended = without_nuls;
   }
 
-  DCHECK(!IsPathAbsolute(appended));
+  PA_DCHECK(!IsPathAbsolute(appended));
 
   if (path_.compare(kCurrentDirectory) == 0 && !appended.empty()) {
     // Append normally doesn't do any normalization, but as a special case,
diff --git a/base/allocator/partition_allocator/partition_alloc_base/logging.cc b/base/allocator/partition_allocator/partition_alloc_base/logging.cc
index b4e73086..cbf408a 100644
--- a/base/allocator/partition_allocator/partition_alloc_base/logging.cc
+++ b/base/allocator/partition_allocator/partition_alloc_base/logging.cc
@@ -4,7 +4,12 @@
 
 #include "base/allocator/partition_allocator/partition_alloc_base/logging.h"
 
-#ifdef BASE_CHECK_H_
+// TODO(1151236): After finishing copying //base files to PA library, remove
+// defined(BASE_CHECK_H_) from here.
+#if defined(                                                             \
+    BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_BASE_CHECK_H_) || \
+    defined(BASE_CHECK_H_) ||                                            \
+    defined(BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_CHECK_H_)
 #error "logging.h should not include check.h"
 #endif
 
diff --git a/base/allocator/partition_allocator/partition_alloc_base/memory/ref_counted.cc b/base/allocator/partition_allocator/partition_alloc_base/memory/ref_counted.cc
index c935ce41..3b7a5c1 100644
--- a/base/allocator/partition_allocator/partition_alloc_base/memory/ref_counted.cc
+++ b/base/allocator/partition_allocator/partition_alloc_base/memory/ref_counted.cc
@@ -20,8 +20,8 @@
 
 #if DCHECK_IS_ON()
 RefCountedThreadSafeBase::~RefCountedThreadSafeBase() {
-  DCHECK(in_dtor_) << "RefCountedThreadSafe object deleted without "
-                      "calling Release()";
+  PA_DCHECK(in_dtor_) << "RefCountedThreadSafe object deleted without "
+                         "calling Release()";
 }
 #endif
 
diff --git a/base/allocator/partition_allocator/partition_alloc_base/memory/ref_counted.h b/base/allocator/partition_allocator/partition_alloc_base/memory/ref_counted.h
index 630ede2..7ff63087 100644
--- a/base/allocator/partition_allocator/partition_alloc_base/memory/ref_counted.h
+++ b/base/allocator/partition_allocator/partition_alloc_base/memory/ref_counted.h
@@ -8,9 +8,8 @@
 #include "base/allocator/partition_allocator/partition_alloc_base/atomic_ref_count.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/compiler_specific.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/memory/scoped_refptr.h"
+#include "base/allocator/partition_allocator/partition_alloc_check.h"
 #include "base/base_export.h"
-#include "base/check.h"
-#include "base/check_op.h"
 #include "base/dcheck_is_on.h"
 #include "build/build_config.h"
 
@@ -61,37 +60,37 @@
 
   void Adopted() const {
 #if DCHECK_IS_ON()
-    DCHECK(needs_adopt_ref_);
+    PA_DCHECK(needs_adopt_ref_);
     needs_adopt_ref_ = false;
 #endif
   }
 
   PA_ALWAYS_INLINE void AddRefImpl() const {
 #if DCHECK_IS_ON()
-    DCHECK(!in_dtor_);
+    PA_DCHECK(!in_dtor_);
     // This RefCounted object is created with non-zero reference count.
     // The first reference to such a object has to be made by AdoptRef or
     // MakeRefCounted.
-    DCHECK(!needs_adopt_ref_);
+    PA_DCHECK(!needs_adopt_ref_);
 #endif
     ref_count_.Increment();
   }
 
   PA_ALWAYS_INLINE void AddRefWithCheckImpl() const {
 #if DCHECK_IS_ON()
-    DCHECK(!in_dtor_);
+    PA_DCHECK(!in_dtor_);
     // This RefCounted object is created with non-zero reference count.
     // The first reference to such a object has to be made by AdoptRef or
     // MakeRefCounted.
-    DCHECK(!needs_adopt_ref_);
+    PA_DCHECK(!needs_adopt_ref_);
 #endif
-    CHECK_GT(ref_count_.Increment(), 0);
+    PA_CHECK(ref_count_.Increment() > 0);
   }
 
   PA_ALWAYS_INLINE bool ReleaseImpl() const {
 #if DCHECK_IS_ON()
-    DCHECK(!in_dtor_);
-    DCHECK(!ref_count_.IsZero());
+    PA_DCHECK(!in_dtor_);
+    PA_DCHECK(!ref_count_.IsZero());
 #endif
     if (!ref_count_.Decrement()) {
 #if DCHECK_IS_ON()
diff --git a/base/allocator/partition_allocator/partition_alloc_base/memory/scoped_refptr.h b/base/allocator/partition_allocator/partition_alloc_base/memory/scoped_refptr.h
index b7d417e0..857c0a6 100644
--- a/base/allocator/partition_allocator/partition_alloc_base/memory/scoped_refptr.h
+++ b/base/allocator/partition_allocator/partition_alloc_base/memory/scoped_refptr.h
@@ -12,7 +12,7 @@
 #include <utility>
 
 #include "base/allocator/partition_allocator/partition_alloc_base/compiler_specific.h"
-#include "base/check.h"
+#include "base/allocator/partition_allocator/partition_alloc_check.h"
 
 namespace partition_alloc::internal {
 
@@ -70,8 +70,8 @@
   static_assert(std::is_same<subtle::StartRefCountFromOneTag, Tag>::value,
                 "Use AdoptRef only if the reference count starts from one.");
 
-  DCHECK(obj);
-  DCHECK(obj->HasOneRef());
+  PA_DCHECK(obj);
+  PA_DCHECK(obj->HasOneRef());
   obj->Adopted();
   return scoped_refptr<T>(obj, subtle::kAdoptRefTag);
 }
@@ -225,12 +225,12 @@
   T* get() const { return ptr_; }
 
   T& operator*() const {
-    DCHECK(ptr_);
+    PA_DCHECK(ptr_);
     return *ptr_;
   }
 
   T* operator->() const {
-    DCHECK(ptr_);
+    PA_DCHECK(ptr_);
     return ptr_;
   }
 
diff --git a/base/allocator/partition_allocator/partition_alloc_base/native_library_posix.cc b/base/allocator/partition_allocator/partition_alloc_base/native_library_posix.cc
index 43be0aaf..b025cfbc 100644
--- a/base/allocator/partition_allocator/partition_alloc_base/native_library_posix.cc
+++ b/base/allocator/partition_allocator/partition_alloc_base/native_library_posix.cc
@@ -7,7 +7,7 @@
 #include <dlfcn.h>
 
 #include "base/allocator/partition_allocator/partition_alloc_base/files/file_path.h"
-#include "base/check.h"
+#include "base/allocator/partition_allocator/partition_alloc_check.h"
 #include "build/build_config.h"
 
 namespace partition_alloc::internal::base {
@@ -36,7 +36,7 @@
   // Certain platforms don't define RTLD_DEEPBIND. Android dlopen() requires
   // further investigation, as it might vary across versions. Crash here to
   // warn developers that they're trying to rely on uncertain behavior.
-  CHECK(!options.prefer_own_symbols);
+  PA_CHECK(!options.prefer_own_symbols);
 #else
   if (options.prefer_own_symbols)
     flags |= RTLD_DEEPBIND;
diff --git a/base/allocator/partition_allocator/partition_alloc_base/rand_util.cc b/base/allocator/partition_allocator/partition_alloc_base/rand_util.cc
index 6b0566b3..4915e02 100644
--- a/base/allocator/partition_allocator/partition_alloc_base/rand_util.cc
+++ b/base/allocator/partition_allocator/partition_alloc_base/rand_util.cc
@@ -10,7 +10,7 @@
 
 #include <limits>
 
-#include "base/check_op.h"
+#include "base/allocator/partition_allocator/partition_alloc_check.h"
 
 namespace partition_alloc::internal::base {
 
@@ -21,7 +21,7 @@
 }
 
 uint64_t RandGenerator(uint64_t range) {
-  DCHECK_GT(range, 0u);
+  PA_DCHECK(range > 0u);
   // We must discard random results above this number, as they would
   // make the random generator non-uniform (consider e.g. if
   // MAX_UINT64 was 7 and |range| was 5, then a result of 1 would be twice
diff --git a/base/allocator/partition_allocator/partition_alloc_base/rand_util_pa_unittest.cc b/base/allocator/partition_allocator/partition_alloc_base/rand_util_pa_unittest.cc
index f4fe93c..742deec2 100644
--- a/base/allocator/partition_allocator/partition_alloc_base/rand_util_pa_unittest.cc
+++ b/base/allocator/partition_allocator/partition_alloc_base/rand_util_pa_unittest.cc
@@ -15,7 +15,7 @@
 
 #include "base/allocator/partition_allocator/partition_alloc_base/logging.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/time/time.h"
-#include "base/check_op.h"
+#include "base/allocator/partition_allocator/partition_alloc_check.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace partition_alloc::internal::base {
@@ -180,7 +180,7 @@
                     int from_bit,
                     int num_bits) {
   const int range = 1 << num_bits;
-  CHECK_EQ(static_cast<int>(n % range), 0) << "Makes computations simpler";
+  PA_CHECK(static_cast<int>(n % range) == 0) << "Makes computations simpler";
   std::vector<size_t> samples(range, 0);
 
   // Count how many samples pf each value are found. All buckets should be
diff --git a/base/allocator/partition_allocator/partition_alloc_base/rand_util_posix.cc b/base/allocator/partition_allocator/partition_alloc_base/rand_util_posix.cc
index 859cb0d5..8e9df218 100644
--- a/base/allocator/partition_allocator/partition_alloc_base/rand_util_posix.cc
+++ b/base/allocator/partition_allocator/partition_alloc_base/rand_util_posix.cc
@@ -15,7 +15,7 @@
 #include "base/allocator/partition_allocator/partition_alloc_base/files/file_util.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/no_destructor.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/posix/eintr_wrapper.h"
-#include "base/check.h"
+#include "base/allocator/partition_allocator/partition_alloc_check.h"
 #include "build/build_config.h"
 
 #if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && !BUILDFLAG(IS_NACL)
@@ -42,7 +42,7 @@
 class URandomFd {
  public:
   URandomFd() : fd_(PA_HANDLE_EINTR(open("/dev/urandom", kOpenFlags))) {
-    CHECK(fd_ >= 0) << "Cannot open /dev/urandom";
+    PA_CHECK(fd_ >= 0) << "Cannot open /dev/urandom";
   }
 
   ~URandomFd() { close(fd_); }
@@ -96,7 +96,7 @@
   const int urandom_fd = GetUrandomFD();
   const bool success =
       ReadFromFD(urandom_fd, static_cast<char*>(output), output_length);
-  CHECK(success);
+  PA_CHECK(success);
 }
 
 }  // namespace partition_alloc::internal::base
diff --git a/base/allocator/partition_allocator/partition_alloc_base/rand_util_win.cc b/base/allocator/partition_allocator/partition_alloc_base/rand_util_win.cc
index fa8c636..b5775ad 100644
--- a/base/allocator/partition_allocator/partition_alloc_base/rand_util_win.cc
+++ b/base/allocator/partition_allocator/partition_alloc_base/rand_util_win.cc
@@ -18,7 +18,7 @@
 #include <algorithm>
 #include <limits>
 
-#include "base/check.h"
+#include "base/allocator/partition_allocator/partition_alloc_check.h"
 
 namespace partition_alloc::internal::base {
 
@@ -29,7 +29,7 @@
         output_length, static_cast<size_t>(std::numeric_limits<ULONG>::max())));
     const bool success =
         RtlGenRandom(output_ptr, output_bytes_this_pass) != FALSE;
-    CHECK(success);
+    PA_CHECK(success);
     output_length -= output_bytes_this_pass;
     output_ptr += output_bytes_this_pass;
   }
diff --git a/base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread_mac_for_testing.mm b/base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread_mac_for_testing.mm
index 8b5d028..d9046021 100644
--- a/base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread_mac_for_testing.mm
+++ b/base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread_mac_for_testing.mm
@@ -15,6 +15,7 @@
 #include <algorithm>
 #include <atomic>
 
+#include "base/allocator/partition_allocator/partition_alloc_check.h"
 #include "base/mac/foundation_util.h"
 #include "base/mac/mac_util.h"
 #include "build/build_config.h"
@@ -38,7 +39,7 @@
                            withObject:nil];
     multithreaded = YES;
 
-    DCHECK([NSThread isMultiThreaded]);
+    PA_DCHECK([NSThread isMultiThreaded]);
   }
 }
 
diff --git a/base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread_posix_for_testing.cc b/base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread_posix_for_testing.cc
index a1a44c6..4947e7b7 100644
--- a/base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread_posix_for_testing.cc
+++ b/base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread_posix_for_testing.cc
@@ -16,7 +16,7 @@
 #include "base/allocator/buildflags.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/logging.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread_internal_posix.h"
-#include "base/check_op.h"
+#include "base/allocator/partition_allocator/partition_alloc_check.h"
 #include "build/build_config.h"
 
 #if BUILDFLAG(IS_FUCHSIA)
@@ -71,7 +71,7 @@
 bool CreateThread(size_t stack_size,
                   PlatformThreadForTesting::Delegate* delegate,
                   PlatformThreadHandle* thread_handle) {
-  DCHECK(thread_handle);
+  PA_DCHECK(thread_handle);
   base::InitThreading();
 
   pthread_attr_t attributes;
@@ -135,7 +135,7 @@
   //
   // base::internal::ScopedBlockingCallWithBaseSyncPrimitives
   //   scoped_blocking_call(base::BlockingType::MAY_BLOCK);
-  CHECK_EQ(0, pthread_join(thread_handle.platform_handle(), nullptr));
+  PA_CHECK(0 == pthread_join(thread_handle.platform_handle(), nullptr));
 }
 
 // static
diff --git a/base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread_win_for_testing.cc b/base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread_win_for_testing.cc
index cdf045f..501e49e 100644
--- a/base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread_win_for_testing.cc
+++ b/base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread_win_for_testing.cc
@@ -8,8 +8,7 @@
 
 #include "base/allocator/buildflags.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/debug/alias.h"
-#include "base/check.h"
-#include "base/check_op.h"
+#include "base/allocator/partition_allocator/partition_alloc_check.h"
 #include "base/process/memory.h"
 #include "build/build_config.h"
 
@@ -156,7 +155,7 @@
 
 // static
 void PlatformThreadForTesting::Join(PlatformThreadHandle thread_handle) {
-  DCHECK(thread_handle.platform_handle());
+  PA_DCHECK(thread_handle.platform_handle());
 
   DWORD thread_id = 0;
   thread_id = ::GetThreadId(thread_handle.platform_handle());
@@ -178,7 +177,7 @@
 
   // Wait for the thread to exit.  It should already have terminated but make
   // sure this assumption is valid.
-  CHECK_EQ(WAIT_OBJECT_0,
+  PA_CHECK(WAIT_OBJECT_0 ==
            WaitForSingleObject(thread_handle.platform_handle(), INFINITE));
   CloseHandle(thread_handle.platform_handle());
 }
@@ -187,7 +186,7 @@
 bool PlatformThreadForTesting::Create(size_t stack_size,
                                       Delegate* delegate,
                                       PlatformThreadHandle* thread_handle) {
-  DCHECK(thread_handle);
+  PA_DCHECK(thread_handle);
   return CreateThreadInternal(stack_size, delegate, thread_handle);
 }
 
diff --git a/base/allocator/partition_allocator/partition_alloc_check.h b/base/allocator/partition_allocator/partition_alloc_check.h
index 58ad5c39..c888f86 100644
--- a/base/allocator/partition_allocator/partition_alloc_check.h
+++ b/base/allocator/partition_allocator/partition_alloc_check.h
@@ -9,9 +9,9 @@
 
 #include "base/allocator/buildflags.h"
 #include "base/allocator/partition_allocator/page_allocator_constants.h"
+#include "base/allocator/partition_allocator/partition_alloc_base/check.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/debug/alias.h"
 #include "base/allocator/partition_allocator/partition_alloc_base/immediate_crash.h"
-#include "base/check.h"
 #include "base/dcheck_is_on.h"
 #include "build/build_config.h"
 
@@ -32,22 +32,22 @@
 #if defined(OFFICIAL_BUILD) && defined(NDEBUG)
 // See base/check.h for implementation details.
 #define PA_CHECK(condition) \
-  UNLIKELY(!(condition)) ? PA_IMMEDIATE_CRASH() : EAT_CHECK_STREAM_PARAMS()
+  UNLIKELY(!(condition)) ? PA_IMMEDIATE_CRASH() : PA_EAT_CHECK_STREAM_PARAMS()
 #else
 // PartitionAlloc uses async-signal-safe RawCheck() for error reporting.
 // Async-signal-safe functions are guaranteed to not allocate as otherwise they
 // could operate with inconsistent allocator state.
 #define PA_CHECK(condition)                                                \
   UNLIKELY(!(condition))                                                   \
-  ? ::logging::RawCheck(                                                   \
+  ? ::partition_alloc::internal::logging::RawCheck(                        \
         __FILE__ "(" PA_STRINGIFY(__LINE__) ") Check failed: " #condition) \
-  : EAT_CHECK_STREAM_PARAMS()
+  : PA_EAT_CHECK_STREAM_PARAMS()
 #endif  // defined(OFFICIAL_BUILD) && defined(NDEBUG)
 
 #if DCHECK_IS_ON()
 #define PA_DCHECK(condition) PA_CHECK(condition)
 #else
-#define PA_DCHECK(condition) EAT_CHECK_STREAM_PARAMS(!(condition))
+#define PA_DCHECK(condition) PA_EAT_CHECK_STREAM_PARAMS(!(condition))
 #endif  // DCHECK_IS_ON()
 
 #define PA_PCHECK(condition)                                 \
@@ -57,10 +57,17 @@
     PA_IMMEDIATE_CRASH();                                    \
   }
 
+#if DCHECK_IS_ON()
+#define PA_DPCHECK(condition) PA_PCHECK(condition)
 #else
-#define PA_CHECK(condition) CHECK(condition)
-#define PA_DCHECK(condition) DCHECK(condition)
-#define PA_PCHECK(condition) PCHECK(condition)
+#define PA_DPCHECK(condition) PA_EAT_CHECK_STREAM_PARAMS(!(condition))
+#endif  // DCHECK_IS_ON()
+
+#else
+#define PA_CHECK(condition) PA_BASE_CHECK(condition)
+#define PA_DCHECK(condition) PA_BASE_DCHECK(condition)
+#define PA_PCHECK(condition) PA_BASE_PCHECK(condition)
+#define PA_DPCHECK(condition) PA_BASE_DPCHECK(condition)
 #endif  // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
 
 // Expensive dchecks that run within *Scan. These checks are only enabled in
@@ -74,7 +81,7 @@
 #if PA_SCAN_DCHECK_IS_ON()
 #define PA_SCAN_DCHECK(expr) PA_DCHECK(expr)
 #else
-#define PA_SCAN_DCHECK(expr) EAT_CHECK_STREAM_PARAMS(!(expr))
+#define PA_SCAN_DCHECK(expr) PA_EAT_CHECK_STREAM_PARAMS(!(expr))
 #endif
 
 #if defined(PAGE_ALLOCATOR_CONSTANTS_ARE_CONSTEXPR)
diff --git a/base/allocator/partition_allocator/partition_alloc_notreached.h b/base/allocator/partition_allocator/partition_alloc_notreached.h
index e04fe42..b745e958 100644
--- a/base/allocator/partition_allocator/partition_alloc_notreached.h
+++ b/base/allocator/partition_allocator/partition_alloc_notreached.h
@@ -6,7 +6,6 @@
 #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_NOTREACHED_H_
 
 #include "base/allocator/partition_allocator/partition_alloc_check.h"
-#include "base/check.h"
 #include "base/dcheck_is_on.h"
 #include "base/logging_buildflags.h"
 
@@ -16,10 +15,10 @@
 // So PA_NOTREACHED() uses PA_DCHECK() instead of DCHECK().
 
 #if BUILDFLAG(ENABLE_LOG_ERROR_NOT_REACHED)
-#define PA_NOTREACHED()                                                        \
-  true ? ::logging::RawError(__FILE__                                          \
-                             "(" PA_STRINGIFY(__LINE__) ") NOTREACHED() hit.") \
-       : EAT_CHECK_STREAM_PARAMS()
+#define PA_NOTREACHED()                                                    \
+  true ? ::partition_alloc::internal::logging::RawError(                   \
+             __FILE__ "(" PA_STRINGIFY(__LINE__) ") PA_NOTREACHED() hit.") \
+       : PA_EAT_CHECK_STREAM_PARAMS()
 
 #elif BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && defined(OFFICIAL_BUILD) && \
     defined(NDEBUG) && DCHECK_IS_ON()
@@ -37,11 +36,11 @@
 //     case Y:
 //     ...
 // So define PA_NOTREACHED() by using async-signal-safe RawCheck().
-#define PA_NOTREACHED()                                                   \
-  UNLIKELY(true)                                                          \
-  ? ::logging::RawCheck(__FILE__                                          \
-                        "(" PA_STRINGIFY(__LINE__) ") NOTREACHED() hit.") \
-  : EAT_CHECK_STREAM_PARAMS()
+#define PA_NOTREACHED()                                               \
+  UNLIKELY(true)                                                      \
+  ? ::partition_alloc::internal::logging::RawCheck(                   \
+        __FILE__ "(" PA_STRINGIFY(__LINE__) ") PA_NOTREACHED() hit.") \
+  : PA_EAT_CHECK_STREAM_PARAMS()
 
 #else
 
diff --git a/base/allocator/partition_allocator/partition_alloc_perftest.cc b/base/allocator/partition_allocator/partition_alloc_perftest.cc
index f0ea1cf..b8b6d0a3 100644
--- a/base/allocator/partition_allocator/partition_alloc_perftest.cc
+++ b/base/allocator/partition_allocator/partition_alloc_perftest.cc
@@ -193,7 +193,7 @@
   do {
     auto* next = reinterpret_cast<MemoryAllocationPerfNode*>(
         allocator->Alloc(kAllocSize));
-    CHECK_NE(next, nullptr);
+    PA_CHECK(next != nullptr);
     cur->SetNext(next);
     cur = next;
     timer.NextLap();
@@ -224,7 +224,7 @@
   base::LapTimer timer(kWarmupRuns, kTimeLimit, kTimeCheckInterval);
   do {
     void* cur = allocator->Alloc(kAllocSize);
-    CHECK_NE(cur, nullptr);
+    PA_CHECK(cur != nullptr);
     allocator->Free(cur);
     timer.NextLap();
   } while (!timer.HasTimeLimitExpired());
@@ -246,7 +246,7 @@
       size_t size = kMultiBucketMinimumSize + (i * kMultiBucketIncrement);
       auto* next =
           reinterpret_cast<MemoryAllocationPerfNode*>(allocator->Alloc(size));
-      CHECK_NE(next, nullptr);
+      PA_CHECK(next != nullptr);
       cur->SetNext(next);
       cur = next;
       allocated_memory += size;
@@ -278,7 +278,7 @@
   for (int i = 0; i < kMultiBucketRounds; i++) {
     void* cur =
         allocator->Alloc(kMultiBucketMinimumSize + (i * kMultiBucketIncrement));
-    CHECK_NE(cur, nullptr);
+    PA_CHECK(cur != nullptr);
     elems.push_back(cur);
   }
 
@@ -287,7 +287,7 @@
     for (int i = 0; i < kMultiBucketRounds; i++) {
       void* cur = allocator->Alloc(kMultiBucketMinimumSize +
                                    (i * kMultiBucketIncrement));
-      CHECK_NE(cur, nullptr);
+      PA_CHECK(cur != nullptr);
       allocator->Free(cur);
     }
     timer.NextLap();
@@ -306,7 +306,7 @@
   base::LapTimer timer(kWarmupRuns, kTimeLimit, kTimeCheckInterval);
   do {
     void* cur = allocator->Alloc(kSize);
-    CHECK_NE(cur, nullptr);
+    PA_CHECK(cur != nullptr);
     allocator->Free(cur);
     timer.NextLap();
   } while (!timer.HasTimeLimitExpired());
diff --git a/base/allocator/partition_allocator/partition_alloc_unittest.cc b/base/allocator/partition_allocator/partition_alloc_unittest.cc
index e65dbc8..bb4f06b 100644
--- a/base/allocator/partition_allocator/partition_alloc_unittest.cc
+++ b/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -2831,7 +2831,7 @@
   const size_t kSecondAllocPages = kHasLargePages ? 31 : 61;
 
   // Detect case (1) from above.
-  DCHECK_LT(kFirstAllocPages * SystemPageSize(), 1UL << kMaxBucketedOrder);
+  PA_DCHECK(kFirstAllocPages * SystemPageSize() < (1UL << kMaxBucketedOrder));
 
   const size_t kDeltaPages = kFirstAllocPages - kSecondAllocPages;
 
@@ -4289,7 +4289,7 @@
   const size_t min_pool_size = PartitionAddressSpace::ConfigurablePoolMinSize();
   for (size_t pool_size = max_pool_size; pool_size >= min_pool_size;
        pool_size /= 2) {
-    DCHECK(partition_alloc::internal::base::bits::IsPowerOfTwo(pool_size));
+    PA_DCHECK(partition_alloc::internal::base::bits::IsPowerOfTwo(pool_size));
     EXPECT_FALSE(IsConfigurablePoolAvailable());
     uintptr_t pool_base = AllocPages(
         pool_size, pool_size, PageAccessibilityConfiguration::kInaccessible,
diff --git a/base/allocator/partition_allocator/partition_bucket.cc b/base/allocator/partition_allocator/partition_bucket.cc
index 840d062..70d06a0 100644
--- a/base/allocator/partition_allocator/partition_bucket.cc
+++ b/base/allocator/partition_allocator/partition_bucket.cc
@@ -31,7 +31,6 @@
 #include "base/allocator/partition_allocator/reservation_offset_table.h"
 #include "base/allocator/partition_allocator/starscan/state_bitmap.h"
 #include "base/allocator/partition_allocator/tagging.h"
-#include "base/check.h"
 #include "build/build_config.h"
 
 namespace partition_alloc::internal {
diff --git a/base/win/scoped_handle_unittest.cc b/base/win/scoped_handle_unittest.cc
index 1b4ccbc..1b41733e 100644
--- a/base/win/scoped_handle_unittest.cc
+++ b/base/win/scoped_handle_unittest.cc
@@ -105,7 +105,8 @@
       FailureMessage("CloseHandle failed"));
 }
 
-TEST_P(ScopedHandleDeathTest, HandleVerifierCloseTrackedHandle) {
+// TODO(crbug.com/1328022): Flaky on Windows 7, deflake and re-enable.
+TEST_P(ScopedHandleDeathTest, DISABLED_HandleVerifierCloseTrackedHandle) {
   // This test is only valid if hooks are enabled.
   if (!HooksEnabled())
     return;
@@ -130,7 +131,8 @@
       FailureMessage("CloseHandleHook validation failure"));
 }
 
-TEST_P(ScopedHandleDeathTest, HandleVerifierDoubleTracking) {
+// TODO(crbug.com/1328022): Flaky on Windows 7, deflake and re-enable.
+TEST_P(ScopedHandleDeathTest, DISABLED_HandleVerifierDoubleTracking) {
   HANDLE handle = ::CreateMutex(nullptr, false, nullptr);
   ASSERT_NE(HANDLE(nullptr), handle);
 
@@ -139,7 +141,8 @@
   ASSERT_DEATH({ base::win::CheckedScopedHandle handle_holder2(handle); }, "");
 }
 
-TEST_P(ScopedHandleDeathTest, HandleVerifierWrongOwner) {
+// TODO(crbug.com/1328022): Flaky on Windows 7, deflake and re-enable.
+TEST_P(ScopedHandleDeathTest, DISABLED_HandleVerifierWrongOwner) {
   HANDLE handle = ::CreateMutex(nullptr, false, nullptr);
   ASSERT_NE(HANDLE(nullptr), handle);
 
@@ -154,7 +157,8 @@
   handle_holder.Close();
 }
 
-TEST_P(ScopedHandleDeathTest, HandleVerifierUntrackedHandle) {
+// TODO(crbug.com/1328022): Flaky on Windows 7, deflake and re-enable.
+TEST_P(ScopedHandleDeathTest, DISABLED_HandleVerifierUntrackedHandle) {
   HANDLE handle = ::CreateMutex(nullptr, false, nullptr);
   ASSERT_NE(HANDLE(nullptr), handle);
 
diff --git a/build/toolchain/win/ml.py b/build/toolchain/win/ml.py
deleted file mode 100755
index 6a1b6e57..0000000
--- a/build/toolchain/win/ml.py
+++ /dev/null
@@ -1,290 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2018 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Wraps ml.exe or ml64.exe and postprocesses the output to be deterministic.
-Sets timestamp in .obj file to 0, hence incompatible with link.exe /incremental.
-
-Use by prefixing the ml(64).exe invocation with this script:
-    python ml.py ml.exe [args...]"""
-
-import array
-import collections
-import struct
-import subprocess
-import sys
-
-
-class Struct(object):
-  """A thin wrapper around the struct module that returns a namedtuple"""
-  def __init__(self, name, *args):
-    """Pass the name of the return type, and then an interleaved list of
-    format strings as used by the struct module and of field names."""
-    self.fmt = '<' + ''.join(args[0::2])
-    self.type = collections.namedtuple(name, args[1::2])
-
-  def pack_into(self, buffer, offset, data):
-    return struct.pack_into(self.fmt, buffer, offset, *data)
-
-  def unpack_from(self, buffer, offset=0):
-    return self.type(*struct.unpack_from(self.fmt, buffer, offset))
-
-  def size(self):
-    return struct.calcsize(self.fmt)
-
-
-def Subtract(nt, **kwargs):
-  """Subtract(nt, f=2) returns a new namedtuple with 2 subtracted from nt.f"""
-  return nt._replace(**{k: getattr(nt, k) - v for k, v in kwargs.items()})
-
-
-def MakeDeterministic(objdata):
-  # Takes data produced by ml(64).exe (without any special flags) and
-  # 1. Sets the timestamp to 0
-  # 2. Strips the .debug$S section (which contains an unwanted absolute path)
-
-  # This makes several assumptions about ml's output:
-  # - Section data is in the same order as the corresponding section headers:
-  #   section headers preceding the .debug$S section header have their data
-  #   preceding the .debug$S section data; likewise for section headers
-  #   following the .debug$S section.
-  # - The .debug$S section contains only the absolute path to the obj file and
-  #   nothing else, in particular there's only a single entry in the symbol
-  #   table referring to the .debug$S section.
-  # - There are no COFF line number entries.
-  # - There's no IMAGE_SYM_CLASS_CLR_TOKEN symbol.
-  # These seem to hold in practice; if they stop holding this script needs to
-  # become smarter.
-
-  objdata = array.array('b', objdata)  # Writable, e.g. via struct.pack_into.
-
-  # Read coff header.
-  COFFHEADER = Struct('COFFHEADER',
-                      'H', 'Machine',
-                      'H', 'NumberOfSections',
-                      'I', 'TimeDateStamp',
-                      'I', 'PointerToSymbolTable',
-                      'I', 'NumberOfSymbols',
-
-                      'H', 'SizeOfOptionalHeader',
-                      'H', 'Characteristics')
-  coff_header = COFFHEADER.unpack_from(objdata)
-  assert coff_header.SizeOfOptionalHeader == 0  # Only set for binaries.
-
-  # Read section headers following coff header.
-  SECTIONHEADER = Struct('SECTIONHEADER',
-                         '8s', 'Name',
-                         'I', 'VirtualSize',
-                         'I', 'VirtualAddress',
-
-                         'I', 'SizeOfRawData',
-                         'I', 'PointerToRawData',
-                         'I', 'PointerToRelocations',
-                         'I', 'PointerToLineNumbers',
-
-                         'H', 'NumberOfRelocations',
-                         'H', 'NumberOfLineNumbers',
-                         'I', 'Characteristics')
-  section_headers = []
-  debug_section_index = -1
-  for i in range(0, coff_header.NumberOfSections):
-    section_header = SECTIONHEADER.unpack_from(
-        objdata, offset=COFFHEADER.size() + i * SECTIONHEADER.size())
-    assert not section_header[0].startswith(b'/')  # Support short names only.
-    section_headers.append(section_header)
-
-    if section_header.Name == b'.debug$S':
-      assert debug_section_index == -1
-      debug_section_index = i
-  assert debug_section_index != -1
-
-  data_start = COFFHEADER.size() + len(section_headers) * SECTIONHEADER.size()
-
-  # Verify the .debug$S section looks like we expect.
-  assert section_headers[debug_section_index].Name == b'.debug$S'
-  assert section_headers[debug_section_index].VirtualSize == 0
-  assert section_headers[debug_section_index].VirtualAddress == 0
-  debug_size = section_headers[debug_section_index].SizeOfRawData
-  debug_offset = section_headers[debug_section_index].PointerToRawData
-  assert section_headers[debug_section_index].PointerToRelocations == 0
-  assert section_headers[debug_section_index].PointerToLineNumbers == 0
-  assert section_headers[debug_section_index].NumberOfRelocations == 0
-  assert section_headers[debug_section_index].NumberOfLineNumbers == 0
-
-  # Make sure sections in front of .debug$S have their data preceding it.
-  for header in section_headers[:debug_section_index]:
-    assert header.PointerToRawData < debug_offset
-    assert header.PointerToRelocations < debug_offset
-    assert header.PointerToLineNumbers < debug_offset
-
-  # Make sure sections after of .debug$S have their data following it.
-  for header in section_headers[debug_section_index + 1:]:
-    # Make sure the .debug$S data is at the very end of section data:
-    assert header.PointerToRawData > debug_offset
-    assert header.PointerToRelocations == 0
-    assert header.PointerToLineNumbers == 0
-
-  # Make sure the first non-empty section's data starts right after the section
-  # headers.
-  for section_header in section_headers:
-    if section_header.PointerToRawData == 0:
-      assert section_header.PointerToRelocations == 0
-      assert section_header.PointerToLineNumbers == 0
-      continue
-    assert section_header.PointerToRawData == data_start
-    break
-
-  # Make sure the symbol table (and hence, string table) appear after the last
-  # section:
-  assert (coff_header.PointerToSymbolTable >=
-      section_headers[-1].PointerToRawData + section_headers[-1].SizeOfRawData)
-
-  # The symbol table contains a symbol for the no-longer-present .debug$S
-  # section. If we leave it there, lld-link will complain:
-  #
-  #    lld-link: error: .debug$S should not refer to non-existent section 5
-  #
-  # so we need to remove that symbol table entry as well. This shifts symbol
-  # entries around and we need to update symbol table indices in:
-  # - relocations
-  # - line number records (never present)
-  # - one aux symbol entry (IMAGE_SYM_CLASS_CLR_TOKEN; not present in ml output)
-  SYM = Struct('SYM',
-               '8s', 'Name',
-               'I', 'Value',
-               'h', 'SectionNumber',  # Note: Signed!
-               'H', 'Type',
-
-               'B', 'StorageClass',
-               'B', 'NumberOfAuxSymbols')
-  i = 0
-  debug_sym = -1
-  while i < coff_header.NumberOfSymbols:
-    sym_offset = coff_header.PointerToSymbolTable + i * SYM.size()
-    sym = SYM.unpack_from(objdata, sym_offset)
-
-    # 107 is IMAGE_SYM_CLASS_CLR_TOKEN, which has aux entry "CLR Token
-    # Definition", which contains a symbol index. Check it's never present.
-    assert sym.StorageClass != 107
-
-    # Note: sym.SectionNumber is 1-based, debug_section_index is 0-based.
-    if sym.SectionNumber - 1 == debug_section_index:
-      assert debug_sym == -1, 'more than one .debug$S symbol found'
-      debug_sym = i
-      # Make sure the .debug$S symbol looks like we expect.
-      # In particular, it should have exactly one aux symbol.
-      assert sym.Name == b'.debug$S'
-      assert sym.Value == 0
-      assert sym.Type == 0
-      assert sym.StorageClass == 3
-      assert sym.NumberOfAuxSymbols == 1
-    elif sym.SectionNumber > debug_section_index:
-      sym = Subtract(sym, SectionNumber=1)
-      SYM.pack_into(objdata, sym_offset, sym)
-    i += 1 + sym.NumberOfAuxSymbols
-  assert debug_sym != -1, '.debug$S symbol not found'
-
-  # Note: Usually the .debug$S section is the last, but for files saying
-  # `includelib foo.lib`, like safe_terminate_process.asm in 32-bit builds,
-  # this isn't true: .drectve is after .debug$S.
-
-  # Update symbol table indices in relocations.
-  # There are a few processor types that have one or two relocation types
-  # where SymbolTableIndex has a different meaning, but not for x86.
-  REL = Struct('REL',
-               'I', 'VirtualAddress',
-               'I', 'SymbolTableIndex',
-               'H', 'Type')
-  for header in section_headers[0:debug_section_index]:
-    for j in range(0, header.NumberOfRelocations):
-      rel_offset = header.PointerToRelocations + j * REL.size()
-      rel = REL.unpack_from(objdata, rel_offset)
-      assert rel.SymbolTableIndex != debug_sym
-      if rel.SymbolTableIndex > debug_sym:
-        rel = Subtract(rel, SymbolTableIndex=2)
-        REL.pack_into(objdata, rel_offset, rel)
-
-  # Update symbol table indices in line numbers -- just check they don't exist.
-  for header in section_headers:
-    assert header.NumberOfLineNumbers == 0
-
-  # Now that all indices are updated, remove the symbol table entry referring to
-  # .debug$S and its aux entry.
-  del objdata[coff_header.PointerToSymbolTable + debug_sym * SYM.size():
-              coff_header.PointerToSymbolTable + (debug_sym + 2) * SYM.size()]
-
-  # Now we know that it's safe to write out the input data, with just the
-  # timestamp overwritten to 0, the last section header cut out (and the
-  # offsets of all other section headers decremented by the size of that
-  # one section header), and the last section's data cut out. The symbol
-  # table offset needs to be reduced by one section header and the size of
-  # the missing section.
-  # (The COFF spec only requires on-disk sections to be aligned in image files,
-  # for obj files it's not required. If that wasn't the case, deleting slices
-  # if data would not generally be safe.)
-
-  # Update section offsets and remove .debug$S section data.
-  for i in range(0, debug_section_index):
-    header = section_headers[i]
-    if header.SizeOfRawData:
-      header = Subtract(header, PointerToRawData=SECTIONHEADER.size())
-    if header.NumberOfRelocations:
-      header = Subtract(header, PointerToRelocations=SECTIONHEADER.size())
-    if header.NumberOfLineNumbers:
-      header = Subtract(header, PointerToLineNumbers=SECTIONHEADER.size())
-    SECTIONHEADER.pack_into(
-        objdata, COFFHEADER.size() + i * SECTIONHEADER.size(), header)
-  for i in range(debug_section_index + 1, len(section_headers)):
-    header = section_headers[i]
-    shift = SECTIONHEADER.size() + debug_size
-    if header.SizeOfRawData:
-      header = Subtract(header, PointerToRawData=shift)
-    if header.NumberOfRelocations:
-      header = Subtract(header, PointerToRelocations=shift)
-    if header.NumberOfLineNumbers:
-      header = Subtract(header, PointerToLineNumbers=shift)
-    SECTIONHEADER.pack_into(
-        objdata, COFFHEADER.size() + i * SECTIONHEADER.size(), header)
-
-  del objdata[debug_offset:debug_offset + debug_size]
-
-  # Finally, remove .debug$S section header and update coff header.
-  coff_header = coff_header._replace(TimeDateStamp=0)
-  coff_header = Subtract(coff_header,
-                         NumberOfSections=1,
-                         PointerToSymbolTable=SECTIONHEADER.size() + debug_size,
-                         NumberOfSymbols=2)
-  COFFHEADER.pack_into(objdata, 0, coff_header)
-
-  del objdata[
-      COFFHEADER.size() + debug_section_index * SECTIONHEADER.size():
-      COFFHEADER.size() + (debug_section_index + 1) * SECTIONHEADER.size()]
-
-  # All done!
-  if sys.version_info.major == 2:
-    return objdata.tostring()
-  else:
-    return objdata.tobytes()
-
-
-def main():
-  ml_result = subprocess.call(sys.argv[1:])
-  if ml_result != 0:
-    return ml_result
-
-  objfile = None
-  for i in range(1, len(sys.argv)):
-    if sys.argv[i].startswith('/Fo'):
-      objfile = sys.argv[i][len('/Fo'):]
-  assert objfile, 'failed to find ml output'
-
-  with open(objfile, 'rb') as f:
-    objdata = f.read()
-  objdata = MakeDeterministic(objdata)
-  with open(objfile, 'wb') as f:
-    f.write(objdata)
-
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/build/toolchain/win/toolchain.gni b/build/toolchain/win/toolchain.gni
index e7fd6209..9cdcc6bf 100644
--- a/build/toolchain/win/toolchain.gni
+++ b/build/toolchain/win/toolchain.gni
@@ -254,11 +254,12 @@
           ml = "armasm64.exe"
         }
       } else {
-        # x86/x64 builds always use the MSVC assembler.
+        prefix = rebase_path("$clang_base_path/bin", root_build_dir)
+        ml = "$prefix/llvm-ml.exe"
         if (toolchain_args.current_cpu == "x64") {
-          ml = "ml64.exe"
+          ml += " --m64"
         } else {
-          ml = "ml.exe"
+          ml += " --m32"
         }
       }
 
@@ -270,16 +271,6 @@
         if (toolchain_args.current_cpu != "arm64") {
           ml += " /c"
         }
-        if (use_lld) {
-          # Wrap ml(64).exe with a script that makes its output deterministic.
-          # It's lld only because the script zaps obj Timestamp which
-          # link.exe /incremental looks at.
-          # TODO(https://crbug.com/762167): If we end up writing an llvm-ml64,
-          # make sure it has deterministic output (maybe with /Brepro or
-          # something) and remove this wrapper.
-          ml_py = rebase_path("//build/toolchain/win/ml.py", root_build_dir)
-          ml = "$python_path $ml_py $ml"
-        }
       }
       if (toolchain_args.current_cpu != "arm64" || toolchain_is_clang) {
         command = "$python_path $_tool_wrapper_path asm-wrapper $env $ml {{defines}} {{include_dirs}} {{asmflags}} {{source}}"
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index ebf4a04..7629f1f 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -712,7 +712,6 @@
   "java/src/org/chromium/chrome/browser/init/NativeStartupBridge.java",
   "java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java",
   "java/src/org/chromium/chrome/browser/init/SingleWindowKeyboardVisibilityDelegate.java",
-  "java/src/org/chromium/chrome/browser/init/StartupTabPreloader.java",
   "java/src/org/chromium/chrome/browser/installedapp/InstalledAppProviderFactory.java",
   "java/src/org/chromium/chrome/browser/instantapps/AuthenticatedProxyActivity.java",
   "java/src/org/chromium/chrome/browser/instantapps/InstantAppsBannerData.java",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni
index 1255160..b80d1f9 100644
--- a/chrome/android/chrome_test_java_sources.gni
+++ b/chrome/android/chrome_test_java_sources.gni
@@ -165,7 +165,6 @@
   "javatests/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabActivityTestRule.java",
   "javatests/src/org/chromium/chrome/browser/customtabs/TabReparentingTest.java",
   "javatests/src/org/chromium/chrome/browser/customtabs/TrustedCdnPublisherUrlTest.java",
-  "javatests/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabControllerTest.java",
   "javatests/src/org/chromium/chrome/browser/customtabs/content/TabObserverRegistrarTest.java",
   "javatests/src/org/chromium/chrome/browser/dependency_injection/ModuleOverridesRule.java",
   "javatests/src/org/chromium/chrome/browser/device_dialog/BluetoothChooserDialogTest.java",
@@ -263,9 +262,6 @@
   "javatests/src/org/chromium/chrome/browser/init/ChainedTasksTest.java",
   "javatests/src/org/chromium/chrome/browser/init/ChromeBrowserInitializerTest.java",
   "javatests/src/org/chromium/chrome/browser/init/FirstDrawDetectorTest.java",
-  "javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderCustomTabTest.java",
-  "javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderTest.java",
-  "javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderUnitTest.java",
   "javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java",
   "javatests/src/org/chromium/chrome/browser/instantapps/InstantAppsHandlerTest.java",
   "javatests/src/org/chromium/chrome/browser/interstitials/LookalikeInterstitialTest.java",
diff --git a/chrome/android/expectations/lint-baseline.xml b/chrome/android/expectations/lint-baseline.xml
index dfae2cf..2d71bed6 100644
--- a/chrome/android/expectations/lint-baseline.xml
+++ b/chrome/android/expectations/lint-baseline.xml
@@ -7580,18 +7580,7 @@
             column="85"/>
     </issue>
 
-    <issue
-        id="WrongConstant"
-        message="Must be one of: LoadDecisionReason.DISABLED_BY_INTENT, LoadDecisionReason.INCOGNITO, LoadDecisionReason.INTENT_IGNORED, LoadDecisionReason.NO_URL, LoadDecisionReason.NO_TAB_CREATOR, LoadDecisionReason.WRONG_TAB_CREATOR, LoadDecisionReason.DISABLED_BY_FEATURE, LoadDecisionReason.ALL_SATISFIED"
-        errorLine1="                    getLoadDecisionReason(), LoadDecisionReason.NUM_ENTRIES);"
-        errorLine2="                                                                ~~~~~~~~~~~">
-        <location
-            file="../../chrome/android/java/src/org/chromium/chrome/browser/init/StartupTabPreloader.java"
-            line="356"
-            column="65"/>
-    </issue>
-
-    <issue
+     <issue
         id="WrongConstant"
         message="Must be one of: ApiCall.ADD_WEB_MESSAGE_LISTENER, ApiCall.CLEAR_PROXY_OVERRIDE, ApiCall.GET_PROXY_CONTROLLER, ApiCall.GET_SAFE_BROWSING_PRIVACY_POLICY_URL, ApiCall.GET_SERVICE_WORKER_CONTROLLER, ApiCall.GET_SERVICE_WORKER_WEB_SETTINGS, ApiCall.GET_TRACING_CONTROLLER, ApiCall.GET_WEBCHROME_CLIENT, ApiCall.GET_WEBVIEW_CLIENT, ApiCall.GET_WEBVIEW_RENDERER, ApiCall.GET_WEBVIEW_RENDERER_CLIENT, ApiCall.INIT_SAFE_BROWSING, ApiCall.INSERT_VISUAL_STATE_CALLBACK, ApiCall.IS_MULTI_PROCESS_ENABLED, ApiCall.JS_REPLY_POST_MESSAGE, ApiCall.POST_MESSAGE_TO_MAIN_FRAME, ApiCall.REMOVE_WEB_MESSAGE_LISTENER, ApiCall.SERVICE_WORKER_SETTINGS_GET_ALLOW_CONTENT_ACCESS, ApiCall.SERVICE_WORKER_SETTINGS_GET_ALLOW_FILE_ACCESS, ApiCall.SERVICE_WORKER_SETTINGS_GET_BLOCK_NETWORK_LOADS, ApiCall.SERVICE_WORKER_SETTINGS_GET_CACHE_MODE, ApiCall.SERVICE_WORKER_SETTINGS_SET_ALLOW_CONTENT_ACCESS, ApiCall.SERVICE_WORKER_SETTINGS_SET_ALLOW_FILE_ACCESS, ApiCall.SERVICE_WORKER_SETTINGS_SET_BLOCK_NETWORK_LOADS, ApiCall.SERVICE_WORKER_SETTINGS_SET_CACHE_MODE, ApiCall.SET_PROXY_OVERRIDE, ApiCall.SET_SAFE_BROWSING_ALLOWLIST_DEPRECATED_NAME, ApiCall.SET_SERVICE_WORKER_CLIENT, ApiCall.SET_WEBVIEW_RENDERER_CLIENT, ApiCall.TRACING_CONTROLLER_IS_TRACING, ApiCall.TRACING_CONTROLLER_START, ApiCall.TRACING_CONTROLLER_STOP, ApiCall.WEB_MESSAGE_GET_DATA, ApiCall.WEB_MESSAGE_GET_PORTS, ApiCall.WEB_MESSAGE_PORT_CLOSE, ApiCall.WEB_MESSAGE_PORT_POST_MESSAGE, ApiCall.WEB_MESSAGE_PORT_SET_CALLBACK, ApiCall.WEB_MESSAGE_PORT_SET_CALLBACK_WITH_HANDLER, ApiCall.WEB_RESOURCE_REQUEST_IS_REDIRECT, ApiCall.WEB_SETTINGS_GET_DISABLED_ACTION_MODE_MENU_ITEMS, ApiCall.WEB_SETTINGS_GET_FORCE_DARK, ApiCall.WEB_SETTINGS_GET_FORCE_DARK_BEHAVIOR, ApiCall.WEB_SETTINGS_GET_OFFSCREEN_PRE_RASTER, ApiCall.WEB_SETTINGS_GET_SAFE_BROWSING_ENABLED, ApiCall.WEB_SETTINGS_GET_WILL_SUPPRESS_ERROR_PAGE, ApiCall.WEB_SETTINGS_SET_DISABLED_ACTION_MODE_MENU_ITEMS, ApiCall.WEB_SETTINGS_SET_FORCE_DARK, ApiCall.WEB_SETTINGS_SET_FORCE_DARK_BEHAVIOR, ApiCall.WEB_SETTINGS_SET_OFFSCREEN_PRE_RASTER, ApiCall.WEB_SETTINGS_SET_SAFE_BROWSING_ENABLED, ApiCall.WEB_SETTINGS_SET_WILL_SUPPRESS_ERROR_PAGE, ApiCall.WEBVIEW_RENDERER_TERMINATE, ApiCall.ADD_DOCUMENT_START_SCRIPT, ApiCall.REMOVE_DOCUMENT_START_SCRIPT, ApiCall.SET_SAFE_BROWSING_ALLOWLIST, ApiCall.SET_PROXY_OVERRIDE_REVERSE_BYPASS"
         errorLine1="                &quot;Android.WebView.AndroidX.ApiCall&quot;, apiCall, ApiCall.COUNT);"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index c5742ba..ed86565 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -1934,14 +1934,12 @@
             };
         }
         return Pair.create(
-                new ChromeTabCreator(this, getWindowAndroid(), getStartupTabPreloader(),
-                        this::getTabDelegateFactory, false, overviewNTPCreator,
-                        AsyncTabParamsManagerSingleton.getInstance(), getTabModelSelectorSupplier(),
-                        getCompositorViewHolderSupplier()),
-                new ChromeTabCreator(this, getWindowAndroid(), getStartupTabPreloader(),
-                        this::getTabDelegateFactory, true, overviewNTPCreator,
-                        AsyncTabParamsManagerSingleton.getInstance(), getTabModelSelectorSupplier(),
-                        getCompositorViewHolderSupplier()));
+                new ChromeTabCreator(this, getWindowAndroid(), this::getTabDelegateFactory, false,
+                        overviewNTPCreator, AsyncTabParamsManagerSingleton.getInstance(),
+                        getTabModelSelectorSupplier(), getCompositorViewHolderSupplier()),
+                new ChromeTabCreator(this, getWindowAndroid(), this::getTabDelegateFactory, true,
+                        overviewNTPCreator, AsyncTabParamsManagerSingleton.getInstance(),
+                        getTabModelSelectorSupplier(), getCompositorViewHolderSupplier()));
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/DEPS b/chrome/android/java/src/org/chromium/chrome/browser/DEPS
index c7655683..d1dac274 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/DEPS
+++ b/chrome/android/java/src/org/chromium/chrome/browser/DEPS
@@ -102,9 +102,6 @@
   "IncognitoNotificationServiceImpl\.java": [
     "+chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
   ],
-  "StartupTabPreloader\.java": [
-    "+chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
-  ],
   "MultiInstanceChromeTabbedActivity\.java": [
     "+chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java"
   ],
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
index 16bb332..5dd38e4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -123,7 +123,6 @@
 import org.chromium.chrome.browser.history.HistoryManagerUtils;
 import org.chromium.chrome.browser.init.AsyncInitializationActivity;
 import org.chromium.chrome.browser.init.ProcessInitializationHandler;
-import org.chromium.chrome.browser.init.StartupTabPreloader;
 import org.chromium.chrome.browser.keyboard_accessory.ManualFillingComponent;
 import org.chromium.chrome.browser.keyboard_accessory.ManualFillingComponentFactory;
 import org.chromium.chrome.browser.keyboard_accessory.ManualFillingComponentSupplier;
@@ -381,9 +380,6 @@
     @Nullable
     private BottomContainer mBottomContainer;
 
-    @Nullable
-    private StartupTabPreloader mStartupTabPreloader;
-
     private LaunchCauseMetrics mLaunchCauseMetrics;
 
     private GSAAccountChangeListener mGSAAccountChangeListener;
@@ -839,19 +835,6 @@
     }
 
     /**
-     * @return The {@link StartupTabPreloader} associated with this ChromeActivity. If there isn't
-     *         one it creates it.
-     */
-    protected StartupTabPreloader getStartupTabPreloader() {
-        if (mStartupTabPreloader == null) {
-            mStartupTabPreloader = new StartupTabPreloader(this::getIntent,
-                    getLifecycleDispatcher(), getWindowAndroid(), this, mIntentHandler,
-                    getActivityTabStartupMetricsTracker());
-        }
-        return mStartupTabPreloader;
-    }
-
-    /**
      * @return The {@link TabModelOrchestrator} owned by this {@link ChromeActivity}.
      */
     protected abstract TabModelOrchestrator createTabModelOrchestrator();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
index d7f9193..470cef6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -90,7 +90,6 @@
                 add(ChromeFeatureList.EARLY_LIBRARY_LOAD);
                 add(ChromeFeatureList.ELASTIC_OVERSCROLL);
                 add(ChromeFeatureList.ELIDE_PRIORITIZATION_OF_PRE_NATIVE_BOOTSTRAP_TASKS);
-                add(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP);
                 add(ChromeFeatureList.FEED_LOADING_PLACEHOLDER);
                 add(ChromeFeatureList
                                 .GIVE_JAVA_UI_THREAD_DEFAULT_TASK_TRAITS_USER_BLOCKING_PRIORITY);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
index 3aed83a..3d62f84dc 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
@@ -184,12 +184,11 @@
 
         BaseCustomTabActivityModule baseCustomTabsModule = overridenBaseCustomTabFactory != null
                 ? overridenBaseCustomTabFactory.create(mIntentDataProvider,
-                        getStartupTabPreloader(), mNightModeStateController,
-                        intentIgnoringCriterion, getTopUiThemeColorProvider(),
-                        new DefaultBrowserProviderImpl())
-                : new BaseCustomTabActivityModule(mIntentDataProvider, getStartupTabPreloader(),
                         mNightModeStateController, intentIgnoringCriterion,
-                        getTopUiThemeColorProvider(), new DefaultBrowserProviderImpl());
+                        getTopUiThemeColorProvider(), new DefaultBrowserProviderImpl())
+                : new BaseCustomTabActivityModule(mIntentDataProvider, mNightModeStateController,
+                        intentIgnoringCriterion, getTopUiThemeColorProvider(),
+                        new DefaultBrowserProviderImpl());
         BaseCustomTabActivityComponent component =
                 ChromeApplicationImpl.getComponent().createBaseCustomTabActivityComponent(
                         commonsModule, baseCustomTabsModule);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java
index bfa7245..5887ede 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java
@@ -16,7 +16,6 @@
 import androidx.annotation.Nullable;
 import androidx.appcompat.app.AppCompatActivity;
 import androidx.browser.customtabs.CustomTabsSessionToken;
-import androidx.browser.trusted.sharing.ShareTarget;
 
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.supplier.Supplier;
@@ -29,7 +28,6 @@
 import org.chromium.chrome.browser.app.tab_activity_glue.ReparentingDelegateFactory;
 import org.chromium.chrome.browser.app.tabmodel.TabModelOrchestrator;
 import org.chromium.chrome.browser.browserservices.intents.BrowserServicesIntentDataProvider;
-import org.chromium.chrome.browser.browserservices.intents.WebApkExtras;
 import org.chromium.chrome.browser.compositor.CompositorViewHolder;
 import org.chromium.chrome.browser.customtabs.CustomTabDelegateFactory;
 import org.chromium.chrome.browser.customtabs.CustomTabIncognitoManager;
@@ -42,7 +40,6 @@
 import org.chromium.chrome.browser.customtabs.PageLoadMetricsObserver;
 import org.chromium.chrome.browser.customtabs.ReparentingTaskProvider;
 import org.chromium.chrome.browser.dependency_injection.ActivityScope;
-import org.chromium.chrome.browser.init.StartupTabPreloader;
 import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
 import org.chromium.chrome.browser.lifecycle.InflationObserver;
 import org.chromium.chrome.browser.profiles.Profile;
@@ -51,7 +48,6 @@
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabAssociatedApp;
 import org.chromium.chrome.browser.tab.TabCreationState;
-import org.chromium.chrome.browser.tab.TabLaunchType;
 import org.chromium.chrome.browser.tab.TabObserver;
 import org.chromium.chrome.browser.tabmodel.AsyncTabParams;
 import org.chromium.chrome.browser.tabmodel.AsyncTabParamsManager;
@@ -61,10 +57,7 @@
 import org.chromium.chrome.browser.tabmodel.TabModelSelectorBase;
 import org.chromium.chrome.browser.tabmodel.TabReparentingParams;
 import org.chromium.chrome.browser.translate.TranslateBridge;
-import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.content_public.browser.WebContents;
-import org.chromium.content_public.common.Referrer;
-import org.chromium.network.mojom.ReferrerPolicy;
 import org.chromium.ui.base.ActivityWindowAndroid;
 
 import java.lang.annotation.Retention;
@@ -107,7 +100,6 @@
     private final CustomTabNavigationEventObserver mTabNavigationEventObserver;
     private final ActivityTabProvider mActivityTabProvider;
     private final CustomTabActivityTabProvider mTabProvider;
-    private final StartupTabPreloader mStartupTabPreloader;
     private final ReparentingTaskProvider mReparentingTaskProvider;
     private final Lazy<CustomTabIncognitoManager> mCustomTabIncognitoManager;
     private final Lazy<AsyncTabParamsManager> mAsyncTabParamsManager;
@@ -129,7 +121,7 @@
             CustomTabTabPersistencePolicy persistencePolicy, CustomTabActivityTabFactory tabFactory,
             Lazy<CustomTabObserver> customTabObserver, WebContentsFactory webContentsFactory,
             CustomTabNavigationEventObserver tabNavigationEventObserver,
-            CustomTabActivityTabProvider tabProvider, StartupTabPreloader startupTabPreloader,
+            CustomTabActivityTabProvider tabProvider,
             ReparentingTaskProvider reparentingTaskProvider,
             Lazy<CustomTabIncognitoManager> customTabIncognitoManager,
             Lazy<AsyncTabParamsManager> asyncTabParamsManager,
@@ -149,7 +141,6 @@
         mTabNavigationEventObserver = tabNavigationEventObserver;
         mActivityTabProvider = activityTabProvider;
         mTabProvider = tabProvider;
-        mStartupTabPreloader = startupTabPreloader;
         mReparentingTaskProvider = reparentingTaskProvider;
         mCustomTabIncognitoManager = customTabIncognitoManager;
         mAsyncTabParamsManager = asyncTabParamsManager;
@@ -275,51 +266,6 @@
         }
     }
 
-    /**
-     * @return A tab if mStartupTabPreloader contains a tab matching the intent.
-     */
-    private Tab maybeTakeTabFromStartupTabPreloader() {
-        // Don't overwrite any pre-existing tab.
-        if (mTabProvider.getTab() != null) return null;
-
-        if (checkIsLikelyPostNavigation()) {
-            // The navigation is likely a POST. This does not match StartupTabPreloader's GET
-            // navigation.
-            return null;
-        }
-
-        LoadUrlParams loadUrlParams = new LoadUrlParams(mIntentDataProvider.getUrlToLoad());
-        String referrer = IntentHandler.getReferrerUrlIncludingExtraHeaders(mIntent);
-        if (!TextUtils.isEmpty(referrer)) {
-            loadUrlParams.setReferrer(new Referrer(referrer, ReferrerPolicy.DEFAULT));
-        }
-
-        Tab tab = mStartupTabPreloader.takeTabIfMatchingOrDestroy(
-                loadUrlParams, TabLaunchType.FROM_EXTERNAL_APP);
-        if (tab == null) return null;
-
-        TabAssociatedApp.from(tab).setAppId(mConnection.getClientPackageNameForSession(mSession));
-        initializeTab(tab);
-        return tab;
-    }
-
-    /**
-     * Checks if the launch intent is likely a POST navigation (likely because we don't do a POST
-     * navigation if the POST target is outside of the TWA/WebAPK scope.)
-     */
-    private boolean checkIsLikelyPostNavigation() {
-        if (mIntentDataProvider.getShareData() == null) return false;
-
-        WebApkExtras webApkExtras = mIntentDataProvider.getWebApkExtras();
-        if (webApkExtras != null && webApkExtras.shareTarget != null
-                && webApkExtras.shareTarget.isShareMethodPost()) {
-            return true;
-        }
-
-        ShareTarget shareTarget = mIntentDataProvider.getShareTarget();
-        return shareTarget != null && ShareTarget.METHOD_POST.equals(shareTarget.method);
-    }
-
     // Creates the tab on native init, if it hasn't been created yet, and does all the additional
     // initialization steps necessary at this stage.
     private void finalizeCreatingTab(TabModelOrchestrator tabModelOrchestrator, TabModel tabModel) {
@@ -337,15 +283,7 @@
         }
 
         if (tab == null) {
-            // No tab was restored or created early, check if we preloaded a tab.
-            tab = maybeTakeTabFromStartupTabPreloader();
-            if (tab != null) mode = TabCreationMode.FROM_STARTUP_TAB_PRELOADER;
-        } else {
-            mStartupTabPreloader.onDestroy();
-        }
-
-        if (tab == null) {
-            // No tab was restored, preloaded or created early, creating a new tab.
+            // No tab was restored or created early, creating a new tab.
             tab = createTab();
             mode = TabCreationMode.DEFAULT;
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabFactory.java
index 37877ee..d2b1acb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabFactory.java
@@ -22,7 +22,6 @@
 import org.chromium.chrome.browser.customtabs.CustomTabDelegateFactory;
 import org.chromium.chrome.browser.customtabs.CustomTabTabPersistencePolicy;
 import org.chromium.chrome.browser.dependency_injection.ActivityScope;
-import org.chromium.chrome.browser.init.StartupTabPreloader;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabBuilder;
 import org.chromium.chrome.browser.tab.TabDelegateFactory;
@@ -56,9 +55,6 @@
     private final Supplier<TabModelSelector> mTabModelSelectorSupplier;
     private final Supplier<CompositorViewHolder> mCompositorViewHolderSupplier;
 
-    @Nullable
-    private final StartupTabPreloader mStartupTabPreloader;
-
     private final Lazy<AsyncTabParamsManager> mAsyncTabParamsManager;
 
     @Nullable
@@ -71,7 +67,6 @@
             Lazy<ActivityWindowAndroid> activityWindowAndroid,
             Lazy<CustomTabDelegateFactory> customTabDelegateFactory,
             BrowserServicesIntentDataProvider intentDataProvider,
-            @Nullable StartupTabPreloader startupTabPreloader,
             Lazy<AsyncTabParamsManager> asyncTabParamsManager, TabCreatorManager tabCreatorManager,
             Supplier<TabModelSelector> tabModelSelectorSupplier,
             Supplier<CompositorViewHolder> compositorViewHolderSupplier) {
@@ -81,7 +76,6 @@
         mActivityWindowAndroid = activityWindowAndroid;
         mCustomTabDelegateFactory = customTabDelegateFactory;
         mIntentDataProvider = intentDataProvider;
-        mStartupTabPreloader = startupTabPreloader;
         mAsyncTabParamsManager = asyncTabParamsManager;
         mTabCreatorManager = tabCreatorManager;
         mTabModelSelectorSupplier = tabModelSelectorSupplier;
@@ -131,7 +125,7 @@
     }
 
     private ChromeTabCreator createTabCreator(boolean incognito) {
-        return new ChromeTabCreator(mActivity, mActivityWindowAndroid.get(), mStartupTabPreloader,
+        return new ChromeTabCreator(mActivity, mActivityWindowAndroid.get(),
                 mCustomTabDelegateFactory::get, incognito, null,
                 AsyncTabParamsManagerSingleton.getInstance(), mTabModelSelectorSupplier,
                 mCompositorViewHolderSupplier);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/DefaultCustomTabIntentHandlingStrategy.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/DefaultCustomTabIntentHandlingStrategy.java
index ce3de2fa..5036a5d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/DefaultCustomTabIntentHandlingStrategy.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/DefaultCustomTabIntentHandlingStrategy.java
@@ -50,8 +50,7 @@
     public void handleInitialIntent(BrowserServicesIntentDataProvider intentDataProvider) {
         @TabCreationMode
         int initialTabCreationMode = mTabProvider.getInitialTabCreationMode();
-        if (initialTabCreationMode == TabCreationMode.HIDDEN
-                || initialTabCreationMode == TabCreationMode.FROM_STARTUP_TAB_PRELOADER) {
+        if (initialTabCreationMode == TabCreationMode.HIDDEN) {
             handleInitialLoadForHiddenTab(initialTabCreationMode, intentDataProvider);
         } else {
             LoadUrlParams params = new LoadUrlParams(intentDataProvider.getUrlToLoad());
@@ -100,17 +99,11 @@
 
         // No actual load to do if the hidden tab already has the exact correct url.
         String speculatedUrl = mTabProvider.getSpeculatedUrl();
-        if (TextUtils.equals(speculatedUrl, url)
-                || initialTabCreationMode == TabCreationMode.FROM_STARTUP_TAB_PRELOADER) {
-            // In the TabCreationMode.FROM_STARTUP_TAB_PRELOADER case:
-            // - CustomActivityTabProvider#getSpeculatedUrl() is not set.
-            // - The tab creation mode is only set in CustomTabActivityTabController if the URL
-            // being loaded is the one we want.
-
+        if (TextUtils.equals(speculatedUrl, url)) {
             if (tab.isLoading()) {
                 // CustomTabObserver and CustomTabActivityNavigationObserver are attached
                 // as observers in CustomTabActivityTabController, not when the navigation is
-                // initiated in HiddenTabHolder or StartupTabPreloader.
+                // initiated in HiddenTabHolder.
                 mCustomTabObserver.get().onPageLoadStarted(tab, gurl);
                 mNavigationEventObserver.onPageLoadStarted(tab, gurl);
             }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/TabCreationMode.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/TabCreationMode.java
index bf904fe..9f94f12 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/TabCreationMode.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/TabCreationMode.java
@@ -7,7 +7,6 @@
 import androidx.annotation.IntDef;
 
 import org.chromium.chrome.browser.customtabs.CustomTabsConnection;
-import org.chromium.chrome.browser.init.StartupTabPreloader;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -16,8 +15,7 @@
  * Specifies the way the initial Tab in a Custom Tab activity was created.
  */
 @IntDef({TabCreationMode.NONE, TabCreationMode.DEFAULT, TabCreationMode.EARLY,
-        TabCreationMode.RESTORED, TabCreationMode.HIDDEN,
-        TabCreationMode.FROM_STARTUP_TAB_PRELOADER})
+        TabCreationMode.RESTORED, TabCreationMode.HIDDEN})
 @Retention(RetentionPolicy.SOURCE)
 public @interface TabCreationMode {
     /** The tab has not been created yet */
@@ -39,7 +37,4 @@
      * A hidden tab that was created preemptively via {@link CustomTabsConnection#mayLaunchUrl}.
      */
     int HIDDEN = 4;
-
-    /** Opened speculatively by the {@link StartupTabPreloader}.. */
-    int FROM_STARTUP_TAB_PRELOADER = 5;
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/BaseCustomTabActivityModule.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/BaseCustomTabActivityModule.java
index 1d48dd50..7e204ce 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/BaseCustomTabActivityModule.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/BaseCustomTabActivityModule.java
@@ -21,7 +21,6 @@
 import org.chromium.chrome.browser.customtabs.content.CustomTabIntentHandlingStrategy;
 import org.chromium.chrome.browser.customtabs.content.DefaultCustomTabIntentHandlingStrategy;
 import org.chromium.chrome.browser.flags.ActivityType;
-import org.chromium.chrome.browser.init.StartupTabPreloader;
 import org.chromium.chrome.browser.tabmodel.IncognitoTabHostRegistry;
 import org.chromium.chrome.browser.theme.TopUiThemeColorProvider;
 import org.chromium.chrome.browser.webapps.WebApkPostShareTargetNavigator;
@@ -37,7 +36,6 @@
 @Module
 public class BaseCustomTabActivityModule {
     private final BrowserServicesIntentDataProvider mIntentDataProvider;
-    private final StartupTabPreloader mStartupTabPreloader;
     private final @ActivityType int mActivityType;
     private final CustomTabNightModeStateController mNightModeController;
     private final IntentIgnoringCriterion mIntentIgnoringCriterion;
@@ -46,13 +44,11 @@
             .DefaultBrowserProvider mDefaultBrowserProvider;
 
     public BaseCustomTabActivityModule(BrowserServicesIntentDataProvider intentDataProvider,
-            StartupTabPreloader startupTabPreloader,
             CustomTabNightModeStateController nightModeController,
             IntentIgnoringCriterion intentIgnoringCriterion,
             TopUiThemeColorProvider topUiThemeColorProvider,
             CustomTabActivityNavigationController.DefaultBrowserProvider defaultBrowserProvider) {
         mIntentDataProvider = intentDataProvider;
-        mStartupTabPreloader = startupTabPreloader;
         mActivityType = intentDataProvider.getActivityType();
         mNightModeController = nightModeController;
         mIntentIgnoringCriterion = intentIgnoringCriterion;
@@ -76,11 +72,6 @@
     }
 
     @Provides
-    public StartupTabPreloader provideStartupTabPreloader() {
-        return mStartupTabPreloader;
-    }
-
-    @Provides
     public Verifier provideVerifier(Lazy<WebApkVerifier> webApkVerifier,
             Lazy<AddToHomescreenVerifier> addToHomescreenVerifier, Lazy<TwaVerifier> twaVerifier,
             Lazy<EmptyVerifier> emptyVerifier) {
@@ -142,7 +133,6 @@
 
     public interface Factory {
         BaseCustomTabActivityModule create(BrowserServicesIntentDataProvider intentDataProvider,
-                StartupTabPreloader startupTabPreloader,
                 CustomTabNightModeStateController nightModeController,
                 IntentIgnoringCriterion intentIgnoringCriterion,
                 TopUiThemeColorProvider topUiThemeColorProvider,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/StartupTabPreloader.java b/chrome/android/java/src/org/chromium/chrome/browser/init/StartupTabPreloader.java
deleted file mode 100644
index 6dccc7e..0000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/init/StartupTabPreloader.java
+++ /dev/null
@@ -1,492 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// 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.init;
-
-import android.content.Intent;
-import android.os.SystemClock;
-import android.text.TextUtils;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.IntentUtils;
-import org.chromium.base.TraceEvent;
-import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.ChromeTabbedActivity;
-import org.chromium.chrome.browser.IntentHandler;
-import org.chromium.chrome.browser.WebContentsFactory;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
-import org.chromium.chrome.browser.lifecycle.DestroyObserver;
-import org.chromium.chrome.browser.metrics.ActivityTabStartupMetricsTracker;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.profiles.ProfileManager;
-import org.chromium.chrome.browser.tab.EmptyTabObserver;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.browser.tab.TabBuilder;
-import org.chromium.chrome.browser.tab.TabLaunchType;
-import org.chromium.chrome.browser.tabmodel.ChromeTabCreator;
-import org.chromium.chrome.browser.tabmodel.TabCreator;
-import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
-import org.chromium.components.url_formatter.UrlFormatter;
-import org.chromium.content_public.browser.LoadUrlParams;
-import org.chromium.content_public.browser.WebContents;
-import org.chromium.content_public.common.Referrer;
-import org.chromium.network.mojom.ReferrerPolicy;
-import org.chromium.ui.base.WindowAndroid;
-import org.chromium.url.GURL;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * This class attempts to preload the tab if the url is known from the intent when the profile
- * is created. This is done to improve startup latency.
- */
-public class StartupTabPreloader implements ProfileManager.Observer, DestroyObserver,
-                                            ActivityTabStartupMetricsTracker.Observer {
-    public static final String EXTRA_DISABLE_STARTUP_TAB_PRELOADER =
-            "org.chromium.chrome.browser.init.DISABLE_STARTUP_TAB_PRELOADER";
-    private static boolean sFailNextTabMatchForTesting;
-
-    // These values are persisted in histograms. Please do not renumber. Append only.
-    @VisibleForTesting
-    @IntDef({LoadDecisionReason.DISABLED_BY_INTENT, LoadDecisionReason.INCOGNITO,
-            LoadDecisionReason.INTENT_IGNORED, LoadDecisionReason.NO_URL,
-            LoadDecisionReason.NO_TAB_CREATOR, LoadDecisionReason.WRONG_TAB_CREATOR,
-            LoadDecisionReason.DISABLED_BY_FEATURE, LoadDecisionReason.ALL_SATISFIED})
-    @Retention(RetentionPolicy.SOURCE)
-    @interface LoadDecisionReason {
-        int DISABLED_BY_INTENT = 0;
-        int INCOGNITO = 1;
-        int INTENT_IGNORED = 2;
-        int NO_URL = 3;
-        int NO_TAB_CREATOR = 4;
-        int WRONG_TAB_CREATOR = 5;
-        int DISABLED_BY_FEATURE = 6;
-        int ALL_SATISFIED = 7;
-
-        int NUM_ENTRIES = 8;
-    }
-
-    private final Supplier<Intent> mIntentSupplier;
-    private final ActivityLifecycleDispatcher mActivityLifecycleDispatcher;
-    private final WindowAndroid mWindowAndroid;
-    private final TabCreatorManager mTabCreatorManager;
-    private final IntentHandler mIntentHandler;
-    private LoadUrlParams mLoadUrlParams;
-    private Tab mTab;
-    private StartupTabObserver mObserver;
-    private ActivityTabStartupMetricsTracker mStartupMetricsTracker;
-
-    // The time at which the tab preload decision was made. Recorded only for non-incognito
-    // startups.
-    private long mLoadDecisionMs;
-    // Records whether a preload was triggered.
-    boolean mTriggerPreload;
-    // Records the reason for the last preload decision.
-    @LoadDecisionReason
-    int mLoadDecisionReason;
-    // Records whether a preloaded tab matched.
-    boolean mTabMatches;
-    // Records whether we have already recorded the histogram for the duration between the load
-    // decision and the match decision; this histogram should be recorded only on the first match
-    // decision.
-    private boolean mRecordedLoadDecisionToMatchDecisionHistogram;
-
-    // Whether a tab preload was prevented only by the ElideTabPreloadAtStartup feature.
-    private boolean mPreloadPreventedOnlyByFeature;
-    // The params that would have been used for the preload if not prevented by the feature.
-    // NOTE: We explicitly track only the params that are necessary for comparison of tab matching
-    // to avoid calling IntentHandler#createLoadUrlParamsForIntent(). The latter is undesirable
-    // because it is destructive to the intent metadata, which is problematic in the case where the
-    // LoadUrlParams are not intended for usage (as they're not here).
-    private String mUrlForPreloadPreventedOnlyByFeature;
-    private String mReferrerForPreloadPreventedOnlyByFeature;
-    // Whether the tab preload that was prevented only by the feature would have matched.
-    private boolean mPreloadPreventedOnlyByFeatureWouldHaveMatched;
-
-    // The time at which the first navigation start occurred.
-    private long mFirstNavigationStartMs;
-
-    public static void failNextTabMatchForTesting() {
-        sFailNextTabMatchForTesting = true;
-    }
-
-    public StartupTabPreloader(Supplier<Intent> intentSupplier,
-            ActivityLifecycleDispatcher activityLifecycleDispatcher, WindowAndroid windowAndroid,
-            TabCreatorManager tabCreatorManager, IntentHandler intentHandler,
-            ActivityTabStartupMetricsTracker startupMetricsTracker) {
-        mIntentSupplier = intentSupplier;
-        mActivityLifecycleDispatcher = activityLifecycleDispatcher;
-        mWindowAndroid = windowAndroid;
-        mTabCreatorManager = tabCreatorManager;
-        mIntentHandler = intentHandler;
-        mStartupMetricsTracker = startupMetricsTracker;
-
-        mActivityLifecycleDispatcher.register(this);
-        ProfileManager.addObserver(this);
-        ActivityTabStartupMetricsTracker.addObserver(this);
-    }
-
-    // Returns true if a startup tab preload either (a) was triggered or (b) was prevented
-    // from triggering only by the ElideTabPreloadAtStartup Feature.
-    private boolean preloadWasViable() {
-        return mTriggerPreload || mPreloadPreventedOnlyByFeature;
-    }
-
-    // Returns true if a match of a preloaded tab either (a) occurred or (b) was prevented from
-    // occurring only by the ElideTabPreloadAtStartup Feature.
-    private boolean tabMatchWasViable() {
-        return mTabMatches || mPreloadPreventedOnlyByFeatureWouldHaveMatched;
-    }
-
-    @Override
-    public void onDestroy() {
-        if (mTab != null) mTab.destroy();
-        mTab = null;
-
-        ProfileManager.removeObserver(this);
-        ActivityTabStartupMetricsTracker.removeObserver(this);
-        mActivityLifecycleDispatcher.unregister(this);
-    }
-
-    @Override
-    public void onFirstNavigationStart() {
-        mFirstNavigationStartMs = SystemClock.uptimeMillis();
-    }
-
-    @Override
-    public void onFirstVisibleContent() {
-        recordDurationFromLoadDecisionIntoPostTabMatchHistogram(
-                "Android.StartupTabPreloader.LoadDecisionToFirstVisibleContent");
-    }
-
-    @Override
-    public void onFirstNavigationCommit() {
-        recordDurationFromLoadDecisionIntoPostTabMatchHistogram(
-                "Android.StartupTabPreloader.LoadDecisionToFirstNavigationCommit");
-
-        // We record the metric for navigation start here as well, as we want that metric to be
-        // recorded only for navigations that result in the first navigation commit startup metric
-        // being recorded.
-        assert mFirstNavigationStartMs > 0;
-        recordDurationFromLoadDecisionToEventTimeIntoPreTabMatchHistogram(
-                "Android.StartupTabPreloader.LoadDecisionToFirstNavigationStart",
-                mFirstNavigationStartMs);
-    }
-
-    @Override
-    public void onFirstContentfulPaint() {
-        recordDurationFromLoadDecisionIntoPostTabMatchHistogram(
-                "Android.StartupTabPreloader.LoadDecisionToFirstContentfulPaint");
-    }
-
-    // Records the duration from the load decision to the current time into |histogram| (suffixed
-    // by the state of the tab preload decision). To be used when the current time is before the
-    // tab match decision has occurred.
-    private void recordDurationFromLoadDecisionIntoPreTabMatchHistogram(String histogram) {
-        recordDurationFromLoadDecisionToEventTimeIntoPreTabMatchHistogram(
-                histogram, SystemClock.uptimeMillis());
-    }
-
-    // Records the duration from the load decision to |eventTimeMs| into |histogram| (suffixed
-    // by the state of the tab preload decision). To be used when the corresponding event occurred
-    // before the tab match decision has occurred.
-    private void recordDurationFromLoadDecisionToEventTimeIntoPreTabMatchHistogram(
-            String histogram, long eventTimeMs) {
-        if (mLoadDecisionMs == 0 || eventTimeMs == 0) return;
-
-        long triggerpointToEventTimeMs = eventTimeMs - mLoadDecisionMs;
-
-        String suffix = preloadWasViable() ? ".Load" : ".NoLoad";
-        RecordHistogram.recordMediumTimesHistogram(histogram + suffix, triggerpointToEventTimeMs);
-    }
-
-    // Records the duration from the load decision to the current time into |histogram| (suffixed
-    // by the state of the tab preload and match decisions). To be used when the tab match decision
-    // may have already occurred at the present time.
-    private void recordDurationFromLoadDecisionIntoPostTabMatchHistogram(String histogram) {
-        if (mLoadDecisionMs == 0) return;
-
-        long currentTimeMs = SystemClock.uptimeMillis();
-        long triggerpointToCurrentTimeMs = currentTimeMs - mLoadDecisionMs;
-
-        String suffix = ".NoLoad";
-        if (preloadWasViable()) {
-            // Check whether the tab match decision has yet occurred. It is still pending if (1) the
-            // preloaded tab is non-null, or (2) in the case where preloading is disabled by
-            // feature, the stored state used to calculate whether the preload would have matched is
-            // non-null.
-            boolean tabMatchStillPending =
-                    mTab != null || mUrlForPreloadPreventedOnlyByFeature != null;
-            if (tabMatchStillPending) {
-                suffix = ".LoadPreMatch";
-            } else if (tabMatchWasViable()) {
-                suffix = ".LoadAndMatch";
-            } else {
-                suffix = ".LoadAndMismatch";
-            }
-        }
-
-        RecordHistogram.recordMediumTimesHistogram(histogram + suffix, triggerpointToCurrentTimeMs);
-    }
-
-    // Returns whether the state specified for the tab preload and the actual load match.
-    private boolean doesPreloadStateMatch(@TabLaunchType int preconnectLaunchType,
-            @TabLaunchType int loadLaunchType, LoadUrlParams preconnectParams,
-            LoadUrlParams loadParams) {
-        boolean tabMatch = preconnectLaunchType == loadLaunchType
-                && doLoadUrlParamsMatchForWarmupManagerNavigation(preconnectParams, loadParams)
-                && !sFailNextTabMatchForTesting;
-        sFailNextTabMatchForTesting = false;
-
-        return tabMatch;
-    }
-
-    /**
-     * Returns the Tab if loadUrlParams and type match, otherwise the Tab is discarded.
-     *
-     * @param loadUrlParams The actual parameters of the url load.  @param type The actual launch
-     * type type.  @return The results of maybeNavigate() if they match loadUrlParams and type or
-     * null otherwise.
-     */
-    public Tab takeTabIfMatchingOrDestroy(LoadUrlParams loadUrlParams, @TabLaunchType int type) {
-        if (!mRecordedLoadDecisionToMatchDecisionHistogram
-                && mStartupMetricsTracker.isTrackingStartupMetrics()) {
-            // NOTE: This histogram is segmented only by state of the load decision as it covers the
-            // duration from the load decision *up to* the tab match decision. Additionally, note
-            // that we record the metric only when tracking startup metrics to ensure that the
-            // latencies of this metric are comparable to those ones.
-            recordDurationFromLoadDecisionIntoPreTabMatchHistogram(
-                    "Android.StartupTabPreloader.LoadDecisionToMatchDecision");
-            mRecordedLoadDecisionToMatchDecisionHistogram = true;
-
-            // Similarly, we record this metric only now to avoid recording cases where startup
-            // metrics are tracked at the time of the load decision but have been cancelled by the
-            // time of the tab match decision (e.g., due to a decision being made to show an
-            // overview).
-            RecordHistogram.recordMediumTimesHistogram(
-                    "Android.StartupTabPreloader.ActivityStartToLoadDecision",
-                    mLoadDecisionMs - mStartupMetricsTracker.getActivityStartTimeMs());
-        }
-
-        if (mTab == null) {
-            if (mUrlForPreloadPreventedOnlyByFeature != null) {
-                // Construct a LoadUrlParams object for the preload that would have occurred.
-                LoadUrlParams loadUrlParamsForPreloadPreventedOnlyByFeature =
-                        new LoadUrlParams(mUrlForPreloadPreventedOnlyByFeature);
-                if (mReferrerForPreloadPreventedOnlyByFeature != null) {
-                    loadUrlParamsForPreloadPreventedOnlyByFeature.setReferrer(new Referrer(
-                            mReferrerForPreloadPreventedOnlyByFeature, ReferrerPolicy.DEFAULT));
-                }
-
-                // Calculate whether a tab match *would have* occurred if the preload wasn't
-                // prevented by the feature. This is used later for metrics tracking.
-                mPreloadPreventedOnlyByFeatureWouldHaveMatched =
-                        doesPreloadStateMatch(TabLaunchType.FROM_EXTERNAL_APP, type,
-                                loadUrlParamsForPreloadPreventedOnlyByFeature, loadUrlParams);
-                mUrlForPreloadPreventedOnlyByFeature = null;
-                mReferrerForPreloadPreventedOnlyByFeature = null;
-            }
-
-            return null;
-        }
-
-        mTabMatches =
-                doesPreloadStateMatch(mTab.getLaunchType(), type, mLoadUrlParams, loadUrlParams);
-
-        RecordHistogram.recordBooleanHistogram(
-                "Startup.Android.StartupTabPreloader.TabTaken", mTabMatches);
-
-        if (!mTabMatches) {
-            mStartupMetricsTracker.onStartupTabPreloadDropped();
-
-            mTab.destroy();
-            mTab = null;
-            mLoadUrlParams = null;
-            return null;
-        }
-
-        Tab tab = mTab;
-        mTab = null;
-        mLoadUrlParams = null;
-        tab.removeObserver(mObserver);
-        return tab;
-    }
-
-    @VisibleForTesting
-    static boolean doLoadUrlParamsMatchForWarmupManagerNavigation(
-            LoadUrlParams preconnectParams, LoadUrlParams loadParams) {
-        if (!TextUtils.equals(preconnectParams.getUrl(), loadParams.getUrl())) return false;
-
-        String preconnectReferrer = preconnectParams.getReferrer() != null
-                ? preconnectParams.getReferrer().getUrl()
-                : null;
-        String loadParamsReferrer =
-                loadParams.getReferrer() != null ? loadParams.getReferrer().getUrl() : null;
-
-        return TextUtils.equals(preconnectReferrer, loadParamsReferrer);
-    }
-
-    /**
-     * Called by the ProfileManager when a profile has been created. This occurs during startup
-     * and it's the earliest point at which we can create and load a tab. If the url can be
-     * determined from the intent, then a tab will be loaded and potentially adopted by
-     * {@link ChromeTabCreator}.
-     */
-    @Override
-    public void onProfileAdded(Profile profile) {
-        try (TraceEvent e = TraceEvent.scoped("StartupTabPreloader.onProfileAdded")) {
-            // We only care about the first non-incognito profile that's created during startup.
-            if (profile.isOffTheRecord()) return;
-
-            ProfileManager.removeObserver(this);
-            mTriggerPreload = shouldLoadTab();
-            mLoadDecisionMs = SystemClock.uptimeMillis();
-
-            if (mTriggerPreload) loadTab();
-            RecordHistogram.recordBooleanHistogram(
-                    "Startup.Android.StartupTabPreloader.TabLoaded", mTriggerPreload);
-            RecordHistogram.recordEnumeratedHistogram(
-                    "Startup.Android.StartupTabPreloader.LoadDecisionReason",
-                    getLoadDecisionReason(), LoadDecisionReason.NUM_ENTRIES);
-        }
-    }
-
-    @Override
-    public void onProfileDestroyed(Profile profile) {}
-
-    /**
-     * @returns The reason for the decision returned by the most recent invocation of
-     * shouldLoadTab().
-     */
-    @VisibleForTesting
-    @LoadDecisionReason
-    int getLoadDecisionReason() {
-        return mLoadDecisionReason;
-    }
-
-    /**
-     * @returns True if based on the intent we should load the tab, returns false otherwise.
-     */
-    @VisibleForTesting
-    boolean shouldLoadTab() {
-        // If mTab isn't null we've been called before and there is nothing to do.
-        if (mTab != null) return false;
-
-        mPreloadPreventedOnlyByFeature = false;
-
-        Intent intent = mIntentSupplier.get();
-        if (IntentUtils.safeGetBooleanExtra(intent, EXTRA_DISABLE_STARTUP_TAB_PRELOADER, false)) {
-            mLoadDecisionReason = LoadDecisionReason.DISABLED_BY_INTENT;
-            return false;
-        }
-
-        // We don't support incognito tabs. NOTE: This check is before the check for whether the
-        // intent should be ignored to allow capturing the metric for this case separately, as
-        // IntentHandler also disallows incognito tab intents not sent by Chrome (i.e.,
-        // IntentHandler#shouldIgnoreIntent() returns true in this case).
-        boolean incognito = IntentUtils.safeGetBooleanExtra(
-                intent, IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, false);
-        if (incognito) {
-            mLoadDecisionReason = LoadDecisionReason.INCOGNITO;
-            return false;
-        }
-        if (mIntentHandler.shouldIgnoreIntent(intent, /*startedActivity=*/true)) {
-            mLoadDecisionReason = LoadDecisionReason.INTENT_IGNORED;
-            return false;
-        }
-        if (getUrlFromIntent(intent) == null) {
-            mLoadDecisionReason = LoadDecisionReason.NO_URL;
-            return false;
-        }
-
-        // The TabCreatorManager throws an IllegalStateException if it is not ready to provide a
-        // TabCreator.
-        TabCreator tabCreator;
-        try {
-            tabCreator = mTabCreatorManager.getTabCreator(incognito);
-        } catch (IllegalStateException e) {
-            mLoadDecisionReason = LoadDecisionReason.NO_TAB_CREATOR;
-            return false;
-        }
-
-        // We want to get the TabDelegateFactory but only ChromeTabCreator has one.
-        if (!(tabCreator instanceof ChromeTabCreator)) {
-            mLoadDecisionReason = LoadDecisionReason.WRONG_TAB_CREATOR;
-            return false;
-        }
-
-        if (ChromeFeatureList.isEnabled(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)) {
-            mPreloadPreventedOnlyByFeature = true;
-            mLoadDecisionReason = LoadDecisionReason.DISABLED_BY_FEATURE;
-            GURL url = UrlFormatter.fixupUrl(getUrlFromIntent(intent));
-
-            // NOTE: We avoid calling IntentHandler.createLoadUrlParamsForIntent() here as that
-            // call is destructive to the metadata associated with the intent. Instead, we save the
-            // parameters of the load that are used in the check for matching later. This is
-            // fragile, but this state is used only for evaluating the effectiveness of startup tab
-            // preloading.
-            mUrlForPreloadPreventedOnlyByFeature = url.getSpec();
-            mReferrerForPreloadPreventedOnlyByFeature =
-                    IntentHandler.getReferrerUrlIncludingExtraHeaders(intent);
-
-            return false;
-        }
-
-        mLoadDecisionReason = LoadDecisionReason.ALL_SATISFIED;
-        return true;
-    }
-
-    private void loadTab() {
-        Intent intent = mIntentSupplier.get();
-        GURL url = UrlFormatter.fixupUrl(getUrlFromIntent(intent));
-
-        ChromeTabCreator chromeTabCreator =
-                (ChromeTabCreator) mTabCreatorManager.getTabCreator(false);
-        WebContents webContents =
-                WebContentsFactory.createWebContents(Profile.getLastUsedRegularProfile(), false);
-
-        mLoadUrlParams = mIntentHandler.createLoadUrlParamsForIntent(url.getSpec(), intent);
-
-        // Create a detached tab, but don't add it to the tab model yet. We'll do that
-        // later if the loadUrlParams etc... match.
-        mTab = TabBuilder.createLiveTab(false)
-                       .setIncognito(false)
-                       .setLaunchType(TabLaunchType.FROM_EXTERNAL_APP)
-                       .setWindow(mWindowAndroid)
-                       .setWebContents(webContents)
-                       .setDelegateFactory(chromeTabCreator.createDefaultTabDelegateFactory())
-                       .build();
-
-        mObserver = new StartupTabObserver();
-        mTab.addObserver(mObserver);
-        mTab.loadUrl(mLoadUrlParams);
-    }
-
-    private static String getUrlFromIntent(Intent intent) {
-        String action = intent.getAction();
-        if (Intent.ACTION_VIEW.equals(action) || Intent.ACTION_MAIN.equals(action)
-                || (action == null
-                        && ChromeTabbedActivity.MAIN_LAUNCHER_ACTIVITY_NAME.equals(
-                                intent.getComponent().getClassName()))) {
-            // TODO(alexclarke): For ACTION_MAIN maybe refactor TabPersistentStore so we can
-            // instantiate (a subset of that) here to extract the URL if it's not set in the
-            // intent.
-            return IntentHandler.getUrlFromIntent(intent);
-        } else {
-            return null;
-        }
-    }
-
-    private class StartupTabObserver extends EmptyTabObserver {
-        @Override
-        public void onCrash(Tab tab) {
-            onDestroy();
-        }
-    }
-}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java
index e4a7b08..e967362 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java
@@ -108,13 +108,6 @@
 
             recordFirstContentfulPaint(navigationStartMicros / 1000 + firstContentfulPaintMs);
         }
-
-        void resetMetricsRecordingStateForInitialNavigation() {
-            // NOTE: |mInvokedOnFirstNavigationStart| is intentionally not reset to avoid duplicate
-            // observer notifications.
-            mNavigationId = NO_NAVIGATION_ID;
-            mShouldRecordHistograms = false;
-        }
     };
 
     private final long mActivityStartTimeMs;
@@ -250,21 +243,6 @@
     }
 
     /**
-     * Invoked when a tab preloaded at startup is dropped rather than taken, meaning that a new tab
-     * will need to be created to do the initial navigation. Resets state related to observation of
-     * the initial navigation to ensure that loading startup metrics are properly recorded in this
-     * case. Note that it is not necessary to reset the state of |mTabModelSelectorTabObserver| in
-     * this case, as that observer tracks state starting only from the addition of a tab to the tab
-     * model, which by definition has not yet occurred at this point.
-     */
-    public void onStartupTabPreloadDropped() {
-        // Note that observers are not created in all contexts (e.g., CCT).
-        if (mPageLoadMetricsObserver == null) return;
-
-        mPageLoadMetricsObserver.resetMetricsRecordingStateForInitialNavigation();
-    }
-
-    /**
      * Marks that startup metrics should be tracked with the |histogramSuffix|.
      * Must only be called on the UI thread.
      */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java
index 82a82811..7c11415 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java
@@ -20,7 +20,6 @@
 import org.chromium.chrome.browser.app.tab_activity_glue.ReparentingDelegateFactory;
 import org.chromium.chrome.browser.app.tab_activity_glue.ReparentingTask;
 import org.chromium.chrome.browser.compositor.CompositorViewHolder;
-import org.chromium.chrome.browser.init.StartupTabPreloader;
 import org.chromium.chrome.browser.ntp.NewTabPageLaunchOrigin;
 import org.chromium.chrome.browser.ntp.NewTabPageUtils;
 import org.chromium.chrome.browser.tab.RedirectHandlerTabHelper;
@@ -71,7 +70,6 @@
     private static final String TAG = "ChromeTabCreator";
 
     private final Activity mActivity;
-    private final StartupTabPreloader mStartupTabPreloader;
     private final boolean mIncognito;
 
     private WindowAndroid mNativeWindow;
@@ -85,13 +83,11 @@
     private final Supplier<CompositorViewHolder> mCompositorViewHolderSupplier;
 
     public ChromeTabCreator(Activity activity, WindowAndroid nativeWindow,
-            StartupTabPreloader startupTabPreloader,
             Supplier<TabDelegateFactory> tabDelegateFactory, boolean incognito,
             OverviewNTPCreator overviewNTPCreator, AsyncTabParamsManager asyncTabParamsManager,
             Supplier<TabModelSelector> tabModelSelectorSupplier,
             Supplier<CompositorViewHolder> compositorViewHolderSupplier) {
         mActivity = activity;
-        mStartupTabPreloader = startupTabPreloader;
         mNativeWindow = nativeWindow;
         mTabDelegateFactorySupplier = tabDelegateFactory;
         mIncognito = incognito;
@@ -222,31 +218,24 @@
                               .build();
                 creationState = TabCreationState.FROZEN_FOR_LAZY_LOAD;
             } else {
-                tab = (mStartupTabPreloader != null)
-                        ? mStartupTabPreloader.takeTabIfMatchingOrDestroy(loadUrlParams, type)
-                        : null;
-
-                if (tab == null) {
-                    TraceEvent.begin("ChromeTabCreator.loadUrl");
-                    Callback<Tab> action = null;
-                    if (mOverviewNTPCreator != null) {
-                        action = (newTab) -> {
-                            mOverviewNTPCreator.preTabInitialization(
-                                    newTab, loadUrlParams.getUrl());
-                        };
-                    }
-                    tab = TabBuilder.createLiveTab(!openInForeground)
-                                  .setParent(parent)
-                                  .setIncognito(mIncognito)
-                                  .setWindow(mNativeWindow)
-                                  .setLaunchType(type)
-                                  .setDelegateFactory(delegateFactory)
-                                  .setInitiallyHidden(!openInForeground)
-                                  .setPreInitializeAction(action)
-                                  .build();
-                    tab.loadUrl(loadUrlParams);
-                    TraceEvent.end("ChromeTabCreator.loadUrl");
+                TraceEvent.begin("ChromeTabCreator.loadUrl");
+                Callback<Tab> action = null;
+                if (mOverviewNTPCreator != null) {
+                    action = (newTab) -> {
+                        mOverviewNTPCreator.preTabInitialization(newTab, loadUrlParams.getUrl());
+                    };
                 }
+                tab = TabBuilder.createLiveTab(!openInForeground)
+                              .setParent(parent)
+                              .setIncognito(mIncognito)
+                              .setWindow(mNativeWindow)
+                              .setLaunchType(type)
+                              .setDelegateFactory(delegateFactory)
+                              .setInitiallyHidden(!openInForeground)
+                              .setPreInitializeAction(action)
+                              .build();
+                tab.loadUrl(loadUrlParams);
+                TraceEvent.end("ChromeTabCreator.loadUrl");
             }
             // When tab reparenting the |intent| is the reparenting intent, not the intent that
             // created the tab.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityAppMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityAppMenuTest.java
index 3ea998a..d5b9231 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityAppMenuTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityAppMenuTest.java
@@ -48,7 +48,6 @@
 import org.chromium.chrome.browser.dependency_injection.ModuleOverridesRule;
 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
 import org.chromium.chrome.browser.firstrun.FirstRunStatus;
-import org.chromium.chrome.browser.init.StartupTabPreloader;
 import org.chromium.chrome.browser.test.ScreenShooter;
 import org.chromium.chrome.browser.theme.TopUiThemeColorProvider;
 import org.chromium.chrome.browser.ui.appmenu.AppMenuCoordinator;
@@ -76,17 +75,16 @@
 
     public CustomTabActivityTestRule mCustomTabActivityTestRule = new CustomTabActivityTestRule();
 
-    private final TestRule mModuleOverridesRule = new ModuleOverridesRule().setOverride(
-            BaseCustomTabActivityModule.Factory.class,
-            (BrowserServicesIntentDataProvider intentDataProvider,
-                    StartupTabPreloader startupTabPreloader,
-                    CustomTabNightModeStateController nightModeController,
-                    CustomTabIntentHandler.IntentIgnoringCriterion intentIgnoringCriterion,
-                    TopUiThemeColorProvider topUiThemeColorProvider,
-                    DefaultBrowserProviderImpl customTabDefaultBrowserProvider)
-                    -> new BaseCustomTabActivityModule(intentDataProvider, startupTabPreloader,
-                            nightModeController, intentIgnoringCriterion, topUiThemeColorProvider,
-                            new FakeDefaultBrowserProviderImpl()));
+    private final TestRule mModuleOverridesRule =
+            new ModuleOverridesRule().setOverride(BaseCustomTabActivityModule.Factory.class,
+                    (BrowserServicesIntentDataProvider intentDataProvider,
+                            CustomTabNightModeStateController nightModeController,
+                            CustomTabIntentHandler.IntentIgnoringCriterion intentIgnoringCriterion,
+                            TopUiThemeColorProvider topUiThemeColorProvider,
+                            DefaultBrowserProviderImpl customTabDefaultBrowserProvider)
+                            -> new BaseCustomTabActivityModule(intentDataProvider,
+                                    nightModeController, intentIgnoringCriterion,
+                                    topUiThemeColorProvider, new FakeDefaultBrowserProviderImpl()));
 
     @Rule
     public RuleChain mRuleChain = RuleChain.emptyRuleChain()
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
index 9f3468f..0b3293b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -862,10 +862,8 @@
      */
     @Test
     @SmallTest
-    @EnableFeatures({ChromeFeatureList.ELIDE_PRIORITIZATION_OF_PRE_NATIVE_BOOTSTRAP_TASKS,
-            ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP})
-    public void
-    testNavigationHistogramsRecorded() throws Exception {
+    @EnableFeatures({ChromeFeatureList.ELIDE_PRIORITIZATION_OF_PRE_NATIVE_BOOTSTRAP_TASKS})
+    public void testNavigationHistogramsRecorded() throws Exception {
         String startHistogramPrefix = "CustomTabs.IntentToFirstNavigationStartTime";
         String commitHistogramPrefix = "CustomTabs.IntentToFirstCommitNavigationTime3";
         assertSuffixedHistogramTotalCount(0, startHistogramPrefix);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TabReparentingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TabReparentingTest.java
index 60f6fef3..0f0cc6a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TabReparentingTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TabReparentingTest.java
@@ -44,7 +44,6 @@
 import org.chromium.chrome.browser.firstrun.FirstRunStatus;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.infobar.InfoBarContainer;
-import org.chromium.chrome.browser.init.StartupTabPreloader;
 import org.chromium.chrome.browser.tab.EmptyTabObserver;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabHidingType;
@@ -76,17 +75,16 @@
     @Rule
     public CustomTabActivityTestRule mCustomTabActivityTestRule = new CustomTabActivityTestRule();
 
-    private final TestRule mModuleOverridesRule = new ModuleOverridesRule().setOverride(
-            BaseCustomTabActivityModule.Factory.class,
-            (BrowserServicesIntentDataProvider intentDataProvider,
-                    StartupTabPreloader startupTabPreloader,
-                    CustomTabNightModeStateController nightModeController,
-                    CustomTabIntentHandler.IntentIgnoringCriterion intentIgnoringCriterion,
-                    TopUiThemeColorProvider topUiThemeColorProvider,
-                    DefaultBrowserProviderImpl customTabDefaultBrowserProvider)
-                    -> new BaseCustomTabActivityModule(intentDataProvider, startupTabPreloader,
-                            nightModeController, intentIgnoringCriterion, topUiThemeColorProvider,
-                            new FakeDefaultBrowserProviderImpl()));
+    private final TestRule mModuleOverridesRule =
+            new ModuleOverridesRule().setOverride(BaseCustomTabActivityModule.Factory.class,
+                    (BrowserServicesIntentDataProvider intentDataProvider,
+                            CustomTabNightModeStateController nightModeController,
+                            CustomTabIntentHandler.IntentIgnoringCriterion intentIgnoringCriterion,
+                            TopUiThemeColorProvider topUiThemeColorProvider,
+                            DefaultBrowserProviderImpl customTabDefaultBrowserProvider)
+                            -> new BaseCustomTabActivityModule(intentDataProvider,
+                                    nightModeController, intentIgnoringCriterion,
+                                    topUiThemeColorProvider, new FakeDefaultBrowserProviderImpl()));
 
     @Rule
     public RuleChain mRuleChain = RuleChain.emptyRuleChain()
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabControllerTest.java
deleted file mode 100644
index c5ff57dc..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabControllerTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// 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.customtabs.content;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-
-import android.content.Intent;
-import android.support.test.InstrumentationRegistry;
-
-import androidx.test.filters.MediumTest;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.IntentUtils;
-import org.chromium.base.test.params.ParameterAnnotations.ClassParameter;
-import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate;
-import org.chromium.base.test.params.ParameterSet;
-import org.chromium.base.test.params.ParameterizedRunner;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.UrlUtils;
-import org.chromium.chrome.browser.browserservices.intents.BrowserServicesIntentDataProvider.CustomTabsUiType;
-import org.chromium.chrome.browser.customtabs.BaseCustomTabActivity;
-import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.customtabs.CustomTabActivityTypeTestUtils;
-import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider;
-import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
-import org.chromium.chrome.browser.flags.ActivityType;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.flags.ChromeSwitches;
-import org.chromium.chrome.test.ChromeActivityTestRule;
-import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
-import org.chromium.chrome.test.util.ChromeTabUtils;
-import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.TimeoutException;
-
-/**
- * Tests for {@link CustomTabActivityTabController}.
- */
-@RunWith(ParameterizedRunner.class)
-@UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class)
-@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
-public class CustomTabActivityTabControllerTest {
-    // Do not test TWAs because {@link CustomTabActivityTypeTestUtils#launchActivity} warms up the
-    // {@link CustomTabsConnection} which bypasses {@link StartupTabPreloader}.
-    @ClassParameter
-    public static List<ParameterSet> sClassParams =
-            Arrays.asList(new ParameterSet().value(ActivityType.WEBAPP).name("Webapp"),
-                    new ParameterSet().value(ActivityType.CUSTOM_TAB).name("CustomTab"));
-
-    private @ActivityType int mActivityType;
-
-    @Rule
-    public final ChromeActivityTestRule<? extends BaseCustomTabActivity> mActivityTestRule;
-
-    public CustomTabActivityTabControllerTest(@ActivityType int activityType) {
-        mActivityType = activityType;
-        mActivityTestRule = CustomTabActivityTypeTestUtils.createActivityTestRule(activityType);
-    }
-
-    /**
-     * Test that the {@link StartupTabPreloader} tab is used by default.
-     */
-    @Test
-    @MediumTest
-    @Feature({"CustomTabs"})
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testUseStartupPreloaderTab() throws TimeoutException {
-        // TODO(https://crbug.com/1314766): Resolve the flake that occurs when running this test
-        // within the context of Custom Tabs.
-        if (mActivityType == ActivityType.CUSTOM_TAB) return;
-
-        CustomTabActivityTypeTestUtils.launchActivity(
-                mActivityType, mActivityTestRule, "about:blank");
-        CustomTabActivityTabProvider tabProvider = getActivityTabProvider();
-        assertEquals(TabCreationMode.FROM_STARTUP_TAB_PRELOADER,
-                tabProvider.getInitialTabCreationMode());
-    }
-
-    /**
-     * Test that the {@link StartupTabPreloader} tab is not used if the preloaded URL is different
-     * than
-     * {@link IntentDataProvider#getUrlToLoad()}.
-     */
-    @Test
-    @MediumTest
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testDontUseStartupPreloaderMediaViewerUrl() throws TimeoutException {
-        if (mActivityType != ActivityType.CUSTOM_TAB) return;
-
-        String mediaViewerUrl = UrlUtils.getTestFileUrl("google.png");
-        Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(
-                InstrumentationRegistry.getTargetContext(), "about:blank");
-        intent.putExtra(CustomTabIntentDataProvider.EXTRA_UI_TYPE, CustomTabsUiType.MEDIA_VIEWER);
-        intent.putExtra(CustomTabIntentDataProvider.EXTRA_MEDIA_VIEWER_URL, mediaViewerUrl);
-        IntentUtils.addTrustedIntentExtras(intent);
-        ((CustomTabActivityTestRule) mActivityTestRule).startCustomTabActivityWithIntent(intent);
-
-        CustomTabActivityTabProvider tabProvider = getActivityTabProvider();
-        assertEquals(
-                mediaViewerUrl, ChromeTabUtils.getUrlOnUiThread(tabProvider.getTab()).getSpec());
-        assertNotEquals(TabCreationMode.FROM_STARTUP_TAB_PRELOADER,
-                tabProvider.getInitialTabCreationMode());
-    }
-
-    private CustomTabActivityTabProvider getActivityTabProvider() {
-        return mActivityTestRule.getActivity().getComponent().resolveTabProvider();
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderCustomTabTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderCustomTabTest.java
deleted file mode 100644
index d21da2f5..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderCustomTabTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// 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.init;
-
-import android.content.Intent;
-import android.net.Uri;
-import android.support.test.InstrumentationRegistry;
-
-import androidx.test.filters.LargeTest;
-
-import org.junit.Assert;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.DisableIf;
-import org.chromium.chrome.browser.LaunchIntentDispatcher;
-import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.flags.ChromeSwitches;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
-import org.chromium.content_public.browser.test.util.TestThreadUtils;
-import org.chromium.net.test.EmbeddedTestServerRule;
-
-/**
- * Browser tests for {@link StartupTabPreloader}.
- */
-@RunWith(ChromeJUnit4ClassRunner.class)
-@CommandLineFlags.Add(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE)
-public class StartupTabPreloaderCustomTabTest {
-    private static final String TEST_PAGE = "/chrome/test/data/android/google.html";
-    private static final String TAB_LOADED_HISTOGRAM =
-            "Startup.Android.StartupTabPreloader.TabLoaded";
-    private static final String TAB_TAKEN_HISTOGRAM =
-            "Startup.Android.StartupTabPreloader.TabTaken";
-
-    @Rule
-    public CustomTabActivityTestRule mActivityRule = new CustomTabActivityTestRule();
-
-    @Rule
-    public EmbeddedTestServerRule mServerRule = new EmbeddedTestServerRule();
-
-    @Test
-    @LargeTest
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    @DisableIf.Build(supported_abis_includes = "x86", message = "https://crbug.com/1323858")
-    @DisableIf.Build(supported_abis_includes = "x86_64", message = "https://crbug.com/1323858")
-    public void testStartupTabPreloaderWithCustomTab() throws Exception {
-        Uri uri = Uri.parse(mServerRule.getServer().getURL(TEST_PAGE));
-        Intent customTabActivityIntent = TestThreadUtils.runOnUiThreadBlockingNoException(() -> {
-            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
-            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            return LaunchIntentDispatcher.createCustomTabActivityIntent(
-                    InstrumentationRegistry.getTargetContext(), intent);
-        });
-
-        mActivityRule.startCustomTabActivityWithIntent(customTabActivityIntent);
-
-        // The StartupTabPreloader should have loaded a url.
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramValueCountForTesting(TAB_LOADED_HISTOGRAM, 1));
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramValueCountForTesting(TAB_TAKEN_HISTOGRAM, 1));
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderTest.java
deleted file mode 100644
index 7228484..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderTest.java
+++ /dev/null
@@ -1,585 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// 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.init;
-
-import android.content.Intent;
-
-import androidx.test.filters.LargeTest;
-
-import org.junit.Assert;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.CriteriaHelper;
-import org.chromium.base.test.util.DisabledTest;
-import org.chromium.chrome.browser.ChromeTabbedActivity;
-import org.chromium.chrome.browser.IntentHandler;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.flags.ChromeSwitches;
-import org.chromium.chrome.browser.metrics.UmaUtils;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
-import org.chromium.chrome.test.util.ChromeTabUtils;
-import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
-import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
-import org.chromium.content_public.browser.test.util.TestThreadUtils;
-import org.chromium.net.test.EmbeddedTestServerRule;
-
-/**
- * Browser tests for {@link StartupTabPreloader}.
- */
-@RunWith(ChromeJUnit4ClassRunner.class)
-@CommandLineFlags.Add(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE)
-public class StartupTabPreloaderTest {
-    private static final String TEST_PAGE = "/chrome/test/data/android/google.html";
-    private static final String TEST_PAGE2 = "/chrome/test/data/android/about.html";
-    private static final String TAB_LOADED_HISTOGRAM =
-            "Startup.Android.StartupTabPreloader.TabLoaded";
-    private static final String TAB_TAKEN_HISTOGRAM =
-            "Startup.Android.StartupTabPreloader.TabTaken";
-    private static final String FIRST_COMMIT_HISTOGRAM =
-            "Startup.Android.Cold.TimeToFirstNavigationCommit"
-            + ChromeTabbedActivity.STARTUP_UMA_HISTOGRAM_SUFFIX;
-    private static final String FIRST_CONTENTFUL_PAINT_HISTOGRAM =
-            "Startup.Android.Cold.TimeToFirstContentfulPaint"
-            + ChromeTabbedActivity.STARTUP_UMA_HISTOGRAM_SUFFIX;
-    private static final String FIRST_VISIBLE_CONTENT_HISTOGRAM =
-            "Startup.Android.Cold.TimeToFirstVisibleContent";
-    private static final String VISIBLE_CONTENT_HISTOGRAM =
-            "Startup.Android.Cold.TimeToVisibleContent";
-    private static final String ACTIVITY_START_TO_PRELOAD_TRIGGER =
-            "Android.StartupTabPreloader.ActivityStartToLoadDecision";
-    private static final String PRELOAD_TRIGGER_TO_MATCH_DECISION_PRELOAD =
-            "Android.StartupTabPreloader.LoadDecisionToMatchDecision.Load";
-    private static final String PRELOAD_TRIGGER_TO_MATCH_DECISION_NO_PRELOAD =
-            "Android.StartupTabPreloader.LoadDecisionToMatchDecision.NoLoad";
-    private static final String PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_START_PRELOAD =
-            "Android.StartupTabPreloader.LoadDecisionToFirstNavigationStart.Load";
-    private static final String PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_START_NO_PRELOAD =
-            "Android.StartupTabPreloader.LoadDecisionToFirstNavigationStart.NoLoad";
-    private static final String PRELOAD_TRIGGER_TO_FIRST_VISIBLE_CONTENT_PRELOAD_BEFORE_MATCH =
-            "Android.StartupTabPreloader.LoadDecisionToFirstVisibleContent.LoadPreMatch";
-    private static final String PRELOAD_TRIGGER_TO_FIRST_VISIBLE_CONTENT_PRELOAD_AND_TAKE =
-            "Android.StartupTabPreloader.LoadDecisionToFirstVisibleContent.LoadAndMatch";
-    private static final String PRELOAD_TRIGGER_TO_FIRST_VISIBLE_CONTENT_PRELOAD_AND_DROP =
-            "Android.StartupTabPreloader.LoadDecisionToFirstVisibleContent.LoadAndMismatch";
-    private static final String PRELOAD_TRIGGER_TO_FIRST_VISIBLE_CONTENT_NO_PRELOAD =
-            "Android.StartupTabPreloader.LoadDecisionToFirstVisibleContent.NoLoad";
-    private static final String PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_COMMIT_PRELOAD_BEFORE_MATCH =
-            "Android.StartupTabPreloader.LoadDecisionToFirstNavigationCommit.LoadPreMatch";
-    private static final String PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_COMMIT_PRELOAD_AND_TAKE =
-            "Android.StartupTabPreloader.LoadDecisionToFirstNavigationCommit.LoadAndMatch";
-    private static final String PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_COMMIT_PRELOAD_AND_DROP =
-            "Android.StartupTabPreloader.LoadDecisionToFirstNavigationCommit.LoadAndMismatch";
-    private static final String PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_COMMIT_NO_PRELOAD =
-            "Android.StartupTabPreloader.LoadDecisionToFirstNavigationCommit.NoLoad";
-    private static final String PRELOAD_TRIGGER_TO_FIRST_CONTENTFUL_PAINT_PRELOAD_BEFORE_MATCH =
-            "Android.StartupTabPreloader.LoadDecisionToFirstContentfulPaint.LoadPreMatch";
-    private static final String PRELOAD_TRIGGER_TO_FIRST_CONTENTFUL_PAINT_PRELOAD_AND_TAKE =
-            "Android.StartupTabPreloader.LoadDecisionToFirstContentfulPaint.LoadAndMatch";
-    private static final String PRELOAD_TRIGGER_TO_FIRST_CONTENTFUL_PAINT_PRELOAD_AND_DROP =
-            "Android.StartupTabPreloader.LoadDecisionToFirstContentfulPaint.LoadAndMismatch";
-    private static final String PRELOAD_TRIGGER_TO_FIRST_CONTENTFUL_PAINT_NO_PRELOAD =
-            "Android.StartupTabPreloader.LoadDecisionToFirstContentfulPaint.NoLoad";
-    private static final String LOAD_DECISION_REASON =
-            "Startup.Android.StartupTabPreloader.LoadDecisionReason";
-
-    // Used for verifying expected histogram counts.
-    private static final int NO_PRELOAD = 0;
-    private static final int PRELOAD = 1;
-    private static final int NO_PRELOAD_MATCH = 0;
-    private static final int PRELOAD_MATCH = 1;
-
-    @Rule
-    public ChromeTabbedActivityTestRule mActivityRule = new ChromeTabbedActivityTestRule();
-
-    @Rule
-    public EmbeddedTestServerRule mServerRule = new EmbeddedTestServerRule();
-
-    // Verifies the state of various startup metrics being recorded appropriately for the varues of
-    // |preload| and |preloadMatch| (specified by the constants above).
-    private void assertStartupMetricsRecorded(int preload, int preloadMatch) {
-        int noPreload = 1 - preload;
-        int preloadMismatch = (preload == 1 && preloadMatch == 0) ? 1 : 0;
-
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        ACTIVITY_START_TO_PRELOAD_TRIGGER));
-
-        Assert.assertEquals(preload,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_START_PRELOAD));
-        Assert.assertEquals(noPreload,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_START_NO_PRELOAD));
-
-        Assert.assertEquals(preload,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_MATCH_DECISION_PRELOAD));
-        Assert.assertEquals(noPreload,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_MATCH_DECISION_NO_PRELOAD));
-
-        Assert.assertEquals(preloadMatch,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_FIRST_VISIBLE_CONTENT_PRELOAD_AND_TAKE));
-        Assert.assertEquals(preloadMismatch,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_FIRST_VISIBLE_CONTENT_PRELOAD_AND_DROP));
-        Assert.assertEquals(noPreload,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_FIRST_VISIBLE_CONTENT_NO_PRELOAD));
-
-        Assert.assertEquals(preloadMatch,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_COMMIT_PRELOAD_AND_TAKE));
-        Assert.assertEquals(preloadMismatch,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_COMMIT_PRELOAD_AND_DROP));
-        Assert.assertEquals(noPreload,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_COMMIT_NO_PRELOAD));
-
-        Assert.assertEquals(preloadMatch,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_FIRST_CONTENTFUL_PAINT_PRELOAD_AND_TAKE));
-        Assert.assertEquals(preloadMismatch,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_FIRST_CONTENTFUL_PAINT_PRELOAD_AND_DROP));
-        Assert.assertEquals(noPreload,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_FIRST_CONTENTFUL_PAINT_NO_PRELOAD));
-
-        // This case never triggers in these tests.
-        Assert.assertEquals(0,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_FIRST_VISIBLE_CONTENT_PRELOAD_BEFORE_MATCH));
-        Assert.assertEquals(0,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_FIRST_NAVIGATION_COMMIT_PRELOAD_BEFORE_MATCH));
-        Assert.assertEquals(0,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_FIRST_CONTENTFUL_PAINT_PRELOAD_BEFORE_MATCH));
-    }
-
-    @Test
-    @LargeTest
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testStartupTabPreloaderWithViewIntent() throws Exception {
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.addCategory(Intent.CATEGORY_LAUNCHER);
-        mActivityRule.startMainActivityFromIntent(
-                intent, mServerRule.getServer().getURL(TEST_PAGE));
-
-        // The StartupTabPreloader should have loaded a url.
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramValueCountForTesting(TAB_LOADED_HISTOGRAM, 1));
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramValueCountForTesting(TAB_TAKEN_HISTOGRAM, 1));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramValueCountForTesting(LOAD_DECISION_REASON,
-                        StartupTabPreloader.LoadDecisionReason.ALL_SATISFIED));
-    }
-
-    @Test
-    @LargeTest
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    @DisabledTest(message = "https://crbug.com/1271158")
-    public void testStartupTabPreloaderStartupLoadingMetricsRecordedWhenTabTaken()
-            throws Exception {
-        // Force the browser to regard itself as being in the foreground to work around the
-        // fact that the navigation here can happen before ChromeActivity records the
-        // browser as being in the foreground, in which case startup metrics are erroneously
-        // not recorded. TODO(crbug.com/1273097): Eliminate this call when we fix startup
-        // metrics to be recorded in this case.
-        TestThreadUtils.runOnUiThreadBlocking(() -> UmaUtils.recordForegroundStartTime());
-
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.addCategory(Intent.CATEGORY_LAUNCHER);
-        mActivityRule.startMainActivityFromIntent(
-                intent, mServerRule.getServer().getURL(TEST_PAGE));
-
-        // The StartupTabPreloader should have loaded a url.
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramValueCountForTesting(TAB_LOADED_HISTOGRAM, 1));
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramValueCountForTesting(TAB_TAKEN_HISTOGRAM, 1));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramValueCountForTesting(LOAD_DECISION_REASON,
-                        StartupTabPreloader.LoadDecisionReason.ALL_SATISFIED));
-
-        // First contentful paint should be recorded.
-        CriteriaHelper.pollUiThread(()
-                                            -> RecordHistogram.getHistogramTotalCountForTesting(
-                                                       FIRST_CONTENTFUL_PAINT_HISTOGRAM)
-                        == 1);
-        // First contentful paint is the last startup metric to be recorded, so the other startup
-        // metrics should also have been recorded at this point.
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramTotalCountForTesting(FIRST_COMMIT_HISTOGRAM));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramTotalCountForTesting(FIRST_VISIBLE_CONTENT_HISTOGRAM));
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramTotalCountForTesting(VISIBLE_CONTENT_HISTOGRAM));
-
-        // Startup tab preload-specific startup metrics should also have been recorded.
-        assertStartupMetricsRecorded(PRELOAD, PRELOAD_MATCH);
-    }
-
-    @Test
-    @LargeTest
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testStartupTabPreloaderStartupLoadingMetricsRecordedWhenTabDropped()
-            throws Exception {
-        // Force the browser to regard itself as being in the foreground to work around the
-        // fact that the navigation here can happen before ChromeActivity records the
-        // browser as being in the foreground, in which case startup metrics are erroneously
-        // not recorded. TODO(crbug.com/1273097): Eliminate this call when we fix startup
-        // metrics to be recorded in this case.
-        TestThreadUtils.runOnUiThreadBlocking(() -> UmaUtils.recordForegroundStartTime());
-
-        StartupTabPreloader.failNextTabMatchForTesting();
-
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.addCategory(Intent.CATEGORY_LAUNCHER);
-        mActivityRule.startMainActivityFromIntent(
-                intent, mServerRule.getServer().getURL(TEST_PAGE));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramValueCountForTesting(LOAD_DECISION_REASON,
-                        StartupTabPreloader.LoadDecisionReason.ALL_SATISFIED));
-
-        // The StartupTabPreloader should have loaded a url, but it should not have been taken.
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramValueCountForTesting(TAB_LOADED_HISTOGRAM, 1));
-        Assert.assertEquals(
-                0, RecordHistogram.getHistogramValueCountForTesting(TAB_TAKEN_HISTOGRAM, 1));
-
-        // First contentful paint should be recorded.
-        CriteriaHelper.pollUiThread(()
-                                            -> RecordHistogram.getHistogramTotalCountForTesting(
-                                                       FIRST_CONTENTFUL_PAINT_HISTOGRAM)
-                        == 1);
-
-        // First contentful paint is the last startup metric to be recorded, so the other startup
-        // metrics should also have been recorded at this point.
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramTotalCountForTesting(FIRST_COMMIT_HISTOGRAM));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramTotalCountForTesting(FIRST_VISIBLE_CONTENT_HISTOGRAM));
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramTotalCountForTesting(VISIBLE_CONTENT_HISTOGRAM));
-
-        // Startup tab preload-specific startup metrics should also have been recorded.
-        assertStartupMetricsRecorded(PRELOAD, NO_PRELOAD_MATCH);
-    }
-
-    @Test
-    @LargeTest
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testStartupTabPreloaderStartupLoadingMetricsRecordedWhenTabNotPreloaded()
-            throws Exception {
-        // Force the browser to regard itself as being in the foreground to work around the
-        // fact that the navigation here can happen before ChromeActivity records the
-        // browser as being in the foreground, in which case startup metrics are erroneously
-        // not recorded. TODO(crbug.com/1273097): Eliminate this call when we fix startup
-        // metrics to be recorded in this case.
-        TestThreadUtils.runOnUiThreadBlocking(() -> UmaUtils.recordForegroundStartTime());
-
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.addCategory(Intent.CATEGORY_LAUNCHER);
-        intent.putExtra(StartupTabPreloader.EXTRA_DISABLE_STARTUP_TAB_PRELOADER, true);
-        mActivityRule.startMainActivityFromIntent(
-                intent, mServerRule.getServer().getURL(TEST_PAGE));
-
-        // The StartupTabPreloader should not have loaded a url.
-        Assert.assertEquals(
-                0, RecordHistogram.getHistogramValueCountForTesting(TAB_LOADED_HISTOGRAM, 1));
-        Assert.assertEquals(
-                0, RecordHistogram.getHistogramValueCountForTesting(TAB_TAKEN_HISTOGRAM, 1));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramValueCountForTesting(LOAD_DECISION_REASON,
-                        StartupTabPreloader.LoadDecisionReason.DISABLED_BY_INTENT));
-
-        // First contentful paint should be recorded.
-        CriteriaHelper.pollUiThread(()
-                                            -> RecordHistogram.getHistogramTotalCountForTesting(
-                                                       FIRST_CONTENTFUL_PAINT_HISTOGRAM)
-                        == 1);
-        // First contentful paint is the last startup metric to be recorded, so the other startup
-        // metrics should also have been recorded at this point.
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramTotalCountForTesting(FIRST_COMMIT_HISTOGRAM));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramTotalCountForTesting(FIRST_VISIBLE_CONTENT_HISTOGRAM));
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramTotalCountForTesting(VISIBLE_CONTENT_HISTOGRAM));
-
-        // Startup tab preload-specific startup metrics should also have been recorded.
-        assertStartupMetricsRecorded(NO_PRELOAD, NO_PRELOAD_MATCH);
-    }
-
-    @Test
-    @LargeTest
-    @EnableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void
-    testStartupTabPreloaderStartupLoadingMetricsRecordedWhenTabWouldBeTakenIfNotPreventedByFeature()
-            throws Exception {
-        // Force the browser to regard itself as being in the foreground to work around the
-        // fact that the navigation here can happen before ChromeActivity records the
-        // browser as being in the foreground, in which case startup metrics are erroneously
-        // not recorded. TODO(crbug.com/1273097): Eliminate this call when we fix startup
-        // metrics to be recorded in this case.
-        TestThreadUtils.runOnUiThreadBlocking(() -> UmaUtils.recordForegroundStartTime());
-
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.addCategory(Intent.CATEGORY_LAUNCHER);
-        mActivityRule.startMainActivityFromIntent(
-                intent, mServerRule.getServer().getURL(TEST_PAGE));
-
-        // The StartupTabPreloader should not have actually loaded a url.
-        Assert.assertEquals(
-                0, RecordHistogram.getHistogramValueCountForTesting(TAB_LOADED_HISTOGRAM, 1));
-        Assert.assertEquals(
-                0, RecordHistogram.getHistogramValueCountForTesting(TAB_TAKEN_HISTOGRAM, 1));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramValueCountForTesting(LOAD_DECISION_REASON,
-                        StartupTabPreloader.LoadDecisionReason.DISABLED_BY_FEATURE));
-
-        // First contentful paint should be recorded.
-        CriteriaHelper.pollUiThread(()
-                                            -> RecordHistogram.getHistogramTotalCountForTesting(
-                                                       FIRST_CONTENTFUL_PAINT_HISTOGRAM)
-                        == 1);
-        // First contentful paint is the last startup metric to be recorded, so the other startup
-        // metrics should also have been recorded at this point.
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramTotalCountForTesting(FIRST_COMMIT_HISTOGRAM));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramTotalCountForTesting(FIRST_VISIBLE_CONTENT_HISTOGRAM));
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramTotalCountForTesting(VISIBLE_CONTENT_HISTOGRAM));
-
-        // Startup tab preload-specific startup metrics should also have been recorded, with the
-        // state reflecting what it would have been if startup tab preloading were not prevented by
-        // the base::Feature.
-        assertStartupMetricsRecorded(PRELOAD, PRELOAD_MATCH);
-    }
-
-    @Test
-    @LargeTest
-    @EnableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void
-    testStartupTabPreloaderStartupLoadingMetricsRecordedWhenTabWouldBeDroppedIfNotPreventedByFeature()
-            throws Exception {
-        // Force the browser to regard itself as being in the foreground to work around the
-        // fact that the navigation here can happen before ChromeActivity records the
-        // browser as being in the foreground, in which case startup metrics are erroneously
-        // not recorded. TODO(crbug.com/1273097): Eliminate this call when we fix startup
-        // metrics to be recorded in this case.
-        TestThreadUtils.runOnUiThreadBlocking(() -> UmaUtils.recordForegroundStartTime());
-
-        StartupTabPreloader.failNextTabMatchForTesting();
-
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.addCategory(Intent.CATEGORY_LAUNCHER);
-        mActivityRule.startMainActivityFromIntent(
-                intent, mServerRule.getServer().getURL(TEST_PAGE));
-
-        // The StartupTabPreloader should not have actually loaded a url.
-        Assert.assertEquals(
-                0, RecordHistogram.getHistogramValueCountForTesting(TAB_LOADED_HISTOGRAM, 1));
-        Assert.assertEquals(
-                0, RecordHistogram.getHistogramValueCountForTesting(TAB_TAKEN_HISTOGRAM, 1));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramValueCountForTesting(LOAD_DECISION_REASON,
-                        StartupTabPreloader.LoadDecisionReason.DISABLED_BY_FEATURE));
-
-        // First contentful paint should be recorded.
-        CriteriaHelper.pollUiThread(()
-                                            -> RecordHistogram.getHistogramTotalCountForTesting(
-                                                       FIRST_CONTENTFUL_PAINT_HISTOGRAM)
-                        == 1);
-
-        // First contentful paint is the last startup metric to be recorded, so the other startup
-        // metrics should also have been recorded at this point.
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramTotalCountForTesting(FIRST_COMMIT_HISTOGRAM));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramTotalCountForTesting(FIRST_VISIBLE_CONTENT_HISTOGRAM));
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramTotalCountForTesting(VISIBLE_CONTENT_HISTOGRAM));
-
-        // Startup tab preload-specific startup metrics should also have been recorded, with the
-        // state reflecting what it would have been if startup tab preloading were not prevented by
-        // the base::Feature.
-        assertStartupMetricsRecorded(PRELOAD, NO_PRELOAD_MATCH);
-    }
-
-    @Test
-    @LargeTest
-    @EnableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testStartupTabPreloaderWithViewIntentFeatureDisabled() throws Exception {
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.addCategory(Intent.CATEGORY_LAUNCHER);
-        mActivityRule.startMainActivityFromIntent(
-                intent, mServerRule.getServer().getURL(TEST_PAGE));
-
-        // The StartupTabPreloader should have ignored the intent.
-        Assert.assertEquals(
-                0, RecordHistogram.getHistogramValueCountForTesting(TAB_LOADED_HISTOGRAM, 1));
-        Assert.assertEquals(
-                0, RecordHistogram.getHistogramValueCountForTesting(TAB_TAKEN_HISTOGRAM, 1));
-    }
-
-    @Test
-    @LargeTest
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testStartupTabPreloaderWithIncognitoViewIntent() throws Exception {
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.addCategory(Intent.CATEGORY_LAUNCHER);
-        intent.putExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, true);
-        mActivityRule.startMainActivityFromIntent(
-                intent, mServerRule.getServer().getURL(TEST_PAGE));
-
-        // Incognito requests should be ignored.
-        Assert.assertEquals(
-                0, RecordHistogram.getHistogramValueCountForTesting(TAB_LOADED_HISTOGRAM, 1));
-        Assert.assertEquals(
-                0, RecordHistogram.getHistogramValueCountForTesting(TAB_TAKEN_HISTOGRAM, 1));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        LOAD_DECISION_REASON, StartupTabPreloader.LoadDecisionReason.INCOGNITO));
-    }
-
-    @Test
-    @LargeTest
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testStartupTabPreloaderWithMainIntentWithUrl() throws Exception {
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.addCategory(Intent.CATEGORY_LAUNCHER);
-        mActivityRule.startMainActivityFromIntent(
-                intent, mServerRule.getServer().getURL(TEST_PAGE));
-
-        // The StartupTabPreloader should have loaded a url.
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramValueCountForTesting(TAB_LOADED_HISTOGRAM, 1));
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramValueCountForTesting(TAB_TAKEN_HISTOGRAM, 1));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramValueCountForTesting(LOAD_DECISION_REASON,
-                        StartupTabPreloader.LoadDecisionReason.ALL_SATISFIED));
-    }
-
-    @Test
-    @LargeTest
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testStartupTabPreloaderWithMainIntentWithoutUrl() throws Exception {
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.addCategory(Intent.CATEGORY_HOME);
-        mActivityRule.startMainActivityFromIntent(intent, null);
-
-        // There is no url so the StartupTabPreloader should ignore it.
-        Assert.assertEquals(
-                0, RecordHistogram.getHistogramValueCountForTesting(TAB_LOADED_HISTOGRAM, 1));
-        Assert.assertEquals(
-                0, RecordHistogram.getHistogramValueCountForTesting(TAB_TAKEN_HISTOGRAM, 1));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramValueCountForTesting(
-                        LOAD_DECISION_REASON, StartupTabPreloader.LoadDecisionReason.NO_URL));
-    }
-
-    @Test
-    @LargeTest
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testStartupTabPreloaderWithMultipleViewIntents() throws Exception {
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.addCategory(Intent.CATEGORY_LAUNCHER);
-        mActivityRule.startMainActivityFromIntent(
-                intent, mServerRule.getServer().getURL(TEST_PAGE));
-
-        // The StartupTabPreloader should have loaded a url.
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramValueCountForTesting(TAB_LOADED_HISTOGRAM, 1));
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramValueCountForTesting(TAB_TAKEN_HISTOGRAM, 1));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramValueCountForTesting(LOAD_DECISION_REASON,
-                        StartupTabPreloader.LoadDecisionReason.ALL_SATISFIED));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        ACTIVITY_START_TO_PRELOAD_TRIGGER));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_MATCH_DECISION_PRELOAD));
-        Assert.assertEquals(0,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_MATCH_DECISION_NO_PRELOAD));
-
-        Tab currentTab = mActivityRule.getActivity().getActivityTab();
-
-        intent = new Intent(Intent.ACTION_VIEW);
-        String url = mServerRule.getServer().getURL(TEST_PAGE2);
-        mActivityRule.getActivity().startActivity(mActivityRule.prepareUrlIntent(intent, url));
-
-        CriteriaHelper.pollUiThread(
-                () -> mActivityRule.getActivity().getActivityTab() != currentTab);
-        ChromeTabUtils.waitForTabPageLoaded(mActivityRule.getActivity().getActivityTab(), url);
-
-        // The second intent should be ignored and not increment the counters.
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramValueCountForTesting(TAB_LOADED_HISTOGRAM, 1));
-        Assert.assertEquals(
-                1, RecordHistogram.getHistogramValueCountForTesting(TAB_TAKEN_HISTOGRAM, 1));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramValueCountForTesting(LOAD_DECISION_REASON,
-                        StartupTabPreloader.LoadDecisionReason.ALL_SATISFIED));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        ACTIVITY_START_TO_PRELOAD_TRIGGER));
-        Assert.assertEquals(1,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_MATCH_DECISION_PRELOAD));
-        Assert.assertEquals(0,
-                RecordHistogram.getHistogramTotalCountForTesting(
-                        PRELOAD_TRIGGER_TO_MATCH_DECISION_NO_PRELOAD));
-    }
-
-    @Test
-    @LargeTest
-    @EnableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testStartupTabPreloaderMultipleTabCreationWithFeatureEnabled() throws Exception {
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.addCategory(Intent.CATEGORY_LAUNCHER);
-        mActivityRule.startMainActivityFromIntent(
-                intent, mServerRule.getServer().getURL(TEST_PAGE));
-
-        // The StartupTabPreloader should not have loaded a url.
-        Assert.assertEquals(
-                0, RecordHistogram.getHistogramValueCountForTesting(TAB_LOADED_HISTOGRAM, 1));
-        Assert.assertEquals(
-                0, RecordHistogram.getHistogramValueCountForTesting(TAB_TAKEN_HISTOGRAM, 1));
-
-        Tab currentTab = mActivityRule.getActivity().getActivityTab();
-
-        // Creating a second tab should not cause a browser crash. Verifies safety of subtle
-        // logic handling metrics in the case where the feature is enabled.
-        intent = new Intent(Intent.ACTION_VIEW);
-        String url = mServerRule.getServer().getURL(TEST_PAGE2);
-        mActivityRule.getActivity().startActivity(mActivityRule.prepareUrlIntent(intent, url));
-
-        CriteriaHelper.pollUiThread(
-                () -> mActivityRule.getActivity().getActivityTab() != currentTab);
-        ChromeTabUtils.waitForTabPageLoaded(mActivityRule.getActivity().getActivityTab(), url);
-
-        Assert.assertEquals(
-                0, RecordHistogram.getHistogramValueCountForTesting(TAB_LOADED_HISTOGRAM, 1));
-        Assert.assertEquals(
-                0, RecordHistogram.getHistogramValueCountForTesting(TAB_TAKEN_HISTOGRAM, 1));
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderUnitTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderUnitTest.java
deleted file mode 100644
index acca223..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderUnitTest.java
+++ /dev/null
@@ -1,256 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// 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.init;
-
-import android.content.ComponentName;
-import android.content.Intent;
-import android.net.Uri;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Assert;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.Callback;
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.supplier.ObservableSupplier;
-import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.IntentHandler;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.metrics.ActivityTabStartupMetricsTracker;
-import org.chromium.chrome.browser.tabmodel.ChromeTabCreator;
-import org.chromium.chrome.browser.tabmodel.TabCreator;
-import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
-import org.chromium.chrome.browser.tabmodel.TabModelSelector;
-import org.chromium.chrome.browser.tabmodel.document.TabDelegate;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.util.browser.Features;
-import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
-import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
-import org.chromium.content_public.browser.LoadUrlParams;
-import org.chromium.content_public.common.Referrer;
-import org.chromium.network.mojom.ReferrerPolicy;
-
-/**
- * Unit tests for {@link StartupTabPreloader}.
- */
-@RunWith(ChromeJUnit4ClassRunner.class)
-public class StartupTabPreloaderUnitTest {
-    private static final String SITE_A = "https://a.com";
-    private static final String SITE_B = "https://b.com";
-    private static final String SITE_C = "https://c.com";
-    private static final String INVALID_SCHEME = "javascript:alert()";
-    private static final Intent VIEW_INTENT =
-            new Intent(Intent.ACTION_VIEW).setData(Uri.parse(SITE_A));
-    private static final Intent CHROME_MAIN_COMPONENT_INTENT =
-            new Intent()
-                    .setComponent(new ComponentName("com.google.android.apps.chrome",
-                            "com.google.android.apps.chrome.Main"))
-                    .setData(Uri.parse(SITE_A));
-    private static final Intent INCOGNITO_VIEW_INTENT =
-            new Intent(Intent.ACTION_VIEW)
-                    .setData(Uri.parse(SITE_A))
-                    .putExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, true);
-    private static final Intent VIEW_INTENT_WITH_INVALID_SCHEME =
-            new Intent(Intent.ACTION_VIEW).setData(Uri.parse(INVALID_SCHEME));
-    private static final Intent MAIN_INTENT_WITH_URL =
-            new Intent(Intent.ACTION_MAIN).setData(Uri.parse(SITE_B));
-    private static final Intent MAIN_INTENT_WITHOUT_URL = new Intent(Intent.ACTION_MAIN);
-    private static final TabCreatorManager sChromeTabCreator = new ChromeTabCreatorManager();
-    private static final TabCreatorManager sUninitializedChromeTabCreatorManager =
-            new UninitializedChromeTabCreatorManager();
-    private static final TabCreatorManager sNonChromeTabCreator = new NonChromeTabCreatorManager();
-
-    @Rule
-    public Features.JUnitProcessor processor = new Features.JUnitProcessor();
-
-    @Test
-    @SmallTest
-    public void testDoLoadUrlParamsMatchForWarmupManagerNavigation() {
-        LoadUrlParams siteAWithSiteBReferrer_1 = new LoadUrlParams(SITE_A);
-        siteAWithSiteBReferrer_1.setReferrer(new Referrer(SITE_B, ReferrerPolicy.DEFAULT));
-        LoadUrlParams siteAWithSiteBReferrer_2 = new LoadUrlParams(SITE_A);
-        siteAWithSiteBReferrer_2.setReferrer(new Referrer(SITE_B, ReferrerPolicy.DEFAULT));
-
-        LoadUrlParams siteAWithSiteBReferrer = new LoadUrlParams(SITE_A);
-        siteAWithSiteBReferrer.setReferrer(new Referrer(SITE_B, ReferrerPolicy.DEFAULT));
-
-        LoadUrlParams siteAWithSiteCReferrer = new LoadUrlParams(SITE_A);
-        siteAWithSiteCReferrer.setReferrer(new Referrer(SITE_C, ReferrerPolicy.DEFAULT));
-
-        LoadUrlParams siteAWithNoReferrer = new LoadUrlParams(SITE_A);
-        LoadUrlParams siteBWithNoReferrer_1 = new LoadUrlParams(SITE_B);
-        LoadUrlParams siteBWithNoReferrer_2 = new LoadUrlParams(SITE_B);
-
-        Assert.assertTrue(StartupTabPreloader.doLoadUrlParamsMatchForWarmupManagerNavigation(
-                siteAWithSiteBReferrer_1, siteAWithSiteBReferrer_2));
-        Assert.assertTrue(StartupTabPreloader.doLoadUrlParamsMatchForWarmupManagerNavigation(
-                siteBWithNoReferrer_2, siteBWithNoReferrer_2));
-
-        Assert.assertFalse(StartupTabPreloader.doLoadUrlParamsMatchForWarmupManagerNavigation(
-                siteAWithSiteBReferrer_1, siteAWithSiteCReferrer));
-        Assert.assertFalse(StartupTabPreloader.doLoadUrlParamsMatchForWarmupManagerNavigation(
-                siteAWithSiteBReferrer_1, siteAWithNoReferrer));
-        Assert.assertFalse(StartupTabPreloader.doLoadUrlParamsMatchForWarmupManagerNavigation(
-                siteAWithSiteBReferrer_1, siteBWithNoReferrer_1));
-        Assert.assertFalse(StartupTabPreloader.doLoadUrlParamsMatchForWarmupManagerNavigation(
-                siteAWithNoReferrer, siteBWithNoReferrer_1));
-    }
-
-    @Test
-    @SmallTest
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testShouldLoadTab_AllowViewIntents() {
-        StartupTabPreloader preloader = createStartupTabPreloader(VIEW_INTENT, sChromeTabCreator);
-        Assert.assertTrue(preloader.shouldLoadTab());
-        Assert.assertEquals(StartupTabPreloader.LoadDecisionReason.ALL_SATISFIED,
-                preloader.getLoadDecisionReason());
-    }
-
-    @Test
-    @SmallTest
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testShouldLoadTab_AllowChromeMainComponentIntentWithUrl() {
-        StartupTabPreloader preloader =
-                createStartupTabPreloader(CHROME_MAIN_COMPONENT_INTENT, sChromeTabCreator);
-        Assert.assertTrue(preloader.shouldLoadTab());
-        Assert.assertEquals(StartupTabPreloader.LoadDecisionReason.ALL_SATISFIED,
-                preloader.getLoadDecisionReason());
-    }
-
-    @Test
-    @SmallTest
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testShouldLoadTab_AllowMainIntentsWithUrl() {
-        StartupTabPreloader preloader =
-                createStartupTabPreloader(MAIN_INTENT_WITH_URL, sChromeTabCreator);
-        Assert.assertTrue(preloader.shouldLoadTab());
-        Assert.assertEquals(StartupTabPreloader.LoadDecisionReason.ALL_SATISFIED,
-                preloader.getLoadDecisionReason());
-    }
-
-    @Test
-    @SmallTest
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testShouldLoadTab_BlockedMainIntentsWithoutUrl() {
-        StartupTabPreloader preloader =
-                createStartupTabPreloader(MAIN_INTENT_WITHOUT_URL, sChromeTabCreator);
-        Assert.assertFalse(preloader.shouldLoadTab());
-        Assert.assertEquals(
-                StartupTabPreloader.LoadDecisionReason.NO_URL, preloader.getLoadDecisionReason());
-    }
-
-    @Test
-    @SmallTest
-    @EnableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testShouldLoadTab_BlockedWhenSpecifiedByFeature() {
-        StartupTabPreloader preloader = createStartupTabPreloader(VIEW_INTENT, sChromeTabCreator);
-        Assert.assertFalse(preloader.shouldLoadTab());
-        Assert.assertEquals(StartupTabPreloader.LoadDecisionReason.DISABLED_BY_FEATURE,
-                preloader.getLoadDecisionReason());
-    }
-
-    @Test
-    @SmallTest
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testShouldLoadTab_BlockedInvalidSchemeIntent() {
-        StartupTabPreloader preloader =
-                createStartupTabPreloader(VIEW_INTENT_WITH_INVALID_SCHEME, sChromeTabCreator);
-        Assert.assertFalse(preloader.shouldLoadTab());
-        Assert.assertEquals(StartupTabPreloader.LoadDecisionReason.INTENT_IGNORED,
-                preloader.getLoadDecisionReason());
-    }
-
-    @Test
-    @SmallTest
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testShouldLoadTab_BlockedNonChromeTabCreators() {
-        StartupTabPreloader preloader =
-                createStartupTabPreloader(VIEW_INTENT, sNonChromeTabCreator);
-        Assert.assertFalse(preloader.shouldLoadTab());
-        Assert.assertEquals(StartupTabPreloader.LoadDecisionReason.WRONG_TAB_CREATOR,
-                preloader.getLoadDecisionReason());
-    }
-
-    @Test
-    @SmallTest
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testShouldLoadTab_BlockedIncognitoIntents() {
-        StartupTabPreloader preloader =
-                createStartupTabPreloader(INCOGNITO_VIEW_INTENT, sChromeTabCreator);
-        Assert.assertFalse(preloader.shouldLoadTab());
-        Assert.assertEquals(StartupTabPreloader.LoadDecisionReason.INCOGNITO,
-                preloader.getLoadDecisionReason());
-    }
-
-    @Test
-    @SmallTest
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
-    public void testShouldLoadTab_UninitializedTabCreatorManager() {
-        StartupTabPreloader preloader =
-                createStartupTabPreloader(VIEW_INTENT, sUninitializedChromeTabCreatorManager);
-        Assert.assertFalse(preloader.shouldLoadTab());
-        Assert.assertEquals(StartupTabPreloader.LoadDecisionReason.NO_TAB_CREATOR,
-                preloader.getLoadDecisionReason());
-    }
-
-    private StartupTabPreloader createStartupTabPreloader(
-            Intent intent, TabCreatorManager tabCreatorManager) {
-        // StartupTabPreloader calls into code that asserts that it is on the UI thread, which
-        // doesn't exist in this unittesting context.
-        ThreadUtils.setThreadAssertsDisabledForTesting(true);
-
-        return new StartupTabPreloader(
-                new Supplier<Intent>() {
-                    @Override
-                    public Intent get() {
-                        return intent;
-                    }
-                },
-                new ActivityLifecycleDispatcherImpl(null), null, tabCreatorManager,
-                new IntentHandler(null, null),
-                new ActivityTabStartupMetricsTracker(new ObservableSupplier<TabModelSelector>() {
-                    @Override
-                    public TabModelSelector addObserver(Callback<TabModelSelector> obs) {
-                        return null;
-                    }
-
-                    @Override
-                    public void removeObserver(Callback<TabModelSelector> obs) {}
-
-                    @Override
-                    public TabModelSelector get() {
-                        return null;
-                    }
-                }));
-    }
-
-    private static class ChromeTabCreatorManager implements TabCreatorManager {
-        @Override
-        public TabCreator getTabCreator(boolean incognito) {
-            Assert.assertFalse(incognito);
-            return new ChromeTabCreator(null, null, null, null, false, null, null, null, null);
-        }
-    }
-
-    private static class UninitializedChromeTabCreatorManager implements TabCreatorManager {
-        @Override
-        public TabCreator getTabCreator(boolean incognito) {
-            throw new IllegalStateException("uninitialized for test");
-        }
-    }
-
-    private static class NonChromeTabCreatorManager implements TabCreatorManager {
-        @Override
-        public TabCreator getTabCreator(boolean incognito) {
-            Assert.assertFalse(incognito);
-
-            // The important thing is this isn't ChromeTabCreator.
-            return new TabDelegate(false);
-        }
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java
index 8f99732b..a62edc6 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/metrics/StartupLoadingMetricsTest.java
@@ -24,7 +24,6 @@
 import org.chromium.base.test.util.DisableIf;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.webapps.WebApkActivityLifecycleUmaTracker;
@@ -34,7 +33,6 @@
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
 import org.chromium.chrome.test.util.ChromeApplicationTestUtils;
 import org.chromium.chrome.test.util.ChromeTabUtils;
-import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.net.test.EmbeddedTestServer;
 
@@ -274,7 +272,6 @@
 
     @Test
     @LargeTest
-    @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP)
     @DisabledTest(message = "https://crbug.com/1313210")
     public void testRecordingOfFirstNavigationCommitPreForeground() throws Exception {
         UmaUtils.skipRecordingNextForegroundStartTimeForTesting();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationTest.java
index c35f3cb..941a4f1 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationTest.java
@@ -43,7 +43,6 @@
 import org.chromium.chrome.browser.customtabs.dependency_injection.BaseCustomTabActivityModule;
 import org.chromium.chrome.browser.dependency_injection.ModuleOverridesRule;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
-import org.chromium.chrome.browser.init.StartupTabPreloader;
 import org.chromium.chrome.browser.notifications.NotificationConstants;
 import org.chromium.chrome.browser.theme.TopUiThemeColorProvider;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
@@ -63,17 +62,16 @@
     @Rule
     public final WebappActivityTestRule mActivityTestRule = new WebappActivityTestRule();
 
-    private final TestRule mModuleOverridesRule = new ModuleOverridesRule().setOverride(
-            BaseCustomTabActivityModule.Factory.class,
-            (BrowserServicesIntentDataProvider intentDataProvider,
-                    StartupTabPreloader startupTabPreloader,
-                    CustomTabNightModeStateController nightModeController,
-                    CustomTabIntentHandler.IntentIgnoringCriterion intentIgnoringCriterion,
-                    TopUiThemeColorProvider topUiThemeColorProvider,
-                    DefaultBrowserProviderImpl customTabDefaultBrowserProvider)
-                    -> new BaseCustomTabActivityModule(intentDataProvider, startupTabPreloader,
-                            nightModeController, intentIgnoringCriterion, topUiThemeColorProvider,
-                            new FakeDefaultBrowserProviderImpl()));
+    private final TestRule mModuleOverridesRule =
+            new ModuleOverridesRule().setOverride(BaseCustomTabActivityModule.Factory.class,
+                    (BrowserServicesIntentDataProvider intentDataProvider,
+                            CustomTabNightModeStateController nightModeController,
+                            CustomTabIntentHandler.IntentIgnoringCriterion intentIgnoringCriterion,
+                            TopUiThemeColorProvider topUiThemeColorProvider,
+                            DefaultBrowserProviderImpl customTabDefaultBrowserProvider)
+                            -> new BaseCustomTabActivityModule(intentDataProvider,
+                                    nightModeController, intentIgnoringCriterion,
+                                    topUiThemeColorProvider, new FakeDefaultBrowserProviderImpl()));
 
     @Rule
     public RuleChain mRuleChain =
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappNavigationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappNavigationTest.java
index ef3ce75..6fbcf0f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappNavigationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappNavigationTest.java
@@ -55,7 +55,6 @@
 import org.chromium.chrome.browser.dependency_injection.ModuleOverridesRule;
 import org.chromium.chrome.browser.firstrun.FirstRunStatus;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
-import org.chromium.chrome.browser.init.StartupTabPreloader;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.test.MockCertVerifierRuleAndroid;
 import org.chromium.chrome.browser.theme.TopUiThemeColorProvider;
@@ -86,17 +85,16 @@
     public MockCertVerifierRuleAndroid mCertVerifierRule =
             new MockCertVerifierRuleAndroid(0 /* net::OK */);
 
-    private final TestRule mModuleOverridesRule = new ModuleOverridesRule().setOverride(
-            BaseCustomTabActivityModule.Factory.class,
-            (BrowserServicesIntentDataProvider intentDataProvider,
-                    StartupTabPreloader startupTabPreloader,
-                    CustomTabNightModeStateController nightModeController,
-                    CustomTabIntentHandler.IntentIgnoringCriterion intentIgnoringCriterion,
-                    TopUiThemeColorProvider topUiThemeColorProvider,
-                    DefaultBrowserProviderImpl customTabDefaultBrowserProvider)
-                    -> new BaseCustomTabActivityModule(intentDataProvider, startupTabPreloader,
-                            nightModeController, intentIgnoringCriterion, topUiThemeColorProvider,
-                            new FakeDefaultBrowserProviderImpl()));
+    private final TestRule mModuleOverridesRule =
+            new ModuleOverridesRule().setOverride(BaseCustomTabActivityModule.Factory.class,
+                    (BrowserServicesIntentDataProvider intentDataProvider,
+                            CustomTabNightModeStateController nightModeController,
+                            CustomTabIntentHandler.IntentIgnoringCriterion intentIgnoringCriterion,
+                            TopUiThemeColorProvider topUiThemeColorProvider,
+                            DefaultBrowserProviderImpl customTabDefaultBrowserProvider)
+                            -> new BaseCustomTabActivityModule(intentDataProvider,
+                                    nightModeController, intentIgnoringCriterion,
+                                    topUiThemeColorProvider, new FakeDefaultBrowserProviderImpl()));
 
     @Rule
     public RuleChain mRuleChain = RuleChain.emptyRuleChain()
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityContentTestEnvironment.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityContentTestEnvironment.java
index dbc81ba7..220fc6c1 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityContentTestEnvironment.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityContentTestEnvironment.java
@@ -6,7 +6,6 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -50,7 +49,6 @@
 import org.chromium.chrome.browser.flags.ActivityType;
 import org.chromium.chrome.browser.fullscreen.FullscreenManager;
 import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
-import org.chromium.chrome.browser.init.StartupTabPreloader;
 import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
 import org.chromium.chrome.browser.password_manager.PasswordChangeSuccessTrackerBridge;
 import org.chromium.chrome.browser.tab.Tab;
@@ -105,7 +103,6 @@
     @Mock public ToolbarManager toolbarManager;
     @Mock public ChromeBrowserInitializer browserInitializer;
     @Mock public FullscreenManager fullscreenManager;
-    @Mock public StartupTabPreloader startupTabPreloader;
     @Mock public CustomTabIncognitoManager customTabIncognitoManager;
     @Mock public TabModelInitializer tabModelInitializer;
     // clang-format on
@@ -150,7 +147,6 @@
         // Default setup is toolbarManager doesn't consume back press event.
         when(toolbarManager.back()).thenReturn(false);
 
-        when(startupTabPreloader.takeTabIfMatchingOrDestroy(any(), anyInt())).thenReturn(null);
         when(reparentingTaskProvider.get(any())).thenReturn(reparentingTask);
         when(activityTabProvider.addObserver(activityTabObserverCaptor.capture())).thenReturn(null);
         when(intentDataProvider.getColorProvider()).thenReturn(colorProvider);
@@ -178,7 +174,7 @@
                 connection, intentDataProvider, activityTabProvider, tabObserverRegistrar,
                 () -> compositorViewHolder, lifecycleDispatcher, warmupManager,
                 tabPersistencePolicy, tabFactory, () -> customTabObserver, webContentsFactory,
-                navigationEventObserver, tabProvider, startupTabPreloader, reparentingTaskProvider,
+                navigationEventObserver, tabProvider, reparentingTaskProvider,
                 () -> customTabIncognitoManager, () -> realAsyncTabParamsManager,
                 () -> activity.getSavedInstanceState(), activity.getWindowAndroid(),
                 tabModelInitializer);
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index 0722cae..87a01366 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -5625,6 +5625,9 @@
   <message name="IDS_ACCOUNT_MANAGER_DIALOG_ADD_ACCOUNT_LABEL" desc="Label of the Add account button on Account picker screen.">
     Add Google Account
   </message>
+  <message name="IDS_ACCOUNT_MANAGER_DIALOG_ADD_SCHOOL_ACCOUNT_LABEL" desc="Label of the button to add a school/EDU account on Account picker screen.">
+    Add school account
+  </message>
   <message name="IDS_ACCOUNT_MANAGER_DIALOG_WELCOME_CHECKBOX" desc="Checkbox text for the Welcome screen in ChromeOS 'Add account' dialog. If user checks this checkbox, this screen will not be shown the next time they open the dialog.">
     Don't remind me next time
   </message>
diff --git a/chrome/app/chromeos_strings_grdp/IDS_ACCOUNT_MANAGER_DIALOG_ADD_SCHOOL_ACCOUNT_LABEL.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_ACCOUNT_MANAGER_DIALOG_ADD_SCHOOL_ACCOUNT_LABEL.png.sha1
new file mode 100644
index 0000000..4945b74
--- /dev/null
+++ b/chrome/app/chromeos_strings_grdp/IDS_ACCOUNT_MANAGER_DIALOG_ADD_SCHOOL_ACCOUNT_LABEL.png.sha1
@@ -0,0 +1 @@
+a4ba9bcb44572b660c6253f82bcb052c9892216e
\ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 5a1c38d..e51e9f4 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -13082,6 +13082,9 @@
     <message name="IDS_PRIVACY_SANDBOX_BUBBLE_NOTICE_DESCRIPTION" translateable="false">
       During trials, Chrome is exploring ways to limit spam, fraud, and sharing between sites. Chrome also <ph name="ESTIMATE_INTERESTS_LINK">$1<ex>estimates your interests</ex></ph> that sites can use to show you ads. You can manage your interests in settings.
     </message>
+    <message name="IDS_PRIVACY_SANDBOX_BUBBLE_NOTICE_SETTINGS_LINK" translateable="false">
+      Go to settings
+    </message>
     <message name="IDS_PRIVACY_SANDBOX_BUBBLE_NOTICE_DESCRIPTION_ESTIMATES_INTERESTS_LINK" translateable="false">
       estimates your interests
     </message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index ec10a086..0f98bd2 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -7467,11 +7467,12 @@
     {"incognito-screenshot", flag_descriptions::kIncognitoScreenshotName,
      flag_descriptions::kIncognitoScreenshotDescription, kOsAndroid,
      FEATURE_VALUE_TYPE(chrome::android::kIncognitoScreenshot)},
-#endif
+
     {"incognito-downloads-warning",
      flag_descriptions::kIncognitoDownloadsWarningName,
-     flag_descriptions::kIncognitoDownloadsWarningDescription, kOsAll,
+     flag_descriptions::kIncognitoDownloadsWarningDescription, kOsAndroid,
      FEATURE_VALUE_TYPE(features::kIncognitoDownloadsWarning)},
+#endif
 
     {"incognito-ntp-revamp", flag_descriptions::kIncognitoNtpRevampName,
      flag_descriptions::kIncognitoNtpRevampDescription, kOsAll,
diff --git a/chrome/browser/apps/app_service/menu_util.cc b/chrome/browser/apps/app_service/menu_util.cc
index 68b973cf..7e65c199 100644
--- a/chrome/browser/apps/app_service/menu_util.cc
+++ b/chrome/browser/apps/app_service/menu_util.cc
@@ -231,9 +231,9 @@
 }
 
 apps::mojom::MenuType MenuTypeFromString(base::StringPiece menu_type) {
-  if (base::LowerCaseEqualsASCII(menu_type, "shelf"))
+  if (base::EqualsCaseInsensitiveASCII(menu_type, "shelf"))
     return apps::mojom::MenuType::kShelf;
-  if (base::LowerCaseEqualsASCII(menu_type, "applist"))
+  if (base::EqualsCaseInsensitiveASCII(menu_type, "applist"))
     return apps::mojom::MenuType::kAppList;
   return apps::mojom::MenuType::kShelf;
 }
diff --git a/chrome/browser/ash/arc/fileapi/arc_documents_provider_root.h b/chrome/browser/ash/arc/fileapi/arc_documents_provider_root.h
index 6d80ceda..f3ad0b10 100644
--- a/chrome/browser/ash/arc/fileapi/arc_documents_provider_root.h
+++ b/chrome/browser/ash/arc/fileapi/arc_documents_provider_root.h
@@ -221,6 +221,9 @@
   void GetRootSize(GetRootSizeCallback callback);
 
  private:
+  friend class ArcDocumentsProviderRootMapTest;
+  FRIEND_TEST_ALL_PREFIXES(ArcDocumentsProviderRootMapTest, Lookup);
+
   struct WatcherData;
   struct DirectoryCache;
 
diff --git a/chrome/browser/ash/arc/fileapi/arc_documents_provider_root_map.cc b/chrome/browser/ash/arc/fileapi/arc_documents_provider_root_map.cc
index 961e6c8f..0b8b699 100644
--- a/chrome/browser/ash/arc/fileapi/arc_documents_provider_root_map.cc
+++ b/chrome/browser/ash/arc/fileapi/arc_documents_provider_root_map.cc
@@ -5,6 +5,8 @@
 #include "chrome/browser/ash/arc/fileapi/arc_documents_provider_root_map.h"
 
 #include "ash/components/arc/session/arc_service_manager.h"
+#include "ash/constants/ash_features.h"
+#include "base/feature_list.h"
 #include "chrome/browser/ash/arc/fileapi/arc_documents_provider_root.h"
 #include "chrome/browser/ash/arc/fileapi/arc_documents_provider_root_map_factory.h"
 #include "chrome/browser/ash/arc/fileapi/arc_documents_provider_util.h"
@@ -26,19 +28,18 @@
   const char* authority;
   const char* root_document_id;
   const char* root_id;
-  bool read_only;
 };
 
 // List of documents providers for media views.
 constexpr DocumentsProviderSpec kDocumentsProviderAllowlist[] = {
     {kMediaDocumentsProviderAuthority, kImagesRootDocumentId,
-     kImagesRootDocumentId, true},
+     kImagesRootDocumentId},
     {kMediaDocumentsProviderAuthority, kVideosRootDocumentId,
-     kVideosRootDocumentId, true},
+     kVideosRootDocumentId},
     {kMediaDocumentsProviderAuthority, kAudioRootDocumentId,
-     kAudioRootDocumentId, true},
+     kAudioRootDocumentId},
     {kMediaDocumentsProviderAuthority, kDocumentsRootDocumentId,
-     kDocumentsRootDocumentId, true},
+     kDocumentsRootDocumentId},
 };
 
 }  // namespace
@@ -55,6 +56,13 @@
   return GetForBrowserContext(ArcServiceManager::Get()->browser_context());
 }
 
+// static
+// TODO(crbug.com/1327496): can be removed once this flag is on by default.
+bool ArcDocumentsProviderRootMap::IsDocumentProviderRootReadOnly() {
+  // All roots are read-only unless this flag is on.
+  return !base::FeatureList::IsEnabled(chromeos::features::kFiltersInRecentsV2);
+}
+
 ArcDocumentsProviderRootMap::ArcDocumentsProviderRootMap(Profile* profile)
     : runner_(ArcFileSystemOperationRunner::GetForBrowserContext(profile)) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -62,9 +70,10 @@
   // in ArcDocumentsProviderRootMapFactory.
   DCHECK(runner_);
 
+  const bool read_only = IsDocumentProviderRootReadOnly();
   for (const auto& spec : kDocumentsProviderAllowlist) {
-    RegisterRoot(spec.authority, spec.root_document_id, spec.root_id,
-                 spec.read_only, {});
+    RegisterRoot(spec.authority, spec.root_document_id, spec.root_id, read_only,
+                 {});
   }
 }
 
@@ -114,7 +123,7 @@
   Key key(authority, root_document_id);
   if (map_.find(key) != map_.end()) {
     VLOG(1) << "Trying to register (" << authority << ", " << root_document_id
-            << ") which is already regisered.";
+            << ") which is already registered.";
     return;
   }
   map_.emplace(key, std::make_unique<ArcDocumentsProviderRoot>(
diff --git a/chrome/browser/ash/arc/fileapi/arc_documents_provider_root_map.h b/chrome/browser/ash/arc/fileapi/arc_documents_provider_root_map.h
index b8d03c3..919314c 100644
--- a/chrome/browser/ash/arc/fileapi/arc_documents_provider_root_map.h
+++ b/chrome/browser/ash/arc/fileapi/arc_documents_provider_root_map.h
@@ -52,6 +52,9 @@
   // its delegates.
   static ArcDocumentsProviderRootMap* GetForArcBrowserContext();
 
+  // Checks if a given document provider root is read only or not.
+  static bool IsDocumentProviderRootReadOnly();
+
   // Looks up a root corresponding to |url|.
   // |path| is set to the remaining path part of |url|.
   // Returns nullptr if |url| is invalid or no corresponding root is registered.
diff --git a/chrome/browser/ash/arc/fileapi/arc_documents_provider_root_map_unittest.cc b/chrome/browser/ash/arc/fileapi/arc_documents_provider_root_map_unittest.cc
new file mode 100644
index 0000000..c434780a
--- /dev/null
+++ b/chrome/browser/ash/arc/fileapi/arc_documents_provider_root_map_unittest.cc
@@ -0,0 +1,147 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// 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/fileapi/arc_documents_provider_root_map.h"
+
+#include <memory>
+
+#include "ash/components/arc/session/arc_bridge_service.h"
+#include "ash/components/arc/session/arc_service_manager.h"
+#include "ash/components/arc/test/connection_holder_util.h"
+#include "ash/components/arc/test/fake_file_system_instance.h"
+#include "ash/constants/ash_features.h"
+#include "base/bind.h"
+#include "base/memory/raw_ptr.h"
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/ash/arc/fileapi/arc_documents_provider_root.h"
+#include "chrome/browser/ash/arc/fileapi/arc_file_system_operation_runner.h"
+#include "chrome/browser/ash/arc/fileapi/arc_media_view_util.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 {
+namespace {
+
+constexpr char kTestRootId[] = "abc_root";
+
+std::unique_ptr<KeyedService> CreateFileSystemOperationRunnerForTesting(
+    content::BrowserContext* context) {
+  return ArcFileSystemOperationRunner::CreateForTesting(
+      context, ArcServiceManager::Get()->arc_bridge_service());
+}
+
+}  // namespace
+
+class ArcDocumentsProviderRootMapTest : public testing::Test {
+ public:
+  ArcDocumentsProviderRootMapTest() = default;
+  ArcDocumentsProviderRootMapTest(const ArcDocumentsProviderRootMapTest&) =
+      delete;
+  ArcDocumentsProviderRootMapTest& operator=(
+      const ArcDocumentsProviderRootMapTest&) = delete;
+  ~ArcDocumentsProviderRootMapTest() override = default;
+
+ protected:
+  void SetUp() override {
+    profile_ = std::make_unique<TestingProfile>();
+    SetUpARC();
+    arc_documents_provider_root_map_ =
+        ArcDocumentsProviderRootMap::GetForBrowserContext(profile_.get());
+  }
+
+  void TearDown() override {
+    arc_documents_provider_root_map_->Shutdown();
+    TearDownARC();
+    profile_.reset();
+  }
+
+  ArcDocumentsProviderRootMap* GetRootMap() const {
+    return arc_documents_provider_root_map_.get();
+  }
+
+ private:
+  void SetUpARC() {
+    arc_service_manager_ = std::make_unique<ArcServiceManager>();
+    arc_service_manager_->set_browser_context(profile_.get());
+    ArcFileSystemOperationRunner::GetFactory()->SetTestingFactoryAndUse(
+        profile_.get(),
+        base::BindRepeating(&CreateFileSystemOperationRunnerForTesting));
+    arc_service_manager_->arc_bridge_service()->file_system()->SetInstance(
+        &fake_file_system_);
+    WaitForInstanceReady(
+        arc_service_manager_->arc_bridge_service()->file_system());
+    ASSERT_TRUE(fake_file_system_.InitCalled());
+  }
+
+  void TearDownARC() {
+    arc_service_manager_->arc_bridge_service()->file_system()->CloseInstance(
+        &fake_file_system_);
+  }
+
+  content::BrowserTaskEnvironment task_environment_;
+  std::unique_ptr<TestingProfile> profile_;
+  FakeFileSystemInstance fake_file_system_;
+  std::unique_ptr<ArcServiceManager> arc_service_manager_;
+  raw_ptr<ArcDocumentsProviderRootMap> arc_documents_provider_root_map_;
+};
+
+TEST_F(ArcDocumentsProviderRootMapTest, Lookup) {
+  ArcDocumentsProviderRoot* images_root = GetRootMap()->Lookup(
+      kMediaDocumentsProviderAuthority, kImagesRootDocumentId);
+  EXPECT_EQ(images_root->authority_, kMediaDocumentsProviderAuthority);
+  EXPECT_EQ(images_root->root_id_, kImagesRootDocumentId);
+  ArcDocumentsProviderRoot* audio_root = GetRootMap()->Lookup(
+      kMediaDocumentsProviderAuthority, kAudioRootDocumentId);
+  EXPECT_EQ(audio_root->authority_, kMediaDocumentsProviderAuthority);
+  EXPECT_EQ(audio_root->root_id_, kAudioRootDocumentId);
+  ArcDocumentsProviderRoot* videos_root = GetRootMap()->Lookup(
+      kMediaDocumentsProviderAuthority, kVideosRootDocumentId);
+  EXPECT_EQ(videos_root->authority_, kMediaDocumentsProviderAuthority);
+  EXPECT_EQ(videos_root->root_id_, kVideosRootDocumentId);
+  ArcDocumentsProviderRoot* documents_root = GetRootMap()->Lookup(
+      kMediaDocumentsProviderAuthority, kDocumentsRootDocumentId);
+  EXPECT_EQ(documents_root->authority_, kMediaDocumentsProviderAuthority);
+  EXPECT_EQ(documents_root->root_id_, kDocumentsRootDocumentId);
+
+  EXPECT_EQ(GetRootMap()->Lookup(kMediaDocumentsProviderAuthority, kTestRootId),
+            nullptr);
+}
+
+TEST_F(ArcDocumentsProviderRootMapTest, RegisterRoot) {
+  EXPECT_EQ(GetRootMap()->Lookup(kMediaDocumentsProviderAuthority, kTestRootId),
+            nullptr);
+  GetRootMap()->RegisterRoot(kMediaDocumentsProviderAuthority, kTestRootId,
+                             kTestRootId, false, {});
+  EXPECT_NE(GetRootMap()->Lookup(kMediaDocumentsProviderAuthority, kTestRootId),
+            nullptr);
+}
+
+TEST_F(ArcDocumentsProviderRootMapTest, UnregisterRoot) {
+  GetRootMap()->RegisterRoot(kMediaDocumentsProviderAuthority, kTestRootId,
+                             kTestRootId, true, {});
+  EXPECT_NE(GetRootMap()->Lookup(kMediaDocumentsProviderAuthority, kTestRootId),
+            nullptr);
+  GetRootMap()->UnregisterRoot(kMediaDocumentsProviderAuthority, kTestRootId);
+  EXPECT_EQ(GetRootMap()->Lookup(kMediaDocumentsProviderAuthority, kTestRootId),
+            nullptr);
+}
+
+TEST(ArcDocumentsProviderRootMapStaticTest,
+     IsDocumentProviderRootReadOnly_FeatureEnabled) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures({chromeos::features::kFiltersInRecentsV2}, {});
+
+  EXPECT_FALSE(ArcDocumentsProviderRootMap::IsDocumentProviderRootReadOnly());
+}
+
+TEST(ArcDocumentsProviderRootMapStaticTest,
+     IsDocumentProviderRootReadOnly_FeatureDisabled) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures({}, {chromeos::features::kFiltersInRecentsV2});
+
+  EXPECT_TRUE(ArcDocumentsProviderRootMap::IsDocumentProviderRootReadOnly());
+}
+
+}  // namespace arc
diff --git a/chrome/browser/ash/borealis/borealis_task.cc b/chrome/browser/ash/borealis/borealis_task.cc
index df36723..b3b10b2 100644
--- a/chrome/browser/ash/borealis/borealis_task.cc
+++ b/chrome/browser/ash/borealis/borealis_task.cc
@@ -251,13 +251,13 @@
   if (external_disk) {
     base::ScopedFD fd(external_disk->TakePlatformFile());
     request.add_fds(vm_tools::concierge::StartVmRequest::STORAGE);
-    ash::ConciergeClient::Get()->StartTerminaVmWithFd(
+    ash::ConciergeClient::Get()->StartVmWithFd(
         std::move(fd), std::move(request),
         base::BindOnce(&StartBorealisVm::OnStartBorealisVm,
                        weak_factory_.GetWeakPtr(), context));
     return;
   }
-  ash::ConciergeClient::Get()->StartTerminaVm(
+  ash::ConciergeClient::Get()->StartVm(
       std::move(request), base::BindOnce(&StartBorealisVm::OnStartBorealisVm,
                                          weak_factory_.GetWeakPtr(), context));
 }
diff --git a/chrome/browser/ash/borealis/borealis_task_unittest.cc b/chrome/browser/ash/borealis/borealis_task_unittest.cc
index 65bce081..18ec382 100644
--- a/chrome/browser/ash/borealis/borealis_task_unittest.cc
+++ b/chrome/browser/ash/borealis/borealis_task_unittest.cc
@@ -157,7 +157,7 @@
   task.Run(context_.get(), callback_factory.BindOnce());
   task_environment_.RunUntilIdle();
 
-  EXPECT_GE(FakeConciergeClient()->start_termina_vm_call_count(), 1);
+  EXPECT_GE(FakeConciergeClient()->start_vm_call_count(), 1);
 }
 
 TEST_F(BorealisTasksTest,
@@ -173,7 +173,7 @@
   task.Run(context_.get(), callback_factory.BindOnce());
   task_environment_.RunUntilIdle();
 
-  EXPECT_GE(FakeConciergeClient()->start_termina_vm_call_count(), 1);
+  EXPECT_GE(FakeConciergeClient()->start_vm_call_count(), 1);
 }
 
 TEST_F(BorealisTasksTest,
@@ -343,7 +343,7 @@
   task.Run(context_.get(), callback_factory.BindOnce());
   task_environment_.RunUntilIdle();
 
-  EXPECT_GE(FakeConciergeClient()->start_termina_vm_call_count(), 1);
+  EXPECT_GE(FakeConciergeClient()->start_vm_call_count(), 1);
 }
 
 INSTANTIATE_TEST_SUITE_P(
diff --git a/chrome/browser/ash/crostini/crostini_installer_unittest.cc b/chrome/browser/ash/crostini/crostini_installer_unittest.cc
index 841dce80..c938284 100644
--- a/chrome/browser/ash/crostini/crostini_installer_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_installer_unittest.cc
@@ -68,11 +68,11 @@
     explicit WaitingFakeConciergeClient(ash::FakeCiceroneClient* client)
         : ash::FakeConciergeClient(client) {}
 
-    void StartTerminaVm(
+    void StartVm(
         const vm_tools::concierge::StartVmRequest& request,
         chromeos::DBusMethodCallback<vm_tools::concierge::StartVmResponse>
             callback) override {
-      ash::FakeConciergeClient::StartTerminaVm(request, std::move(callback));
+      ash::FakeConciergeClient::StartVm(request, std::move(callback));
       if (quit_closure_) {
         base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                                       std::move(quit_closure_));
@@ -83,7 +83,7 @@
       base::RunLoop loop;
       quit_closure_ = loop.QuitClosure();
       loop.Run();
-      EXPECT_GE(start_termina_vm_call_count(), 1);
+      EXPECT_GE(start_vm_call_count(), 1);
     }
 
    private:
diff --git a/chrome/browser/ash/crostini/crostini_manager.cc b/chrome/browser/ash/crostini/crostini_manager.cc
index 853ef5bd..f1a3bcb 100644
--- a/chrome/browser/ash/crostini/crostini_manager.cc
+++ b/chrome/browser/ash/crostini/crostini_manager.cc
@@ -1446,7 +1446,7 @@
   disk_image->set_writable(true);
   disk_image->set_do_mount(false);
 
-  GetConciergeClient()->StartTerminaVm(
+  GetConciergeClient()->StartVm(
       request, base::BindOnce(&CrostiniManager::OnStartTerminaVm,
                               weak_ptr_factory_.GetWeakPtr(), request.name(),
                               std::move(callback)));
diff --git a/chrome/browser/ash/crostini/crostini_manager.h b/chrome/browser/ash/crostini/crostini_manager.h
index a14d117..a09bd61 100644
--- a/chrome/browser/ash/crostini/crostini_manager.h
+++ b/chrome/browser/ash/crostini/crostini_manager.h
@@ -681,7 +681,7 @@
       ListVmDisksCallback callback,
       absl::optional<vm_tools::concierge::ListVmDisksResponse> response);
 
-  // Callback for ConciergeClient::StartTerminaVm. Called after the Concierge
+  // Callback for ConciergeClient::StartVm. Called after the Concierge
   // service method finishes.  Updates running containers list then calls the
   // |callback| if the container has already been started, otherwise passes the
   // callback to OnStartTremplin.
diff --git a/chrome/browser/ash/crostini/crostini_manager_unittest.cc b/chrome/browser/ash/crostini/crostini_manager_unittest.cc
index 26e9b99..24fb20a4 100644
--- a/chrome/browser/ash/crostini/crostini_manager_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_manager_unittest.cc
@@ -363,7 +363,7 @@
       "", disk_path, {}, 0,
       base::BindOnce(&ExpectFailure, run_loop()->QuitClosure()));
   run_loop()->Run();
-  EXPECT_EQ(fake_concierge_client_->start_termina_vm_call_count(), 0);
+  EXPECT_EQ(fake_concierge_client_->start_vm_call_count(), 0);
 }
 
 TEST_F(CrostiniManagerTest, StartTerminaVmAnomalyDetectorNotConnectedError) {
@@ -376,7 +376,7 @@
       kVmName, disk_path, {}, 0,
       base::BindOnce(&ExpectFailure, run_loop()->QuitClosure()));
   run_loop()->Run();
-  EXPECT_EQ(fake_concierge_client_->start_termina_vm_call_count(), 0);
+  EXPECT_EQ(fake_concierge_client_->start_vm_call_count(), 0);
 }
 
 TEST_F(CrostiniManagerTest, StartTerminaVmDiskPathError) {
@@ -386,7 +386,7 @@
       kVmName, disk_path, {}, 0,
       base::BindOnce(&ExpectFailure, run_loop()->QuitClosure()));
   run_loop()->Run();
-  EXPECT_EQ(fake_concierge_client_->start_termina_vm_call_count(), 0);
+  EXPECT_EQ(fake_concierge_client_->start_vm_call_count(), 0);
 }
 
 TEST_F(CrostiniManagerTest, StartTerminaVmPowerwashRequestError) {
@@ -416,7 +416,7 @@
       kVmName, disk_path, {}, 0,
       base::BindOnce(&ExpectFailure, run_loop()->QuitClosure()));
   run_loop()->Run();
-  EXPECT_EQ(fake_concierge_client_->start_termina_vm_call_count(), 0);
+  EXPECT_EQ(fake_concierge_client_->start_vm_call_count(), 0);
 
   auto notification = notification_service.GetNotification(
       "crostini_powerwash_request_instead_of_run");
@@ -453,7 +453,7 @@
       kVmName, disk_path, {}, 0,
       base::BindOnce(&ExpectFailure, run_loop()->QuitClosure()));
   run_loop()->Run();
-  EXPECT_EQ(fake_concierge_client_->start_termina_vm_call_count(), 0);
+  EXPECT_EQ(fake_concierge_client_->start_vm_call_count(), 0);
 
   auto notification = notification_service.GetNotification(
       "crostini_powerwash_request_cryptohome_error");
@@ -474,7 +474,7 @@
       kVmName, disk_path, {}, 0,
       base::BindOnce(&ExpectFailure, run_loop()->QuitClosure()));
   run_loop()->Run();
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   histogram_tester.ExpectUniqueSample(kCrostiniCorruptionHistogram,
                                       CorruptionStates::MOUNT_FAILED, 1);
 }
@@ -494,7 +494,7 @@
       kVmName, disk_path, {}, 0,
       base::BindOnce(&ExpectSuccess, run_loop()->QuitClosure()));
   run_loop()->Run();
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   histogram_tester.ExpectUniqueSample(kCrostiniCorruptionHistogram,
                                       CorruptionStates::MOUNT_ROLLED_BACK, 1);
 }
@@ -508,7 +508,7 @@
       kVmName, disk_path, {}, 0,
       base::BindOnce(&ExpectSuccess, run_loop()->QuitClosure()));
   run_loop()->Run();
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   histogram_tester.ExpectTotalCount(kCrostiniCorruptionHistogram, 0);
 }
 
@@ -528,7 +528,7 @@
       base::BindOnce(&ExpectSuccess, run_loop()->QuitClosure()));
   run_loop()->Run();
 
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   auto notification = notification_service.GetNotification("crostini_low_disk");
   EXPECT_NE(absl::nullopt, notification);
 }
@@ -550,7 +550,7 @@
       base::BindOnce(&ExpectSuccess, run_loop()->QuitClosure()));
   run_loop()->Run();
 
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   auto notification = notification_service.GetNotification("crostini_low_disk");
   EXPECT_EQ(absl::nullopt, notification);
 }
@@ -818,7 +818,7 @@
       this);
   run_loop()->Run();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   EXPECT_EQ(1, restart_crostini_callback_count_);
 
   absl::optional<ContainerInfo> container_info =
@@ -857,7 +857,7 @@
       this);
   run_loop()->Run();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   EXPECT_EQ(1, restart_crostini_callback_count_);
 
   absl::optional<ContainerInfo> container_info =
@@ -886,7 +886,7 @@
       this);
   run_loop()->Run();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   EXPECT_EQ(1, restart_crostini_callback_count_);
 
   absl::optional<ContainerInfo> container_info =
@@ -906,7 +906,7 @@
       this);
   run_loop()->Run();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   EXPECT_EQ(1, restart_crostini_callback_count_);
 
   absl::optional<ContainerInfo> container_info =
@@ -926,7 +926,7 @@
   EXPECT_FALSE(
       profile_->GetPrefs()->GetBoolean(crostini::prefs::kCrostiniEnabled));
   EXPECT_EQ(fake_concierge_client_->create_disk_image_call_count(), 0);
-  EXPECT_EQ(fake_concierge_client_->start_termina_vm_call_count(), 0);
+  EXPECT_EQ(fake_concierge_client_->start_vm_call_count(), 0);
   ExpectCrostiniRestartResult(CrostiniResult::RESTART_ABORTED);
   ExpectRestarterUmaCount(1);
 }
@@ -958,7 +958,7 @@
       this);
   run_loop()->Run();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_EQ(fake_concierge_client_->start_termina_vm_call_count(), 0);
+  EXPECT_EQ(fake_concierge_client_->start_vm_call_count(), 0);
   ExpectCrostiniRestartResult(CrostiniResult::RESTART_ABORTED);
   ExpectRestarterUmaCount(1);
   histogram_tester_.ExpectTotalCount(
@@ -980,7 +980,7 @@
   task_environment_.FastForwardBy(kLongTime);
   task_environment_.RunUntilIdle();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_EQ(fake_concierge_client_->start_termina_vm_call_count(), 0);
+  EXPECT_EQ(fake_concierge_client_->start_vm_call_count(), 0);
   ExpectCrostiniRestartResult(CrostiniResult::CREATE_DISK_IMAGE_TIMED_OUT);
   ExpectRestarterUmaCount(1);
 }
@@ -1012,7 +1012,7 @@
       this);
   run_loop()->Run();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   ExpectCrostiniRestartResult(CrostiniResult::RESTART_ABORTED);
   ExpectRestarterUmaCount(1);
 }
@@ -1028,7 +1028,7 @@
   task_environment_.FastForwardBy(kLongTime);
   task_environment_.RunUntilIdle();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   ExpectCrostiniRestartResult(CrostiniResult::START_TERMINA_VM_TIMED_OUT);
   ExpectRestarterUmaCount(1);
 }
@@ -1047,7 +1047,7 @@
   task_environment_.FastForwardBy(kLongTime);
   task_environment_.RunUntilIdle();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   ExpectCrostiniRestartResult(CrostiniResult::START_TERMINA_VM_TIMED_OUT);
   ExpectRestarterUmaCount(1);
 }
@@ -1061,7 +1061,7 @@
       this);
   run_loop()->Run();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   ExpectCrostiniRestartResult(CrostiniResult::RESTART_ABORTED);
   ExpectRestarterUmaCount(1);
 }
@@ -1077,7 +1077,7 @@
   task_environment_.FastForwardBy(kLongTime);
   task_environment_.RunUntilIdle();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   ExpectCrostiniRestartResult(CrostiniResult::START_LXD_TIMED_OUT);
   ExpectRestarterUmaCount(1);
 }
@@ -1094,7 +1094,7 @@
   task_environment_.FastForwardBy(kLongTime);
   task_environment_.RunUntilIdle();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   ExpectCrostiniRestartResult(CrostiniResult::START_LXD_TIMED_OUT);
   ExpectRestarterUmaCount(1);
 }
@@ -1108,7 +1108,7 @@
       this);
   run_loop()->Run();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   ExpectCrostiniRestartResult(CrostiniResult::RESTART_ABORTED);
   ExpectRestarterUmaCount(1);
 }
@@ -1138,7 +1138,7 @@
   task_environment_.FastForwardBy(kLongTime);
   task_environment_.RunUntilIdle();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   ExpectCrostiniRestartResult(CrostiniResult::CREATE_CONTAINER_TIMED_OUT);
   ExpectRestarterUmaCount(1);
 }
@@ -1166,7 +1166,7 @@
   ASSERT_EQ(1, restart_crostini_callback_count_);
 
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   ExpectCrostiniRestartResult(CrostiniResult::CREATE_CONTAINER_TIMED_OUT);
   ExpectRestarterUmaCount(1);
 }
@@ -1183,7 +1183,7 @@
   run_loop()->Run();
 
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   EXPECT_EQ(0, restart_crostini_callback_count_);
   ExpectRestarterUmaCount(1);
 }
@@ -1197,7 +1197,7 @@
       this);
   run_loop()->Run();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   ExpectCrostiniRestartResult(CrostiniResult::RESTART_ABORTED);
   ExpectRestarterUmaCount(1);
 }
@@ -1211,7 +1211,7 @@
       this);
   run_loop()->Run();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   ExpectCrostiniRestartResult(CrostiniResult::RESTART_ABORTED);
   ExpectRestarterUmaCount(1);
 }
@@ -1227,7 +1227,7 @@
   task_environment_.FastForwardBy(kLongTime);
   task_environment_.RunUntilIdle();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   ExpectCrostiniRestartResult(CrostiniResult::SETUP_CONTAINER_TIMED_OUT);
   ExpectRestarterUmaCount(1);
 }
@@ -1257,7 +1257,7 @@
   task_environment_.FastForwardBy(kLongTime);
   task_environment_.RunUntilIdle();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   ExpectCrostiniRestartResult(CrostiniResult::START_CONTAINER_TIMED_OUT);
   ExpectRestarterUmaCount(1);
 }
@@ -1287,7 +1287,7 @@
   ASSERT_EQ(1, restart_crostini_callback_count_);
 
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   ExpectCrostiniRestartResult(CrostiniResult::START_CONTAINER_TIMED_OUT);
   ExpectRestarterUmaCount(1);
 }
@@ -1301,7 +1301,7 @@
       this);
   run_loop()->Run();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   ExpectCrostiniRestartResult(CrostiniResult::RESTART_ABORTED);
   ExpectRestarterUmaCount(1);
 }
@@ -1356,7 +1356,7 @@
 
   run_loop()->Run();
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   EXPECT_EQ(3, restart_crostini_callback_count_);
 
   EXPECT_FALSE(crostini_manager()->IsRestartPending(id1));
@@ -1386,7 +1386,7 @@
 
   run_loop()->Run();
 
-  EXPECT_EQ(1, fake_concierge_client_->start_termina_vm_call_count());
+  EXPECT_EQ(1, fake_concierge_client_->start_vm_call_count());
   EXPECT_FALSE(crostini_manager()->IsRestartPending(id1));
   EXPECT_FALSE(crostini_manager()->IsRestartPending(id2));
   EXPECT_FALSE(crostini_manager()->IsRestartPending(id3));
@@ -1402,7 +1402,7 @@
   run_loop()->Run();
 
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   // Mount only performed for termina/penguin.
   EXPECT_EQ(1, restart_crostini_callback_count_);
 
@@ -1418,7 +1418,7 @@
       kVmName, disk_path, {}, 0,
       base::BindOnce(&ExpectSuccess, run_loop2.QuitClosure()));
   run_loop2.Run();
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   EXPECT_TRUE(crostini_manager()->IsVmRunning(kVmName));
   EXPECT_FALSE(crostini_manager()->GetContainerInfo(container_id()));
   ExpectRestarterUmaCount(1);
@@ -1881,7 +1881,7 @@
   run_loop()->Run();
 
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   EXPECT_TRUE(
       fake_concierge_client_->get_vm_enterprise_reporting_info_call_count());
   EXPECT_EQ(1, restart_crostini_callback_count_);
@@ -1907,7 +1907,7 @@
   run_loop()->Run();
 
   EXPECT_GE(fake_concierge_client_->create_disk_image_call_count(), 1);
-  EXPECT_GE(fake_concierge_client_->start_termina_vm_call_count(), 1);
+  EXPECT_GE(fake_concierge_client_->start_vm_call_count(), 1);
   EXPECT_TRUE(
       fake_concierge_client_->get_vm_enterprise_reporting_info_call_count());
   EXPECT_EQ(1, restart_crostini_callback_count_);
diff --git a/chrome/browser/ash/file_manager/delete_io_task.cc b/chrome/browser/ash/file_manager/delete_io_task.cc
index 65f1f69..af5d4b31 100644
--- a/chrome/browser/ash/file_manager/delete_io_task.cc
+++ b/chrome/browser/ash/file_manager/delete_io_task.cc
@@ -9,6 +9,7 @@
 #include "base/callback.h"
 #include "base/files/file.h"
 #include "base/threading/sequenced_task_runner_handle.h"
+#include "chrome/browser/ash/file_manager/io_task_util.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "google_apis/common/task_util.h"
@@ -18,20 +19,6 @@
 namespace file_manager {
 namespace io_task {
 
-namespace {
-
-// Starts the delete operation via FileSystemOperationRunner.
-storage::FileSystemOperationRunner::OperationID StartDeleteOnIOThread(
-    scoped_refptr<storage::FileSystemContext> file_system_context,
-    const storage::FileSystemURL& file_url,
-    storage::FileSystemOperation::StatusCallback status_callback) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-  return file_system_context->operation_runner()->Remove(
-      file_url, /*recursive=*/true, std::move(status_callback));
-}
-
-}  // namespace
-
 DeleteIOTask::DeleteIOTask(
     std::vector<storage::FileSystemURL> file_urls,
     scoped_refptr<storage::FileSystemContext> file_system_context)
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
index 2a62f15c..5950058 100644
--- a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
+++ b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
@@ -3003,6 +3003,11 @@
     return;
   }
 
+  if (name == "isFiltersInRecentsEnabledV2") {
+    *output = options.enable_filters_in_recents_v2 ? "true" : "false";
+    return;
+  }
+
   if (name == "switchLanguage") {
     const std::string* language = value.FindStringKey("language");
     ASSERT_TRUE(language);
diff --git a/chrome/browser/ash/file_manager/file_manager_jstest.cc b/chrome/browser/ash/file_manager/file_manager_jstest.cc
index 260742d1..2394711 100644
--- a/chrome/browser/ash/file_manager/file_manager_jstest.cc
+++ b/chrome/browser/ash/file_manager/file_manager_jstest.cc
@@ -69,6 +69,10 @@
   RunTestURL("foreground/js/directory_contents_unittest.m_gen.html");
 }
 
+IN_PROC_BROWSER_TEST_F(FileManagerJsTest, DirectoryModelTest) {
+  RunTestURL("foreground/js/directory_model_unittest.m_gen.html");
+}
+
 IN_PROC_BROWSER_TEST_F(FileManagerJsTest, DirectoryTreeTest) {
   RunTestURL("foreground/js/ui/directory_tree_unittest.m_gen.html");
 }
diff --git a/chrome/browser/ash/file_manager/io_task_util.cc b/chrome/browser/ash/file_manager/io_task_util.cc
index 6b18599..00df4b8 100644
--- a/chrome/browser/ash/file_manager/io_task_util.cc
+++ b/chrome/browser/ash/file_manager/io_task_util.cc
@@ -37,5 +37,14 @@
                                                        std::move(callback));
 }
 
+storage::FileSystemOperationRunner::OperationID StartDeleteOnIOThread(
+    scoped_refptr<storage::FileSystemContext> file_system_context,
+    const storage::FileSystemURL& file_url,
+    storage::FileSystemOperation::StatusCallback status_callback) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  return file_system_context->operation_runner()->Remove(
+      file_url, /*recursive=*/true, std::move(status_callback));
+}
+
 }  // namespace io_task
 }  // namespace file_manager
diff --git a/chrome/browser/ash/file_manager/io_task_util.h b/chrome/browser/ash/file_manager/io_task_util.h
index 93293ce2..36c113d 100644
--- a/chrome/browser/ash/file_manager/io_task_util.h
+++ b/chrome/browser/ash/file_manager/io_task_util.h
@@ -31,6 +31,12 @@
     int fields,
     storage::FileSystemOperation::GetMetadataCallback callback);
 
+// Starts the delete operation via FileSystemOperationRunner.
+storage::FileSystemOperationRunner::OperationID StartDeleteOnIOThread(
+    scoped_refptr<storage::FileSystemContext> file_system_context,
+    const storage::FileSystemURL& file_url,
+    storage::FileSystemOperation::StatusCallback status_callback);
+
 }  // namespace io_task
 }  // namespace file_manager
 
diff --git a/chrome/browser/ash/file_manager/trash_io_task.cc b/chrome/browser/ash/file_manager/trash_io_task.cc
index 69f02ac7..4bec5fa 100644
--- a/chrome/browser/ash/file_manager/trash_io_task.cc
+++ b/chrome/browser/ash/file_manager/trash_io_task.cc
@@ -393,22 +393,81 @@
     return;
   }
 
-  // TODO(b/231250202): Move the file to trash but on error remove the metadata
-  // file.
-  TrashComplete(source_idx, output_idx, base::File::Error::FILE_OK);
+  last_metadata_url_ = progress_.outputs[output_idx].url;
+  progress_.outputs[output_idx].error = base::File::FILE_OK;
+  TrashFile(source_idx, output_idx, destination_url);
+}
+
+void TrashIOTask::TrashFile(size_t source_idx,
+                            size_t output_idx,
+                            const storage::FileSystemURL& destination_url) {
+  DCHECK(source_idx < progress_.sources.size());
+  DCHECK(output_idx < progress_.outputs.size());
+  progress_.outputs.emplace_back(destination_url, absl::nullopt);
+
+  last_progress_size_ = 0;
+
+  const storage::FileSystemURL& source_url = progress_.sources[source_idx].url;
+
+  // File browsers generally default to preserving mtimes on copy/move so we
+  // should do the same.
+  storage::FileSystemOperation::CopyOrMoveOptionSet options(
+      storage::FileSystemOperation::CopyOrMoveOption::kPreserveLastModified,
+      storage::FileSystemOperation::CopyOrMoveOption::
+          kRemovePartiallyCopiedFilesOnError);
+
+  auto complete_callback =
+      base::BindPostTask(base::SequencedTaskRunnerHandle::Get(),
+                         base::BindOnce(&TrashIOTask::TrashComplete,
+                                        weak_ptr_factory_.GetWeakPtr(),
+                                        source_idx, output_idx + 1));
+
+  // For move operations that occur on the same file system, the progress
+  // callback is never invoked.
+  content::GetIOThreadTaskRunner({})->PostTaskAndReplyWithResult(
+      FROM_HERE,
+      base::BindOnce(&StartMoveOnIOThread, file_system_context_, source_url,
+                     destination_url, options, base::DoNothing(),
+                     std::move(complete_callback)),
+      base::BindOnce(&TrashIOTask::SetCurrentOperationID,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+void TrashIOTask::OnMoveComplete(size_t source_idx,
+                                 size_t output_idx,
+                                 base::File::Error error) {
+  DCHECK(source_idx < progress_.sources.size());
+  DCHECK(output_idx < progress_.outputs.size());
+  if (error != base::File::FILE_OK) {
+    LOG(ERROR) << "Failed to move the file to trash folder: " << error;
+    auto complete_callback = base::BindPostTask(
+        base::SequencedTaskRunnerHandle::Get(),
+        base::BindOnce(&TrashIOTask::TrashComplete,
+                       weak_ptr_factory_.GetWeakPtr(), source_idx, output_idx));
+
+    content::GetIOThreadTaskRunner({})->PostTaskAndReplyWithResult(
+        FROM_HERE,
+        base::BindOnce(&StartDeleteOnIOThread, file_system_context_,
+                       last_metadata_url_, std::move(complete_callback)),
+        base::BindOnce(&TrashIOTask::SetCurrentOperationID,
+                       weak_ptr_factory_.GetWeakPtr()));
+    return;
+  }
+
+  TrashComplete(source_idx, output_idx, error);
 }
 
 void TrashIOTask::TrashComplete(size_t source_idx,
                                 size_t output_idx,
                                 base::File::Error error) {
   DCHECK(source_idx < progress_.sources.size());
-  DCHECK(source_idx < trash_entries_.size());
   DCHECK(output_idx < progress_.outputs.size());
   operation_id_.reset();
   progress_.sources[source_idx].error = error;
   progress_.outputs[output_idx].error = error;
   progress_.bytes_transferred +=
-      trash_entries_[source_idx].trash_info_contents.size();
+      trash_entries_[source_idx].trash_info_contents.size() +
+      (trash_entries_[source_idx].source_file_size - last_progress_size_);
 
   if (source_idx < progress_.sources.size() - 1) {
     progress_callback_.Run(progress_);
diff --git a/chrome/browser/ash/file_manager/trash_io_task.h b/chrome/browser/ash/file_manager/trash_io_task.h
index d7c1eee..1ec8a1b 100644
--- a/chrome/browser/ash/file_manager/trash_io_task.h
+++ b/chrome/browser/ash/file_manager/trash_io_task.h
@@ -12,7 +12,9 @@
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
+#include "chrome/browser/ash/file_manager/file_manager_copy_or_move_hook_delegate.h"
 #include "chrome/browser/ash/file_manager/io_task.h"
+#include "chrome/browser/ash/file_manager/speedometer.h"
 #include "storage/browser/file_system/file_system_context.h"
 #include "storage/browser/file_system/file_system_operation_runner.h"
 #include "storage/browser/file_system/file_system_url.h"
@@ -163,6 +165,14 @@
   void TrashComplete(size_t source_idx,
                      size_t output_idx,
                      base::File::Error error);
+  // Move a file from it's location to the final .Trash/files destination with
+  // a unique name determined by `GenerateDestinationURL`.
+  void TrashFile(size_t source_idx,
+                 size_t output_idx,
+                 const storage::FileSystemURL& destination_url);
+  void OnMoveComplete(size_t source_idx,
+                      size_t output_idx,
+                      base::File::Error error);
 
   raw_ptr<Profile> profile_;
 
@@ -176,6 +186,18 @@
   // with the underlying locations of the .Trash/{files,info} directories.
   FreeSpaceMap free_space_map_;
 
+  // Stores the size reported by the last progress update so we can compute the
+  // delta on the next progress update.
+  int64_t last_progress_size_;
+
+  // Stores the last url for the most recently updated metadata file, in the
+  // event of a move failure this file is removed.
+  storage::FileSystemURL last_metadata_url_;
+
+  // Speedometer for this operation, used to calculate the remaining time to
+  // finish the operation.
+  Speedometer speedometer_;
+
   // Stores the id of the operations currently behind undertaken by Trash,
   // including directory creation. Enables cancelling an inflight operation.
   absl::optional<storage::FileSystemOperationRunner::OperationID> operation_id_;
diff --git a/chrome/browser/ash/file_manager/trash_io_task_unittest.cc b/chrome/browser/ash/file_manager/trash_io_task_unittest.cc
index adef0f6..2f91102 100644
--- a/chrome/browser/ash/file_manager/trash_io_task_unittest.cc
+++ b/chrome/browser/ash/file_manager/trash_io_task_unittest.cc
@@ -32,6 +32,7 @@
 
 using ::base::test::RunClosure;
 using ::testing::_;
+using ::testing::AnyNumber;
 using ::testing::ElementsAre;
 using ::testing::Field;
 using ::testing::Return;
@@ -107,6 +108,11 @@
                              kInfoFolderName, file_name);
   }
 
+  const base::FilePath GenerateFilesPath(const std::string& file_name) {
+    return GenerateTrashPath(downloads_dir_.Append(kTrashFolderName),
+                             kFilesFolderName, file_name);
+  }
+
   const std::string CreateTrashInfoContentsFromPath(
       const base::FilePath& file_path) {
     std::string relative_restore_path = file_path.value();
@@ -271,17 +277,15 @@
   // Completion callback should contain the one metadata file written with the
   // `total_expected_bytes` containing the size of both the file to trash and
   // the size of the metadata.
-  // TODO(b/231250202): Once trash has implemented, the `bytes_transferred`
-  // should be updated to the `total_expected_bytes`.
   EXPECT_CALL(
       complete_callback,
       Run(AllOf(Field(&ProgressStatus::state, State::kSuccess),
-                Field(&ProgressStatus::bytes_transferred,
-                      file_trashinfo_contents.size()),
+                Field(&ProgressStatus::bytes_transferred, total_expected_bytes),
                 Field(&ProgressStatus::total_bytes, total_expected_bytes),
                 Field(&ProgressStatus::sources, EntryStatusUrls(source_urls)),
                 Field(&ProgressStatus::outputs,
-                      EntryStatusErrors(ElementsAre(base::File::FILE_OK))))))
+                      EntryStatusErrors(ElementsAre(base::File::FILE_OK,
+                                                    base::File::FILE_OK))))))
       .WillOnce(RunClosure(run_loop.QuitClosure()));
 
   {
@@ -297,6 +301,7 @@
 
   AssertTrashSetup(downloads_dir_);
   ExpectFileContents(GenerateInfoPath(file_name), file_trashinfo_contents);
+  ExpectFileContents(GenerateFilesPath(file_name), foo_contents);
 }
 
 TEST_F(TrashIOTaskTest, MultipleFilesInvokeProgress) {
@@ -309,10 +314,9 @@
   const base::FilePath file_path_2 = downloads_dir_.Append(file_name_2);
   const std::string file_trashinfo_contents_2 =
       CreateTrashInfoContentsFromPath(file_path_2);
-  const size_t expected_bytes_transferred =
-      file_trashinfo_contents_1.size() + file_trashinfo_contents_2.size();
-  const size_t expected_total_bytes =
-      (kTestFileSize * 2) + expected_bytes_transferred;
+  const size_t expected_total_bytes = (kTestFileSize * 2) +
+                                      file_trashinfo_contents_1.size() +
+                                      file_trashinfo_contents_2.size();
   ASSERT_TRUE(base::WriteFile(file_path_1, foo_contents));
   ASSERT_TRUE(base::WriteFile(file_path_2, foo_contents));
 
@@ -331,28 +335,38 @@
       AllOf(Field(&ProgressStatus::sources, EntryStatusUrls(source_urls)),
             Field(&ProgressStatus::total_bytes, expected_total_bytes));
 
-  // Expect the `progress_callback` to be invoked after the first metadata file
-  // has been written with the size contents and
-  EXPECT_CALL(
-      progress_callback,
-      Run(AllOf(Field(&ProgressStatus::state, State::kInProgress),
-                Field(&ProgressStatus::bytes_transferred,
-                      file_trashinfo_contents_1.size()),
-                Field(&ProgressStatus::outputs,
-                      EntryStatusErrors(ElementsAre(base::File::FILE_OK))),
-                base_matcher)))
-      .Times(1);
+  // Progress callback may be called any number of times, so this expectation
+  // catches extra calls.
+  EXPECT_CALL(progress_callback,
+              Run(AllOf(Field(&ProgressStatus::state, State::kInProgress),
+                        base_matcher)))
+      .Times(AnyNumber());
 
-  // Expect the completion callback to be invoked after the final metadata file
-  // is written out.
-  EXPECT_CALL(complete_callback,
-              Run(AllOf(Field(&ProgressStatus::state, State::kSuccess),
+  // Expect the `progress_callback` to be invoked after the first metadata and
+  // trash file have been written and moved with their size in the
+  // `bytes_transferred`.
+  EXPECT_CALL(progress_callback,
+              Run(AllOf(Field(&ProgressStatus::state, State::kInProgress),
                         Field(&ProgressStatus::bytes_transferred,
-                              expected_bytes_transferred),
+                              file_trashinfo_contents_1.size() + kTestFileSize),
                         Field(&ProgressStatus::outputs,
                               EntryStatusErrors(ElementsAre(
                                   base::File::FILE_OK, base::File::FILE_OK))),
                         base_matcher)))
+      .Times(1);
+
+  // Completion callback should contain 4 files successfully being written. Each
+  // `base::File::FILE_OK` in the outputs field corresponds to a successful
+  // write or move of the file and associated metadata.
+  EXPECT_CALL(
+      complete_callback,
+      Run(AllOf(Field(&ProgressStatus::state, State::kSuccess),
+                Field(&ProgressStatus::bytes_transferred, expected_total_bytes),
+                Field(&ProgressStatus::outputs,
+                      EntryStatusErrors(ElementsAre(
+                          base::File::FILE_OK, base::File::FILE_OK,
+                          base::File::FILE_OK, base::File::FILE_OK))),
+                base_matcher)))
       .WillOnce(RunClosure(run_loop.QuitClosure()));
 
   {
@@ -367,6 +381,8 @@
   AssertTrashSetup(downloads_dir_);
   ExpectFileContents(GenerateInfoPath(file_name_1), file_trashinfo_contents_1);
   ExpectFileContents(GenerateInfoPath(file_name_2), file_trashinfo_contents_2);
+  ExpectFileContents(GenerateFilesPath(file_name_1), foo_contents);
+  ExpectFileContents(GenerateFilesPath(file_name_2), foo_contents);
 }
 
 }  // namespace
diff --git a/chrome/browser/ash/file_manager/volume_manager.cc b/chrome/browser/ash/file_manager/volume_manager.cc
index bff46fdb..922bb7cb 100644
--- a/chrome/browser/ash/file_manager/volume_manager.cc
+++ b/chrome/browser/ash/file_manager/volume_manager.cc
@@ -416,7 +416,8 @@
       arc::kMediaDocumentsProviderAuthority, root_document_id);
   volume->mount_condition_ = ash::disks::MOUNT_CONDITION_NONE;
   volume->volume_label_ = MediaViewDocumentIdToLabel(root_document_id);
-  volume->is_read_only_ = true;
+  volume->is_read_only_ =
+      arc::ArcDocumentsProviderRootMap::IsDocumentProviderRootReadOnly();
   volume->watchable_ = false;
   volume->volume_id_ = arc::GetMediaViewVolumeId(root_document_id);
   return volume;
diff --git a/chrome/browser/ash/input_method/native_input_method_engine_unittest.cc b/chrome/browser/ash/input_method/native_input_method_engine_unittest.cc
index 7a93911..4886d75 100644
--- a/chrome/browser/ash/input_method/native_input_method_engine_unittest.cc
+++ b/chrome/browser/ash/input_method/native_input_method_engine_unittest.cc
@@ -740,7 +740,7 @@
 
     // Each character in "你好" is three UTF-8 code units.
     EXPECT_CALL(mock_input_method,
-                OnSurroundingTextChanged(u8"你好",
+                OnSurroundingTextChanged("你好",
                                          /*offset=*/0,
                                          MojoEq(ime::mojom::SelectionRange(
                                              /*anchor=*/6, /*focus=*/6))));
diff --git a/chrome/browser/ash/login/enrollment/auto_enrollment_controller.cc b/chrome/browser/ash/login/enrollment/auto_enrollment_controller.cc
index c1e2fa5f..54e99a1 100644
--- a/chrome/browser/ash/login/enrollment/auto_enrollment_controller.cc
+++ b/chrome/browser/ash/login/enrollment/auto_enrollment_controller.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/ash/login/enrollment/auto_enrollment_controller.h"
 
+#include <memory>
+
 #include "ash/components/tpm/install_attributes.h"
 #include "ash/constants/ash_switches.h"
 #include "base/bind.h"
@@ -20,6 +22,7 @@
 #include "chrome/browser/ash/policy/enrollment/private_membership/fake_private_membership_rlwe_client.h"
 #include "chrome/browser/ash/policy/enrollment/private_membership/private_membership_rlwe_client.h"
 #include "chrome/browser/ash/policy/enrollment/private_membership/private_membership_rlwe_client_impl.h"
+#include "chrome/browser/ash/policy/enrollment/private_membership/psm_rlwe_dmserver_client_impl.h"
 #include "chrome/browser/ash/policy/enrollment/private_membership/psm_rlwe_id_provider_impl.h"
 #include "chrome/browser/ash/policy/server_backed_state/server_backed_state_keys_broker.h"
 #include "chrome/browser/ash/settings/device_settings_service.h"
@@ -422,7 +425,11 @@
       g_browser_process->system_network_context_manager()
           ->GetSharedURLLoaderFactory(),
       serial_number, rlz_brand_code, power_initial, power_limit,
-      psm_rlwe_client_factory_.get(), &psm_rlwe_id_provider_);
+      std::make_unique<policy::PsmRlweDmserverClientImpl>(
+          service,
+          g_browser_process->system_network_context_manager()
+              ->GetSharedURLLoaderFactory(),
+          psm_rlwe_client_factory_.get(), &psm_rlwe_id_provider_));
 
   LOG(WARNING) << "Starting auto-enrollment client for Initial Enrollment.";
   client_->Start();
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 94800f2..441d59f 100644
--- a/chrome/browser/ash/login/login_ui_shelf_visibility_browsertest.cc
+++ b/chrome/browser/ash/login/login_ui_shelf_visibility_browsertest.cc
@@ -15,11 +15,14 @@
 #include "chrome/browser/ash/login/test/oobe_screen_waiter.h"
 #include "chrome/browser/ash/login/ui/login_display_host.h"
 #include "chrome/browser/ash/login/wizard_controller.h"
+#include "chrome/browser/ash/policy/core/device_policy_cros_browser_test.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
 #include "chrome/browser/ui/webui/chromeos/login/os_install_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/sync_consent_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/user_creation_screen_handler.h"
+#include "components/policy/proto/device_management_backend.pb.h"
 #include "content/public/test/browser_test.h"
 #include "net/dns/mock_host_resolver.h"
 
@@ -179,4 +182,70 @@
   EXPECT_TRUE(LoginScreenTestApi::IsGuestButtonShown());
 }
 
+namespace {
+
+// This is the constant that exists on the server side. It corresponds to
+// the type of enrollment license.
+constexpr char kKioskSkuName[] = "GOOGLE.CHROME_KIOSK_ANNUAL";
+
+}  // namespace
+
+class KioskSkuVisibilityTest : public LoginUIShelfVisibilityTest {
+ public:
+  KioskSkuVisibilityTest() {
+    device_state_.set_skip_initial_policy_setup(true);
+  }
+  ~KioskSkuVisibilityTest() override = default;
+  KioskSkuVisibilityTest(const KioskSkuVisibilityTest&) = delete;
+  void operator=(const KioskSkuVisibilityTest&) = delete;
+
+ protected:
+  policy::DevicePolicyCrosTestHelper* policy_helper() {
+    return &policy_helper_;
+  }
+
+ private:
+  ash::DeviceStateMixin device_state_{
+      &mixin_host_,
+      ash::DeviceStateMixin::State::OOBE_COMPLETED_CLOUD_ENROLLED};
+  policy::DevicePolicyCrosTestHelper policy_helper_;
+};
+
+// Verifies that shelf buttons of Guest mode and Add user are shown, and kiosk
+// instruction bubble is hidden without kiosk SKU.
+IN_PROC_BROWSER_TEST_F(KioskSkuVisibilityTest, WithoutKioskSku) {
+  EXPECT_TRUE(LoginScreenTestApi::IsLoginShelfShown());
+  EXPECT_TRUE(LoginScreenTestApi::IsGuestButtonShown());
+  EXPECT_TRUE(LoginScreenTestApi::IsAddUserButtonShown());
+  EXPECT_FALSE(LoginScreenTestApi::IsKioskInstructionBubbleShown());
+}
+
+// Verifies that shelf buttons of Guest mode and Add user are hidden, and kiosk
+// instruction bubble is hidden too without kiosk apps.
+IN_PROC_BROWSER_TEST_F(KioskSkuVisibilityTest, WithoutApps) {
+  policy_helper()->device_policy()->policy_data().set_license_sku(
+      kKioskSkuName);
+  policy_helper()->RefreshPolicyAndWaitUntilDeviceCloudPolicyUpdated();
+
+  EXPECT_TRUE(LoginScreenTestApi::IsLoginShelfShown());
+  EXPECT_FALSE(LoginScreenTestApi::IsGuestButtonShown());
+  EXPECT_FALSE(LoginScreenTestApi::IsAddUserButtonShown());
+  EXPECT_FALSE(LoginScreenTestApi::IsKioskInstructionBubbleShown());
+}
+
+// Verifies that shelf buttons of Guest mode and Add user are hidden, and kiosk
+// instruction bubble is shown with kiosk apps.
+IN_PROC_BROWSER_TEST_F(KioskSkuVisibilityTest, WithApps) {
+  policy_helper()->device_policy()->policy_data().set_license_sku(
+      kKioskSkuName);
+  KioskAppsMixin::AppendKioskAccount(
+      &policy_helper()->device_policy()->payload());
+  policy_helper()->RefreshPolicyAndWaitUntilDeviceCloudPolicyUpdated();
+
+  EXPECT_TRUE(LoginScreenTestApi::IsLoginShelfShown());
+  EXPECT_FALSE(LoginScreenTestApi::IsGuestButtonShown());
+  EXPECT_FALSE(LoginScreenTestApi::IsAddUserButtonShown());
+  EXPECT_TRUE(LoginScreenTestApi::IsKioskInstructionBubbleShown());
+}
+
 }  // namespace ash
diff --git a/chrome/browser/ash/login/saml/saml_browsertest.cc b/chrome/browser/ash/login/saml/saml_browsertest.cc
index 3197c33..6e9083d 100644
--- a/chrome/browser/ash/login/saml/saml_browsertest.cc
+++ b/chrome/browser/ash/login/saml/saml_browsertest.cc
@@ -735,14 +735,7 @@
                                      1);
 }
 
-// Tests the no password scraped flow.
-// TODO(crbug.com/1315447): Disabled for debug builds.
-#if !defined(NDEBUG)
-#define MAYBE_ScrapedNone DISABLED_ScrapedNone
-#else
-#define MAYBE_ScrapedNone ScrapedNone
-#endif
-IN_PROC_BROWSER_TEST_P(SamlTestWithFeatures, MAYBE_ScrapedNone) {
+IN_PROC_BROWSER_TEST_P(SamlTestWithFeatures, ScrapedNone) {
   base::HistogramTester histogram_tester;
   fake_saml_idp()->SetLoginHTMLTemplate("saml_login_no_passwords.html");
 
@@ -833,15 +826,7 @@
   WaitForSigninScreen();
 }
 
-// Tests the password confirm flow when more than one password is scraped: show
-// error on the first failure and fatal error on the second failure.
-// TODO(crbug.com/1315447): Disabled for debug builds.
-#if !defined(NDEBUG)
-#define MAYBE_PasswordConfirmFlow DISABLED_PasswordConfirmFlow
-#else
-#define MAYBE_PasswordConfirmFlow PasswordConfirmFlow
-#endif
-IN_PROC_BROWSER_TEST_P(SamlTestWithFeatures, MAYBE_PasswordConfirmFlow) {
+IN_PROC_BROWSER_TEST_P(SamlTestWithFeatures, PasswordConfirmFlow) {
   base::HistogramTester histogram_tester;
   fake_saml_idp()->SetLoginHTMLTemplate("saml_login_two_passwords.html");
   StartSamlAndWaitForIdpPageLoad(
diff --git a/chrome/browser/ash/policy/core/browser_policy_connector_ash_browsertest.cc b/chrome/browser/ash/policy/core/browser_policy_connector_ash_browsertest.cc
index 06f3032..f99b0f02 100644
--- a/chrome/browser/ash/policy/core/browser_policy_connector_ash_browsertest.cc
+++ b/chrome/browser/ash/policy/core/browser_policy_connector_ash_browsertest.cc
@@ -24,23 +24,6 @@
 const char kMachineName[] = "machine_name";
 const char kCustomManager[] = "user@acme.corp";
 
-void WaitUntilPolicyLoaded() {
-  BrowserPolicyConnectorAsh* connector =
-      g_browser_process->platform_part()->browser_policy_connector_ash();
-  DeviceCloudPolicyStoreAsh* store =
-      connector->GetDeviceCloudPolicyManager()->device_store();
-  if (!store->has_policy()) {
-    MockCloudPolicyStoreObserver observer;
-    base::RunLoop loop;
-    store->AddObserver(&observer);
-    EXPECT_CALL(observer, OnStoreLoaded(store))
-        .Times(1)
-        .WillOnce(InvokeWithoutArgs(&loop, &base::RunLoop::Quit));
-    loop.Run();
-    store->RemoveObserver(&observer);
-  }
-}
-
 class BrowserPolicyConnectorAshTest : public DevicePolicyCrosBrowserTest {
  public:
   BrowserPolicyConnectorAshTest() {
@@ -70,8 +53,7 @@
   BrowserPolicyConnectorAsh* connector =
       g_browser_process->platform_part()->browser_policy_connector_ash();
   device_policy()->policy_data().set_display_domain(kCustomDisplayDomain);
-  RefreshDevicePolicy();
-  WaitUntilPolicyLoaded();
+  policy_helper()->RefreshPolicyAndWaitUntilDeviceCloudPolicyUpdated();
   // At this point display domain is set and policy is loaded so expect to see
   /// the display domain.
   EXPECT_EQ(kCustomDisplayDomain, connector->GetEnterpriseDomainManager());
@@ -89,8 +71,7 @@
   device_policy()->policy_data().set_display_domain(kCustomDisplayDomain);
   device_policy()->policy_data().set_managed_by(kCustomManager);
 
-  RefreshDevicePolicy();
-  WaitUntilPolicyLoaded();
+  policy_helper()->RefreshPolicyAndWaitUntilDeviceCloudPolicyUpdated();
   // Now that the managed_by is set expect to see that.
   EXPECT_EQ(kCustomManager, connector->GetEnterpriseDomainManager());
 
@@ -106,8 +87,7 @@
 
   device_policy()->policy_data().set_market_segment(
       enterprise_management::PolicyData::ENROLLED_EDUCATION);
-  RefreshDevicePolicy();
-  WaitUntilPolicyLoaded();
+  policy_helper()->RefreshPolicyAndWaitUntilDeviceCloudPolicyUpdated();
   EXPECT_EQ(MarketSegment::EDUCATION, connector->GetEnterpriseMarketSegment());
 }
 
@@ -116,8 +96,7 @@
       g_browser_process->platform_part()->browser_policy_connector_ash();
   EXPECT_EQ(std::string(), connector->GetMachineName());
   device_policy()->policy_data().set_machine_name(kMachineName);
-  RefreshDevicePolicy();
-  WaitUntilPolicyLoaded();
+  policy_helper()->RefreshPolicyAndWaitUntilDeviceCloudPolicyUpdated();
   // At this point custom display domain is set and policy is loaded so expect
   // to see the custom display domain.
   EXPECT_EQ(kMachineName, connector->GetMachineName());
diff --git a/chrome/browser/ash/policy/core/device_attributes_browsertest.cc b/chrome/browser/ash/policy/core/device_attributes_browsertest.cc
index e020ab3e..b1151cc2 100644
--- a/chrome/browser/ash/policy/core/device_attributes_browsertest.cc
+++ b/chrome/browser/ash/policy/core/device_attributes_browsertest.cc
@@ -27,23 +27,6 @@
 
 namespace {
 
-void WaitUntilPolicyLoaded() {
-  DeviceCloudPolicyStoreAsh* policy_store = g_browser_process->platform_part()
-                                                ->browser_policy_connector_ash()
-                                                ->GetDeviceCloudPolicyManager()
-                                                ->device_store();
-  if (!policy_store->has_policy()) {
-    MockCloudPolicyStoreObserver observer;
-    base::RunLoop loop;
-    policy_store->AddObserver(&observer);
-    EXPECT_CALL(observer, OnStoreLoaded(policy_store))
-        .Times(1)
-        .WillOnce(InvokeWithoutArgs(&loop, &base::RunLoop::Quit));
-    loop.Run();
-    policy_store->RemoveObserver(&observer);
-  }
-}
-
 constexpr char kFakeDomain[] = "fake.domain.acme.corp";
 constexpr char kFakeDisplayDomain[] = "acme.corp";
 constexpr char kFakeSSOProfile[] = "fake sso profile";
@@ -100,8 +83,7 @@
       kFakeLogoURL);
   device_policy()->policy_data().set_market_segment(
       enterprise_management::PolicyData_MarketSegment_ENROLLED_ENTERPRISE);
-  RefreshDevicePolicy();
-  WaitUntilPolicyLoaded();
+  policy_helper()->RefreshPolicyAndWaitUntilDeviceCloudPolicyUpdated();
 
   // Verify returned attributes correspond to what was set.
   EXPECT_EQ(kFakeDomain, attributes_.GetEnterpriseEnrollmentDomain());
diff --git a/chrome/browser/ash/policy/core/device_policy_cros_browser_test.cc b/chrome/browser/ash/policy/core/device_policy_cros_browser_test.cc
index 911bd12..208cdf8 100644
--- a/chrome/browser/ash/policy/core/device_policy_cros_browser_test.cc
+++ b/chrome/browser/ash/policy/core/device_policy_cros_browser_test.cc
@@ -16,21 +16,46 @@
 #include "base/numerics/safe_conversions.h"
 #include "base/path_service.h"
 #include "base/threading/thread_restrictions.h"
+#include "chrome/browser/ash/policy/core/browser_policy_connector_ash.h"
+#include "chrome/browser/ash/policy/core/device_cloud_policy_store_ash.h"
 #include "chrome/browser/ash/policy/core/device_policy_builder.h"
 #include "chrome/browser/ash/settings/cros_settings.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_process_platform_part_chromeos.h"
 #include "chrome/common/chrome_paths.h"
 #include "chromeos/dbus/constants/dbus_paths.h"
 #include "chromeos/dbus/session_manager/fake_session_manager_client.h"
+#include "components/policy/core/common/cloud/cloud_policy_store.h"
+#include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
 #include "components/prefs/pref_service.h"
 #include "crypto/rsa_private_key.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace policy {
+namespace {
 
 namespace em = ::enterprise_management;
 
+class CloudPolicyStoreWaiter : public CloudPolicyStore::Observer {
+ public:
+  CloudPolicyStoreWaiter() = default;
+  CloudPolicyStoreWaiter(const CloudPolicyStoreWaiter&) = delete;
+  CloudPolicyStoreWaiter& operator=(const CloudPolicyStoreWaiter&) = delete;
+  ~CloudPolicyStoreWaiter() override = default;
+
+  void OnStoreLoaded(CloudPolicyStore* store) override { loop_.Quit(); }
+
+  void OnStoreError(CloudPolicyStore* store) override { FAIL(); }
+
+  void Wait() { loop_.Run(); }
+
+ private:
+  base::RunLoop loop_;
+};
+
+}  // namespace
+
 void DeviceLocalAccountTestHelper::SetupDeviceLocalAccount(
     UserPolicyBuilder* policy_builder,
     const std::string& kAccountId,
@@ -174,6 +199,22 @@
   base::RunLoop().RunUntilIdle();
 }
 
+void DevicePolicyCrosTestHelper::
+    RefreshPolicyAndWaitUntilDeviceCloudPolicyUpdated() {
+  policy::DeviceCloudPolicyStoreAsh* policy_store =
+      g_browser_process->platform_part()
+          ->browser_policy_connector_ash()
+          ->GetDeviceCloudPolicyManager()
+          ->device_store();
+  if (!policy_store->has_policy()) {
+    CloudPolicyStoreWaiter waiter;
+    policy_store->AddObserver(&waiter);
+    RefreshDevicePolicy();
+    waiter.Wait();
+    policy_store->RemoveObserver(&waiter);
+  }
+}
+
 void DevicePolicyCrosTestHelper::UnsetPolicy(
     const std::vector<std::string>& settings) {
   em::ChromeDeviceSettingsProto& proto(device_policy()->payload());
diff --git a/chrome/browser/ash/policy/core/device_policy_cros_browser_test.h b/chrome/browser/ash/policy/core/device_policy_cros_browser_test.h
index af43d8972..6504fa07 100644
--- a/chrome/browser/ash/policy/core/device_policy_cros_browser_test.h
+++ b/chrome/browser/ash/policy/core/device_policy_cros_browser_test.h
@@ -8,9 +8,11 @@
 #include <string>
 
 #include "chrome/browser/ash/login/test/device_state_mixin.h"
+#include "chrome/browser/ash/policy/core/device_cloud_policy_store_ash.h"
 #include "chrome/browser/ash/policy/core/device_policy_builder.h"
 #include "chrome/test/base/mixin_based_in_process_browser_test.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
+#include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
 #include "components/policy/core/common/cloud/test/policy_builder.h"
 #include "components/prefs/pref_change_registrar.h"
 
@@ -96,6 +98,8 @@
   //   resolution setting.
   void RefreshPolicyAndWaitUntilDeviceSettingsUpdated(
       const std::vector<std::string>& settings);
+  // Refreshes the whole device cloud policies.
+  void RefreshPolicyAndWaitUntilDeviceCloudPolicyUpdated();
   void UnsetPolicy(const std::vector<std::string>& settings);
 
  private:
diff --git a/chrome/browser/ash/policy/enrollment/auto_enrollment_client.h b/chrome/browser/ash/policy/enrollment/auto_enrollment_client.h
index 626048d..cb366e4 100644
--- a/chrome/browser/ash/policy/enrollment/auto_enrollment_client.h
+++ b/chrome/browser/ash/policy/enrollment/auto_enrollment_client.h
@@ -10,7 +10,6 @@
 
 #include "base/callback.h"
 #include "base/memory/scoped_refptr.h"
-#include "chrome/browser/ash/policy/enrollment/private_membership/private_membership_rlwe_client.h"
 
 class PrefService;
 
@@ -21,7 +20,7 @@
 namespace policy {
 
 class DeviceManagementService;
-class PsmRlweIdProvider;
+class PsmRlweDmserverClient;
 
 // Indicates the current state of the auto-enrollment check. (Numeric values
 // are just to make reading of log files easier.)
@@ -90,8 +89,7 @@
         const std::string& device_brand_code,
         int power_initial,
         int power_limit,
-        PrivateMembershipRlweClient::Factory* psm_rlwe_client_factory,
-        PsmRlweIdProvider* psm_rlwe_id_provider) = 0;
+        std::unique_ptr<PsmRlweDmserverClient> psm_rlwe_dmserver_client) = 0;
   };
 
   virtual ~AutoEnrollmentClient() {}
diff --git a/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl.cc b/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl.cc
index b2f8faf..41f9d1f 100644
--- a/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl.cc
+++ b/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl.cc
@@ -16,7 +16,6 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/ash/login/enrollment/auto_enrollment_controller.h"
 #include "chrome/browser/ash/policy/enrollment/private_membership/psm_rlwe_dmserver_client.h"
-#include "chrome/browser/ash/policy/enrollment/private_membership/psm_rlwe_id_provider.h"
 #include "chrome/browser/ash/policy/server_backed_state/server_backed_device_state.h"
 #include "chrome/common/chrome_content_client.h"
 #include "chrome/common/pref_names.h"
@@ -45,9 +44,6 @@
 using EnrollmentCheckType =
     em::DeviceAutoEnrollmentRequest::EnrollmentCheckType;
 
-// Timeout for running PSM protocol.
-constexpr base::TimeDelta kPsmTimeout = base::Seconds(15);
-
 // Returns the power of the next power-of-2 starting at |value|.
 int NextPowerOf2(int64_t value) {
   for (int i = 0; i <= AutoEnrollmentClient::kMaximumPower; ++i) {
@@ -196,470 +192,6 @@
       const em::DeviceManagementResponse& response) = 0;
 };
 
-class PsmHelper {
- public:
-  // Callback will be triggered after completing the protocol, in case of a
-  // successful determination or stopping due to an error.
-  // The `psm_result` represents the final result of PSM protocol.
-  using CompletionCallback = base::OnceCallback<void(PsmResult psm_result)>;
-
-  // The PsmHelper doesn't take ownership of |device_management_service|,
-  // |local_state|, |psm_rlwe_client_factory| and |psm_rlwe_id_provider|.
-  // All of them must not be nullptr. Also, |device_management_service|,
-  // and |local_state| must outlive PsmHelper.
-  PsmHelper(DeviceManagementService* device_management_service,
-            scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
-            PrefService* local_state,
-            PrivateMembershipRlweClient::Factory* psm_rlwe_client_factory,
-            PsmRlweIdProvider* psm_rlwe_id_provider)
-      : random_device_id_(base::GenerateGUID()),
-        url_loader_factory_(url_loader_factory),
-        device_management_service_(device_management_service),
-        local_state_(local_state) {
-    CHECK(device_management_service);
-    CHECK(psm_rlwe_client_factory);
-    CHECK(psm_rlwe_id_provider);
-    DCHECK(local_state_);
-
-    psm_rlwe_id_ = psm_rlwe_id_provider->ConstructRlweId();
-
-    // Create PSM client for |psm_rlwe_id_| with use case as CROS_DEVICE_STATE.
-    std::vector<psm_rlwe::RlwePlaintextId> psm_ids = {psm_rlwe_id_};
-    auto status_or_client = psm_rlwe_client_factory->Create(
-        psm_rlwe::RlweUseCase::CROS_DEVICE_STATE, psm_ids);
-    if (!status_or_client.ok()) {
-      // If the PSM RLWE client hasn't been created successfully, then report
-      // the error and don't run the protocol.
-      LOG(ERROR)
-          << "PSM error: unexpected internal logic error during creating "
-             "PSM RLWE client";
-      last_psm_execution_result_ = PsmResult::kCreateRlweClientLibraryError;
-      base::UmaHistogramEnumeration(kUMAPsmResult + uma_suffix_,
-                                    PsmResult::kCreateRlweClientLibraryError);
-      return;
-    }
-
-    psm_rlwe_client_ = std::move(status_or_client).value();
-  }
-
-  // Disallow copy constructor and assignment operator.
-  PsmHelper(const PsmHelper&) = delete;
-  PsmHelper& operator=(const PsmHelper&) = delete;
-
-  // Cancels the ongoing PSM operation, if any (without calling the operation's
-  // callbacks).
-  ~PsmHelper() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); }
-
-  // Determines the PSM for the |psm_rlwe_id_|. Then, will call |callback| upon
-  // completing the protocol, whether it finished with a successful
-  // determination or stopped in case of errors. Also, the |callback| has to be
-  // non-null.
-  // Note: This method should be called only when there is no PSM requests in
-  // progress (i.e. `IsCheckMembershipInProgress` is false).
-  void CheckMembership(CompletionCallback callback) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    DCHECK(callback);
-
-    // Ignore new calls and execute `callback` with
-    // |last_psm_execution_result_|, in case any error occurred while running
-    // PSM previously.
-    if (HasPsmError()) {
-      std::move(callback).Run(last_psm_execution_result_.value());
-      return;
-    }
-
-    // There should not be any pending PSM requests.
-    CHECK(!psm_request_job_);
-
-    time_start_ = base::TimeTicks::Now();
-
-    // Set the initial PSM execution result as unknown until it finishes
-    // successfully or due to an error.
-    // Also, clear the PSM determination timestamp.
-    local_state_->SetInteger(prefs::kEnrollmentPsmResult,
-                             em::DeviceRegisterRequest::PSM_RESULT_UNKNOWN);
-    local_state_->ClearPref(prefs::kEnrollmentPsmDeterminationTime);
-
-    on_completion_callback_ = std::move(callback);
-
-    // Start the protocol and its timeout timer.
-    psm_timeout_.Start(
-        FROM_HERE, kPsmTimeout,
-        base::BindOnce(&PsmHelper::StoreErrorAndStop, base::Unretained(this),
-                       PsmResult::kTimeout));
-    SendPsmRlweOprfRequest();
-  }
-
-  // Tries to load the result of a previous execution of the PSM protocol from
-  // local state. Returns decision value if it has been made and is valid,
-  // otherwise nullopt.
-  absl::optional<bool> GetPsmCachedDecision() const {
-    const PrefService::Preference* has_psm_server_state_pref =
-        local_state_->FindPreference(prefs::kShouldRetrieveDeviceState);
-
-    if (!has_psm_server_state_pref ||
-        has_psm_server_state_pref->IsDefaultValue() ||
-        !has_psm_server_state_pref->GetValue()->is_bool()) {
-      return absl::nullopt;
-    }
-
-    return has_psm_server_state_pref->GetValue()->GetBool();
-  }
-
-  // Indicate whether an error occurred while executing the PSM protocol.
-  bool HasPsmError() const {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    return last_psm_execution_result_ &&
-           last_psm_execution_result_.value() !=
-               PsmResult::kSuccessfulDetermination;
-  }
-
-  // Returns true if the PSM protocol is still running,
-  // otherwise false.
-  bool IsCheckMembershipInProgress() const {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    return psm_request_job_ != nullptr;
-  }
-
- private:
-  void StoreErrorAndStop(PsmResult psm_result) {
-    // Note that kUMAPsmResult histogram is only using initial enrollment as a
-    // suffix until PSM support FRE.
-    base::UmaHistogramEnumeration(kUMAPsmResult + uma_suffix_, psm_result);
-
-    // Records the PSM execution as an error in local_state, so that value will
-    // be used in the DeviceRegisterRequest during the enrollment flow.
-    local_state_->SetInteger(prefs::kEnrollmentPsmResult,
-                             em::DeviceRegisterRequest::PSM_RESULT_ERROR);
-    local_state_->CommitPendingWrite();
-
-    // Stop the PSM timer.
-    psm_timeout_.Stop();
-
-    // Stop the current |psm_request_job_|.
-    psm_request_job_.reset();
-
-    last_psm_execution_result_ = psm_result;
-    std::move(on_completion_callback_).Run(psm_result);
-  }
-
-  // Constructs and sends the PSM RLWE OPRF request.
-  void SendPsmRlweOprfRequest() {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-    // Create RLWE OPRF request.
-    const auto status_or_oprf_request = psm_rlwe_client_->CreateOprfRequest();
-    if (!status_or_oprf_request.ok()) {
-      // If the RLWE OPRF request hasn't been created successfully, then report
-      // the error and stop the protocol.
-      LOG(ERROR)
-          << "PSM error: unexpected internal logic error during creating "
-             "RLWE OPRF request";
-      StoreErrorAndStop(PsmResult::kCreateOprfRequestLibraryError);
-      return;
-    }
-
-    LOG(WARNING) << "PSM: prepare and send out the RLWE OPRF request";
-
-    // Prepare the RLWE OPRF request job.
-    // The passed callback will not be called if |psm_request_job_| is
-    // destroyed, so it's safe to use base::Unretained.
-    std::unique_ptr<DMServerJobConfiguration> config =
-        CreatePsmRequestJobConfiguration(base::BindOnce(
-            &PsmHelper::OnRlweOprfRequestCompletion, base::Unretained(this)));
-
-    em::DeviceManagementRequest* request = config->request();
-    em::PrivateSetMembershipRlweRequest* psm_rlwe_request =
-        request->mutable_private_set_membership_request()
-            ->mutable_rlwe_request();
-
-    *psm_rlwe_request->mutable_oprf_request() = status_or_oprf_request.value();
-    psm_request_job_ = device_management_service_->CreateJob(std::move(config));
-  }
-
-  // If the completion was successful, then it makes another request to
-  // DMServer for performing phase two.
-  void OnRlweOprfRequestCompletion(
-      DeviceManagementService::Job* job,
-      DeviceManagementStatus status,
-      int net_error,
-      const em::DeviceManagementResponse& response) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-    base::UmaHistogramSparse(kUMAPsmDmServerRequestStatus + uma_suffix_,
-                             status);
-
-    switch (status) {
-      case DM_STATUS_SUCCESS: {
-        // Check if the RLWE OPRF response is empty.
-        if (!response.private_set_membership_response().has_rlwe_response() ||
-            !response.private_set_membership_response()
-                 .rlwe_response()
-                 .has_oprf_response()) {
-          LOG(ERROR) << "PSM error: empty OPRF RLWE response";
-          StoreErrorAndStop(PsmResult::kEmptyOprfResponseError);
-          return;
-        }
-
-        LOG(WARNING) << "PSM RLWE OPRF request completed successfully";
-        SendPsmRlweQueryRequest(response.private_set_membership_response());
-        return;
-      }
-      case DM_STATUS_REQUEST_FAILED: {
-        LOG(ERROR)
-            << "PSM error: RLWE OPRF request failed due to connection error";
-        base::UmaHistogramSparse(kUMAPsmNetworkErrorCode + uma_suffix_,
-                                 -net_error);
-        StoreErrorAndStop(PsmResult::kConnectionError);
-        return;
-      }
-      default: {
-        LOG(ERROR) << "PSM error: RLWE OPRF request failed due to server error";
-        StoreErrorAndStop(PsmResult::kServerError);
-        return;
-      }
-    }
-  }
-
-  // Constructs and sends the PSM RLWE Query request.
-  void SendPsmRlweQueryRequest(
-      const em::PrivateSetMembershipResponse& psm_response) {
-    // Extract the oprf_response from |psm_response|.
-    const psm_rlwe::PrivateMembershipRlweOprfResponse oprf_response =
-        psm_response.rlwe_response().oprf_response();
-
-    const auto status_or_query_request =
-        psm_rlwe_client_->CreateQueryRequest(oprf_response);
-
-    // Create RLWE query request.
-    if (!status_or_query_request.ok()) {
-      // If the RLWE query request hasn't been created successfully, then report
-      // the error and stop the protocol.
-      LOG(ERROR)
-          << "PSM error: unexpected internal logic error during creating "
-             "RLWE query request";
-      StoreErrorAndStop(PsmResult::kCreateQueryRequestLibraryError);
-      return;
-    }
-
-    LOG(WARNING) << "PSM: prepare and send out the RLWE query request";
-
-    // Prepare the RLWE query request job.
-    std::unique_ptr<DMServerJobConfiguration> config =
-        CreatePsmRequestJobConfiguration(
-            base::BindOnce(&PsmHelper::OnRlweQueryRequestCompletion,
-                           base::Unretained(this), oprf_response));
-
-    em::DeviceManagementRequest* request = config->request();
-    em::PrivateSetMembershipRlweRequest* psm_rlwe_request =
-        request->mutable_private_set_membership_request()
-            ->mutable_rlwe_request();
-
-    *psm_rlwe_request->mutable_query_request() =
-        status_or_query_request.value();
-    psm_request_job_ = device_management_service_->CreateJob(std::move(config));
-  }
-
-  // If the completion was successful, then it will parse the result and call
-  // the |on_completion_callback_| for |psm_id_|.
-  void OnRlweQueryRequestCompletion(
-      const psm_rlwe::PrivateMembershipRlweOprfResponse& oprf_response,
-      DeviceManagementService::Job* job,
-      DeviceManagementStatus status,
-      int net_error,
-      const em::DeviceManagementResponse& response) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-    base::UmaHistogramSparse(kUMAPsmDmServerRequestStatus + uma_suffix_,
-                             status);
-
-    switch (status) {
-      case DM_STATUS_SUCCESS: {
-        // Check if the RLWE query response is empty.
-        if (!response.private_set_membership_response().has_rlwe_response() ||
-            !response.private_set_membership_response()
-                 .rlwe_response()
-                 .has_query_response()) {
-          LOG(ERROR) << "PSM error: empty query RLWE response";
-          StoreErrorAndStop(PsmResult::kEmptyQueryResponseError);
-          return;
-        }
-
-        const psm_rlwe::PrivateMembershipRlweQueryResponse query_response =
-            response.private_set_membership_response()
-                .rlwe_response()
-                .query_response();
-
-        auto status_or_responses =
-            psm_rlwe_client_->ProcessQueryResponse(query_response);
-
-        if (!status_or_responses.ok()) {
-          // If the RLWE query response hasn't processed successfully, then
-          // report the error and stop the protocol.
-          LOG(ERROR) << "PSM error: unexpected internal logic error during "
-                        "processing the "
-                        "RLWE query response";
-          StoreErrorAndStop(PsmResult::kProcessingQueryResponseLibraryError);
-          return;
-        }
-
-        LOG(WARNING) << "PSM query request completed successfully";
-
-        last_psm_execution_result_ = PsmResult::kSuccessfulDetermination;
-        base::UmaHistogramEnumeration(kUMAPsmResult + uma_suffix_,
-                                      PsmResult::kSuccessfulDetermination);
-        RecordPsmSuccessTimeHistogram();
-
-        // The RLWE query response has been processed successfully. Extract
-        // the membership response, and report the result.
-
-        psm_rlwe::RlweMembershipResponses rlwe_membership_responses =
-            std::move(status_or_responses).value();
-
-        // Ensure the existence of one membership response. Then, verify that it
-        // is regarding the current PSM ID.
-        if (rlwe_membership_responses.membership_responses_size() != 1 ||
-            rlwe_membership_responses.membership_responses(0)
-                    .plaintext_id()
-                    .sensitive_id() != psm_rlwe_id_.sensitive_id()) {
-          LOG(ERROR)
-              << "PSM error: RLWE membership responses are either empty or its "
-                 "first response's ID is not the same as the current PSM ID.";
-          // TODO(crbug.com/1302982): Record that error separately and merge it
-          // with PsmResult.
-          StoreErrorAndStop(PsmResult::kEmptyQueryResponseError);
-          return;
-        }
-
-        const bool membership_result =
-            rlwe_membership_responses.membership_responses(0)
-                .membership_response()
-                .is_member();
-
-        LOG(WARNING) << "PSM determination successful. Identifier "
-                     << (membership_result ? "" : "not ")
-                     << "present on the server";
-
-        // Reset the |psm_request_job_| to allow another call to
-        // CheckMembership.
-        psm_request_job_.reset();
-
-        // Stop the PSM timer.
-        psm_timeout_.Stop();
-
-        // Cache the decision in local_state, so that it is reused in case
-        // the device reboots before completing OOBE.
-        // Also, record the PSM determination timestamp and its execution
-        // result in local state. Because both values will be used in the
-        // DeviceRegisterRequest during the enrollment flow.
-        local_state_->SetBoolean(prefs::kShouldRetrieveDeviceState,
-                                 membership_result);
-        local_state_->SetTime(prefs::kEnrollmentPsmDeterminationTime,
-                              base::Time::Now());
-        local_state_->SetInteger(
-            prefs::kEnrollmentPsmResult,
-            membership_result
-                ? em::DeviceRegisterRequest::PSM_RESULT_SUCCESSFUL_WITH_STATE
-                : em::DeviceRegisterRequest::
-                      PSM_RESULT_SUCCESSFUL_WITHOUT_STATE);
-        local_state_->CommitPendingWrite();
-
-        std::move(on_completion_callback_)
-            .Run(PsmResult::kSuccessfulDetermination);
-        return;
-      }
-      case DM_STATUS_REQUEST_FAILED: {
-        LOG(ERROR)
-            << "PSM error: RLWE query request failed due to connection error";
-        base::UmaHistogramSparse(kUMAPsmNetworkErrorCode + uma_suffix_,
-                                 -net_error);
-        StoreErrorAndStop(PsmResult::kConnectionError);
-        return;
-      }
-      default: {
-        LOG(ERROR)
-            << "PSM error: RLWE query request failed due to server error";
-        StoreErrorAndStop(PsmResult::kServerError);
-        return;
-      }
-    }
-  }
-
-  // Returns a job config that has TYPE_PSM_REQUEST as job type and |callback|
-  // will be executed on completion.
-  std::unique_ptr<DMServerJobConfiguration> CreatePsmRequestJobConfiguration(
-      DMServerJobConfiguration::Callback callback) {
-    return std::make_unique<DMServerJobConfiguration>(
-        device_management_service_,
-        DeviceManagementService::JobConfiguration::
-            TYPE_PSM_HAS_DEVICE_STATE_REQUEST,
-        random_device_id_,
-        /*critical=*/true, DMAuth::NoAuth(),
-        /*oauth_token=*/absl::nullopt, url_loader_factory_,
-        std::move(callback));
-  }
-
-  // Record UMA histogram for timing of successful PSM request.
-  void RecordPsmSuccessTimeHistogram() {
-    // These values determine bucketing of the histogram, they should not be
-    // changed.
-    static const base::TimeDelta kMin = base::Milliseconds(1);
-    static const base::TimeDelta kMax = base::Seconds(25);
-    static const int kBuckets = 50;
-
-    base::TimeTicks now = base::TimeTicks::Now();
-    if (!time_start_.is_null()) {
-      base::TimeDelta delta = now - time_start_;
-      base::UmaHistogramCustomTimes(kUMAPsmSuccessTime, delta, kMin, kMax,
-                                    kBuckets);
-    }
-  }
-
-  // PSM RLWE client, used for preparing PSM requests and parsing PSM responses.
-  std::unique_ptr<PrivateMembershipRlweClient> psm_rlwe_client_;
-
-  // Randomly generated device id for the PSM requests.
-  std::string random_device_id_;
-
-  // The loader factory to use to perform PSM requests.
-  scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
-
-  // Unowned by PsmHelper. Its used to communicate with the device management
-  // service.
-  DeviceManagementService* device_management_service_;
-
-  // Its being used for both PSM requests e.g. RLWE OPRF request and RLWE query
-  // request.
-  std::unique_ptr<DeviceManagementService::Job> psm_request_job_;
-
-  // Callback will be triggered upon completing of the protocol.
-  CompletionCallback on_completion_callback_;
-
-  // PrefService where the PSM protocol result is cached.
-  PrefService* const local_state_;
-
-  // PSM identifier, which is going to be used while preparing the PSM requests.
-  psm_rlwe::RlwePlaintextId psm_rlwe_id_;
-
-  // A timer that puts a hard limit on the maximum time to wait for PSM
-  // protocol.
-  base::OneShotTimer psm_timeout_;
-
-  // The time when the PSM request started.
-  base::TimeTicks time_start_;
-
-  // Represents the last PSM protocol execution result.
-  absl::optional<PsmResult> last_psm_execution_result_;
-
-  // The UMA histogram suffix. It's set only to ".InitialEnrollment" for an
-  // |AutoEnrollmentClient| until PSM will support FRE.
-  const std::string uma_suffix_ = kUMASuffixInitialEnrollment;
-
-  // A sequence checker to prevent the race condition of having the possibility
-  // of the destructor being called and any of the callbacks.
-  SEQUENCE_CHECKER(sequence_checker_);
-};
-
 namespace {
 // Handles DeviceInitialEnrollmentStateRequest /
 // DeviceInitialEnrollmentStateResponse for Forced Initial Enrollment.
@@ -849,8 +381,7 @@
     const std::string& device_brand_code,
     int power_initial,
     int power_limit,
-    PrivateMembershipRlweClient::Factory* psm_rlwe_client_factory,
-    PsmRlweIdProvider* psm_rlwe_id_provider) {
+    std::unique_ptr<PsmRlweDmserverClient> psm_rlwe_dmserver_client) {
   return base::WrapUnique(new AutoEnrollmentClientImpl(
       progress_callback, device_management_service, local_state,
       url_loader_factory,
@@ -858,9 +389,7 @@
       std::make_unique<StateDownloadMessageProcessorInitialEnrollment>(
           device_serial_number, device_brand_code),
       power_initial, power_limit, kUMASuffixInitialEnrollment,
-      std::make_unique<PsmHelper>(device_management_service, url_loader_factory,
-                                  local_state, psm_rlwe_client_factory,
-                                  psm_rlwe_id_provider)));
+      std::move(psm_rlwe_dmserver_client)));
 }
 
 AutoEnrollmentClientImpl::~AutoEnrollmentClientImpl() {
@@ -934,7 +463,7 @@
     int power_initial,
     int power_limit,
     std::string uma_suffix,
-    std::unique_ptr<PsmHelper> private_set_membership_helper)
+    std::unique_ptr<PsmRlweDmserverClient> psm_rlwe_dmserver_client)
     : progress_callback_(callback),
       state_(AUTO_ENROLLMENT_STATE_IDLE),
       has_server_state_(false),
@@ -950,7 +479,7 @@
           std::move(device_identifier_provider_fre)),
       state_download_message_processor_(
           std::move(state_download_message_processor)),
-      psm_helper_(std::move(private_set_membership_helper)),
+      psm_rlwe_dmserver_client_(std::move(psm_rlwe_dmserver_client)),
       uma_suffix_(uma_suffix) {
   DCHECK_LE(current_power_, power_limit_);
   DCHECK(!progress_callback_.is_null());
@@ -976,20 +505,25 @@
 
 bool AutoEnrollmentClientImpl::RetrievePsmCachedDecision() {
   // PSM protocol has to be enabled whenever this function is called.
-  DCHECK(psm_helper_);
+  DCHECK(psm_rlwe_dmserver_client_);
 
-  const absl::optional<bool> private_set_membership_server_state =
-      psm_helper_->GetPsmCachedDecision();
+  const PrefService::Preference* has_psm_server_state_pref =
+      local_state_->FindPreference(prefs::kShouldRetrieveDeviceState);
 
-  if (private_set_membership_server_state.has_value()) {
-    has_server_state_ = std::move(private_set_membership_server_state);
-    return true;
+  if (!has_psm_server_state_pref ||
+      has_psm_server_state_pref->IsDefaultValue()) {
+    // Verify the pref is registered as a boolean.
+    DCHECK(has_psm_server_state_pref->GetValue()->is_bool());
+
+    return false;
   }
-  return false;
+
+  has_server_state_ = has_psm_server_state_pref->GetValue()->GetBool();
+  return true;
 }
 
 bool AutoEnrollmentClientImpl::IsClientForInitialEnrollment() const {
-  return psm_helper_ != nullptr;
+  return psm_rlwe_dmserver_client_ != nullptr;
 }
 
 bool AutoEnrollmentClientImpl::ShouldSendDeviceStateRequest() const {
@@ -1026,15 +560,15 @@
 
 bool AutoEnrollmentClientImpl::PsmRetryStep() {
   // PSM protocol has to be enabled whenever this function is called.
-  DCHECK(psm_helper_);
+  DCHECK(psm_rlwe_dmserver_client_);
 
   // Don't retry if the protocol had an error.
-  if (psm_helper_->HasPsmError())
+  if (psm_result_holder_ && psm_result_holder_->IsError())
     return false;
 
   // If the PSM protocol is in progress, signal to the caller
   // that nothing else needs to be done.
-  if (psm_helper_->IsCheckMembershipInProgress())
+  if (psm_rlwe_dmserver_client_->IsCheckMembershipInProgress())
     return true;
 
   if (RetrievePsmCachedDecision()) {
@@ -1042,15 +576,42 @@
                  << has_server_state_.value();
     return false;
   } else {
-    psm_helper_->CheckMembership(
+    // Set the initial PSM execution result as unknown until it finishes
+    // successfully or due to an error.
+    // Also, clear the PSM determination timestamp.
+    local_state_->SetInteger(prefs::kEnrollmentPsmResult,
+                             em::DeviceRegisterRequest::PSM_RESULT_UNKNOWN);
+    local_state_->ClearPref(prefs::kEnrollmentPsmDeterminationTime);
+
+    psm_rlwe_dmserver_client_->CheckMembership(
         base::BindOnce(&AutoEnrollmentClientImpl::HandlePsmCompletion,
                        base::Unretained(this)));
     return true;
   }
 }
 
-void AutoEnrollmentClientImpl::HandlePsmCompletion(PsmResult psm_result) {
-  switch (psm_result) {
+void AutoEnrollmentClientImpl::HandlePsmCompletion(
+    PsmRlweDmserverClient::ResultHolder psm_result_holder) {
+  psm_result_holder_ = std::move(psm_result_holder);
+
+  // Update `local_state_` PSM's prefs with their corresponding result values.
+  if (psm_result_holder_->psm_result != PsmResult::kSuccessfulDetermination) {
+    local_state_->SetInteger(prefs::kEnrollmentPsmResult,
+                             em::DeviceRegisterRequest::PSM_RESULT_ERROR);
+  } else {
+    local_state_->SetBoolean(prefs::kShouldRetrieveDeviceState,
+                             psm_result_holder_->membership_result.value());
+    local_state_->SetTime(
+        prefs::kEnrollmentPsmDeterminationTime,
+        psm_result_holder_->membership_determination_time.value());
+    local_state_->SetInteger(
+        prefs::kEnrollmentPsmResult,
+        psm_result_holder_->membership_result.value()
+            ? em::DeviceRegisterRequest::PSM_RESULT_SUCCESSFUL_WITH_STATE
+            : em::DeviceRegisterRequest::PSM_RESULT_SUCCESSFUL_WITHOUT_STATE);
+  }
+
+  switch (psm_result_holder_->psm_result) {
     case PsmResult::kConnectionError:
       ReportProgress(AUTO_ENROLLMENT_STATE_CONNECTION_ERROR);
       break;
diff --git a/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl.h b/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl.h
index 34d3498..bbb969d 100644
--- a/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl.h
+++ b/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl.h
@@ -29,14 +29,6 @@
 
 namespace policy {
 
-class PsmRlweIdProvider;
-
-// A class that handles all communications related to PSM protocol with
-// DMServer. Also, upon successful determination, it caches the membership state
-// of a given identifier in the local_state PrefService. Upon a failed
-// determination it won't allow another membership check.
-class PsmHelper;
-
 // Interacts with the device management service and determines whether this
 // machine should automatically enter the Enterprise Enrollment screen during
 // OOBE.
@@ -81,8 +73,8 @@
         const std::string& device_brand_code,
         int power_initial,
         int power_limit,
-        PrivateMembershipRlweClient::Factory* psm_rlwe_client_factory,
-        PsmRlweIdProvider* psm_rlwe_id_provider) override;
+        std::unique_ptr<PsmRlweDmserverClient> psm_rlwe_dmserver_client)
+        override;
   };
 
   AutoEnrollmentClientImpl(const AutoEnrollmentClientImpl&) = delete;
@@ -119,7 +111,7 @@
       int power_initial,
       int power_limit,
       std::string uma_suffix,
-      std::unique_ptr<PsmHelper> psm_helper);
+      std::unique_ptr<PsmRlweDmserverClient> psm_rlwe_dmserver_client);
 
   // Tries to load the result of a previous execution of the protocol from
   // local state. Returns true if that decision has been made and is valid.
@@ -150,7 +142,8 @@
 
   // Calls `NextStep` in case of successful execution of PSM protocol.
   // Otherwise, reports the failure reason of PSM protocol execution.
-  void HandlePsmCompletion(PsmResult psm_result);
+  void HandlePsmCompletion(
+      PsmRlweDmserverClient::ResultHolder psm_result_holder);
 
   // Cleans up and invokes |progress_callback_|.
   void ReportProgress(AutoEnrollmentState state);
@@ -213,6 +206,9 @@
   // information.
   absl::optional<bool> has_server_state_;
 
+  // Holds the cached PSM execution result.
+  absl::optional<PsmRlweDmserverClient::ResultHolder> psm_result_holder_;
+
   // Whether the download of server-kept device state completed successfully.
   bool device_state_available_;
 
@@ -250,8 +246,9 @@
   std::unique_ptr<StateDownloadMessageProcessor>
       state_download_message_processor_;
 
-  // Obtains the device state using PSM protocol.
-  std::unique_ptr<PsmHelper> psm_helper_;
+  // Obtains the device state using PSM protocol. Handles all communications
+  // related to PSM protocol with DMServer.
+  std::unique_ptr<PsmRlweDmserverClient> psm_rlwe_dmserver_client_;
 
   // Times used to determine the duration of the protocol, and the extra time
   // needed to complete after the signin was complete.
diff --git a/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl_unittest.cc b/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl_unittest.cc
index c4ef557..638d24c8 100644
--- a/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl_unittest.cc
+++ b/chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl_unittest.cc
@@ -28,6 +28,7 @@
 #include "base/values.h"
 #include "chrome/browser/ash/login/enrollment/auto_enrollment_controller.h"
 #include "chrome/browser/ash/policy/enrollment/private_membership/psm_rlwe_dmserver_client.h"
+#include "chrome/browser/ash/policy/enrollment/private_membership/psm_rlwe_dmserver_client_impl.h"
 #include "chrome/browser/ash/policy/enrollment/private_membership/testing_private_membership_rlwe_client.h"
 #include "chrome/browser/ash/policy/enrollment/private_membership/testing_psm_rlwe_id_provider.h"
 #include "chrome/browser/ash/policy/server_backed_state/server_backed_device_state.h"
@@ -182,6 +183,7 @@
     shared_url_loader_factory_ =
         base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
             &url_loader_factory_);
+
     if (GetAutoEnrollmentProtocol() == AutoEnrollmentProtocol::kFRE) {
       client_ = AutoEnrollmentClientImpl::FactoryImpl().CreateForFRE(
           progress_callback, service_.get(), local_state_,
@@ -196,8 +198,11 @@
           AutoEnrollmentClientImpl::FactoryImpl().CreateForInitialEnrollment(
               progress_callback, service_.get(), local_state_,
               shared_url_loader_factory_, kSerialNumber, kBrandCode,
-              power_initial, power_limit, psm_rlwe_test_client_factory_.get(),
-              testing_psm_rlwe_id_provider_.get());
+              power_initial, power_limit,
+              std::make_unique<PsmRlweDmserverClientImpl>(
+                  service_.get(), shared_url_loader_factory_,
+                  psm_rlwe_test_client_factory_.get(),
+                  testing_psm_rlwe_id_provider_.get()));
     }
   }
 
diff --git a/chrome/browser/ash/policy/enrollment/fake_auto_enrollment_client.cc b/chrome/browser/ash/policy/enrollment/fake_auto_enrollment_client.cc
index 068719d..28074d4 100644
--- a/chrome/browser/ash/policy/enrollment/fake_auto_enrollment_client.cc
+++ b/chrome/browser/ash/policy/enrollment/fake_auto_enrollment_client.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ash/policy/enrollment/fake_auto_enrollment_client.h"
 
+#include "chrome/browser/ash/policy/enrollment/private_membership/psm_rlwe_dmserver_client.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 
 namespace policy {
@@ -40,8 +41,7 @@
     const std::string& device_brand_code,
     int power_initial,
     int power_limit,
-    PrivateMembershipRlweClient::Factory* psm_rlwe_client_factory,
-    PsmRlweIdProvider* psm_rlwe_id_provider) {
+    std::unique_ptr<PsmRlweDmserverClient> psm_rlwe_dmserver_client) {
   std::unique_ptr<FakeAutoEnrollmentClient> fake_client =
       std::make_unique<FakeAutoEnrollmentClient>(progress_callback);
   fake_client_created_callback_.Run(fake_client.get());
diff --git a/chrome/browser/ash/policy/enrollment/fake_auto_enrollment_client.h b/chrome/browser/ash/policy/enrollment/fake_auto_enrollment_client.h
index 0b5c5e8..ee77aadb 100644
--- a/chrome/browser/ash/policy/enrollment/fake_auto_enrollment_client.h
+++ b/chrome/browser/ash/policy/enrollment/fake_auto_enrollment_client.h
@@ -16,7 +16,7 @@
 namespace policy {
 
 class DeviceManagementService;
-class PsmRlweIdProvider;
+class PsmRlweDmserverClient;
 
 // A fake AutoEnrollmentClient. The test code can control its state.
 class FakeAutoEnrollmentClient : public AutoEnrollmentClient {
@@ -53,8 +53,8 @@
         const std::string& device_brand_code,
         int power_initial,
         int power_limit,
-        PrivateMembershipRlweClient::Factory* psm_rlwe_client_factory,
-        PsmRlweIdProvider* psm_rlwe_id_provider) override;
+        std::unique_ptr<PsmRlweDmserverClient> psm_rlwe_dmserver_client)
+        override;
 
    private:
     base::RepeatingCallback<void(FakeAutoEnrollmentClient*)>
diff --git a/chrome/browser/autofill/autofill_uitest_util.cc b/chrome/browser/autofill/autofill_uitest_util.cc
index 08ffdec9..fdfb10f 100644
--- a/chrome/browser/autofill/autofill_uitest_util.cc
+++ b/chrome/browser/autofill/autofill_uitest_util.cc
@@ -136,7 +136,9 @@
 
   ContentAutofillDriver* driver = static_cast<ContentAutofillDriver*>(
       absl::get<AutofillDriver*>(autofill_external_delegate->GetDriver()));
-  driver->AskForValuesToFill(query_id, form, field, bounds, false);
+  driver->AskForValuesToFill(query_id, form, field, bounds,
+                             /*autoselect_first_suggestion=*/false,
+                             TouchToFillEligible(false));
 
   std::vector<Suggestion> suggestions = {Suggestion(u"Test suggestion")};
   autofill_external_delegate->OnSuggestionsReturned(
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index fb46d80..690f7fa 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -3630,6 +3630,7 @@
     "../ash/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc",
     "../ash/arc/fileapi/arc_content_file_system_file_stream_writer_unittest.cc",
     "../ash/arc/fileapi/arc_content_file_system_url_util_unittest.cc",
+    "../ash/arc/fileapi/arc_documents_provider_root_map_unittest.cc",
     "../ash/arc/fileapi/arc_documents_provider_root_unittest.cc",
     "../ash/arc/fileapi/arc_documents_provider_util_unittest.cc",
     "../ash/arc/fileapi/arc_file_system_bridge_unittest.cc",
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
index b22b2ade..51f3485 100644
--- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
+++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
@@ -46,6 +46,7 @@
 #include "base/base64.h"
 #include "base/bind.h"
 #include "base/command_line.h"
+#include "base/compiler_specific.h"
 #include "base/feature_list.h"
 #include "base/json/json_reader.h"
 #include "base/lazy_instance.h"
@@ -224,7 +225,7 @@
 constexpr char kCrostiniNotAvailableForCurrentUserError[] =
     "Crostini is not available for the current user";
 
-int AccessArray(const volatile int arr[], const volatile int* index) {
+NOINLINE int AccessArray(const int arr[], const int* index) {
   return arr[*index];
 }
 
@@ -1492,11 +1493,10 @@
   DVLOG(1) << "AutotestPrivateSimulateAsanMemoryBugFunction";
 
   if (!IsTestMode(browser_context())) {
-    // This array is volatile not to let compiler optimize us out.
-    volatile int testarray[3] = {0, 0, 0};
+    int testarray[3] = {0, 0, 0};
 
     // Cause Address Sanitizer to abort this process.
-    volatile int index = 5;
+    int index = 5;
     AccessArray(testarray, &index);
   }
   return RespondNow(NoArguments());
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
index fbeb42a..3175fb26 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
@@ -1590,8 +1590,9 @@
           std::move(source_urls), std::move(destination_folder_url), *type);
       break;
   }
-  volume_manager->io_task_controller()->Add(std::move(task));
-  return RespondNow(NoArguments());
+  const auto taskId =
+      volume_manager->io_task_controller()->Add(std::move(task));
+  return RespondNow(OneArgument(base::Value(static_cast<int>(taskId))));
 }
 
 ExtensionFunction::ResponseAction
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
index 66b7114..c82e706 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
@@ -1223,6 +1223,7 @@
 
   model->GetRecentFiles(
       file_system_context.get(), source_url(), file_type,
+      params->invalidate_cache,
       base::BindOnce(
           &FileManagerPrivateInternalGetRecentFilesFunction::OnGetRecentFiles,
           this, params->restriction));
diff --git a/chrome/browser/chromeos/fileapi/recent_model.cc b/chrome/browser/chromeos/fileapi/recent_model.cc
index a32fc6f..69f1ea21 100644
--- a/chrome/browser/chromeos/fileapi/recent_model.cc
+++ b/chrome/browser/chromeos/fileapi/recent_model.cc
@@ -87,12 +87,19 @@
     storage::FileSystemContext* file_system_context,
     const GURL& origin,
     FileType file_type,
+    bool invalidate_cache,
     GetRecentFilesCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-  // Use cache if available.
+  /**
+   * Use cache only if:
+   *  * cache has value.
+   *  * invalidate_cache = false.
+   *  * cached file type matches the query file type.
+   * Otherwise clear cache if it has values.
+   */
   if (cached_files_.has_value()) {
-    if (cached_files_type_ == file_type) {
+    if (!invalidate_cache && cached_files_type_ == file_type) {
       std::move(callback).Run(cached_files_.value());
       return;
     }
diff --git a/chrome/browser/chromeos/fileapi/recent_model.h b/chrome/browser/chromeos/fileapi/recent_model.h
index 169fd60a..d5f5e2a 100644
--- a/chrome/browser/chromeos/fileapi/recent_model.h
+++ b/chrome/browser/chromeos/fileapi/recent_model.h
@@ -60,6 +60,7 @@
   void GetRecentFiles(storage::FileSystemContext* file_system_context,
                       const GURL& origin,
                       FileType file_type,
+                      bool invalidate_cache,
                       GetRecentFilesCallback callback);
 
   // KeyedService overrides:
@@ -68,7 +69,10 @@
  private:
   friend class RecentModelFactory;
   friend class RecentModelTest;
+  friend class RecentModelCacheTest;
   FRIEND_TEST_ALL_PREFIXES(RecentModelTest, GetRecentFiles_UmaStats);
+  FRIEND_TEST_ALL_PREFIXES(RecentModelCacheTest,
+                           GetRecentFiles_InvalidateCache);
 
   static const char kLoadHistogramName[];
 
diff --git a/chrome/browser/chromeos/fileapi/recent_model_unittest.cc b/chrome/browser/chromeos/fileapi/recent_model_unittest.cc
index a633a07..7c81312 100644
--- a/chrome/browser/chromeos/fileapi/recent_model_unittest.cc
+++ b/chrome/browser/chromeos/fileapi/recent_model_unittest.cc
@@ -47,6 +47,29 @@
   return sources;
 }
 
+std::vector<RecentFile> GetRecentFiles(RecentModel* model,
+                                       RecentModel::FileType file_type,
+                                       bool invalidate_cache) {
+  std::vector<RecentFile> files;
+
+  base::RunLoop run_loop;
+
+  model->GetRecentFiles(
+      nullptr /* file_system_context */, GURL() /* origin */, file_type,
+      invalidate_cache,
+      base::BindOnce(
+          [](base::RunLoop* run_loop, std::vector<RecentFile>* files_out,
+             const std::vector<RecentFile>& files) {
+            *files_out = files;
+            run_loop->Quit();
+          },
+          &run_loop, &files));
+
+  run_loop.Run();
+
+  return files;
+}
+
 }  // namespace
 
 class RecentModelTest : public testing::Test {
@@ -61,7 +84,8 @@
       RecentSourceListFactory source_list_factory,
       size_t max_files,
       const base::Time& cutoff_time,
-      RecentModel::FileType file_type) {
+      RecentModel::FileType file_type,
+      bool invalidate_cache) {
     RecentModel* model = static_cast<RecentModel*>(
         RecentModelFactory::GetInstance()->SetTestingFactoryAndUse(
             &profile_,
@@ -76,23 +100,7 @@
     model->SetMaxFilesForTest(max_files);
     model->SetForcedCutoffTimeForTest(cutoff_time);
 
-    std::vector<RecentFile> files;
-
-    base::RunLoop run_loop;
-
-    model->GetRecentFiles(
-        nullptr /* file_system_context */, GURL() /* origin */, file_type,
-        base::BindOnce(
-            [](base::RunLoop* run_loop, std::vector<RecentFile>* files_out,
-               const std::vector<RecentFile>& files) {
-              *files_out = files;
-              run_loop->Quit();
-            },
-            &run_loop, &files));
-
-    run_loop.Run();
-
-    return files;
+    return GetRecentFiles(model, file_type, invalidate_cache);
   }
 
   content::BrowserTaskEnvironment task_environment_;
@@ -100,9 +108,9 @@
 };
 
 TEST_F(RecentModelTest, GetRecentFiles) {
-  std::vector<RecentFile> files =
-      BuildModelAndGetRecentFiles(base::BindRepeating(&BuildDefaultSources), 10,
-                                  base::Time(), RecentModel::FileType::kAll);
+  std::vector<RecentFile> files = BuildModelAndGetRecentFiles(
+      base::BindRepeating(&BuildDefaultSources), 10, base::Time(),
+      RecentModel::FileType::kAll, false);
 
   ASSERT_EQ(4u, files.size());
   EXPECT_EQ("ddd.ogg", files[0].url().path().value());
@@ -116,9 +124,9 @@
 }
 
 TEST_F(RecentModelTest, GetRecentFiles_MaxFiles) {
-  std::vector<RecentFile> files =
-      BuildModelAndGetRecentFiles(base::BindRepeating(&BuildDefaultSources), 3,
-                                  base::Time(), RecentModel::FileType::kAll);
+  std::vector<RecentFile> files = BuildModelAndGetRecentFiles(
+      base::BindRepeating(&BuildDefaultSources), 3, base::Time(),
+      RecentModel::FileType::kAll, false);
 
   ASSERT_EQ(3u, files.size());
   EXPECT_EQ("ddd.ogg", files[0].url().path().value());
@@ -132,7 +140,7 @@
 TEST_F(RecentModelTest, GetRecentFiles_CutoffTime) {
   std::vector<RecentFile> files = BuildModelAndGetRecentFiles(
       base::BindRepeating(&BuildDefaultSources), 10,
-      base::Time::FromJavaTime(2500), RecentModel::FileType::kAll);
+      base::Time::FromJavaTime(2500), RecentModel::FileType::kAll, false);
 
   ASSERT_EQ(2u, files.size());
   EXPECT_EQ("ddd.ogg", files[0].url().path().value());
@@ -146,15 +154,15 @@
 
   BuildModelAndGetRecentFiles(
       base::BindRepeating([]() { return RecentSourceList(); }), 10,
-      base::Time(), RecentModel::FileType::kAll);
+      base::Time(), RecentModel::FileType::kAll, false);
 
   histogram_tester.ExpectTotalCount(RecentModel::kLoadHistogramName, 1);
 }
 
 TEST_F(RecentModelTest, GetRecentFiles_Audio) {
-  std::vector<RecentFile> files =
-      BuildModelAndGetRecentFiles(base::BindRepeating(&BuildDefaultSources), 10,
-                                  base::Time(), RecentModel::FileType::kAudio);
+  std::vector<RecentFile> files = BuildModelAndGetRecentFiles(
+      base::BindRepeating(&BuildDefaultSources), 10, base::Time(),
+      RecentModel::FileType::kAudio, false);
 
   ASSERT_EQ(1u, files.size());
   EXPECT_EQ("ddd.ogg", files[0].url().path().value());
@@ -162,9 +170,9 @@
 }
 
 TEST_F(RecentModelTest, GetRecentFiles_Image) {
-  std::vector<RecentFile> files =
-      BuildModelAndGetRecentFiles(base::BindRepeating(&BuildDefaultSources), 10,
-                                  base::Time(), RecentModel::FileType::kImage);
+  std::vector<RecentFile> files = BuildModelAndGetRecentFiles(
+      base::BindRepeating(&BuildDefaultSources), 10, base::Time(),
+      RecentModel::FileType::kImage, false);
 
   ASSERT_EQ(2u, files.size());
   EXPECT_EQ("bbb.png", files[0].url().path().value());
@@ -174,13 +182,40 @@
 }
 
 TEST_F(RecentModelTest, GetRecentFiles_Video) {
-  std::vector<RecentFile> files =
-      BuildModelAndGetRecentFiles(base::BindRepeating(&BuildDefaultSources), 10,
-                                  base::Time(), RecentModel::FileType::kVideo);
+  std::vector<RecentFile> files = BuildModelAndGetRecentFiles(
+      base::BindRepeating(&BuildDefaultSources), 10, base::Time(),
+      RecentModel::FileType::kVideo, false);
 
   ASSERT_EQ(1u, files.size());
   EXPECT_EQ("ccc.mp4", files[0].url().path().value());
   EXPECT_EQ(base::Time::FromJavaTime(3000), files[0].last_modified());
 }
 
+// Do not use RecentModelTest fixture, because we need to get a reference of
+// RecentModel and call GetRecentFiles() multiple times.
+TEST(RecentModelCacheTest, GetRecentFiles_InvalidateCache) {
+  content::BrowserTaskEnvironment task_environment;
+  std::unique_ptr<RecentModel> model =
+      RecentModel::CreateForTest(BuildDefaultSources());
+  model->SetForcedCutoffTimeForTest(base::Time());
+
+  std::vector<RecentFile> files1 =
+      GetRecentFiles(model.get(), RecentModel::FileType::kAll, false);
+  ASSERT_EQ(4u, files1.size());
+
+  // Shutdown() will clear all sources.
+  model->Shutdown();
+
+  // The returned file list should still has 4 files even though all sources has
+  // been cleared in Shutdown(), because it hits cache.
+  std::vector<RecentFile> files2 =
+      GetRecentFiles(model.get(), RecentModel::FileType::kAll, false);
+  ASSERT_EQ(4u, files2.size());
+
+  // Inalidate cache and query again.
+  std::vector<RecentFile> files3 =
+      GetRecentFiles(model.get(), RecentModel::FileType::kAll, true);
+  ASSERT_EQ(0u, files3.size());
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/extensions/active_tab_permission_granter.cc b/chrome/browser/extensions/active_tab_permission_granter.cc
index 3c487b7..09d9c77 100644
--- a/chrome/browser/extensions/active_tab_permission_granter.cc
+++ b/chrome/browser/extensions/active_tab_permission_granter.cc
@@ -162,8 +162,8 @@
 
   const PermissionsData* permissions_data = extension->permissions_data();
 
-  // TODO(crbug.com/698985): This should be GetLastCommittedURL().
-  const GURL& url = web_contents()->GetVisibleURL();
+  const GURL& url =
+      web_contents()->GetMainFrame()->GetLastCommittedOrigin().GetURL();
 
   // If the extension requested the host permission to |url| but had it
   // withheld, we grant it active tab-style permissions, even if it doesn't have
@@ -185,7 +185,7 @@
     if (!util::AllowFileAccess(extension->id(), browser_context)) {
       valid_schemes &= ~URLPattern::SCHEME_FILE;
     }
-    new_hosts.AddOrigin(valid_schemes, url.DeprecatedGetOriginAsURL());
+    new_hosts.AddOrigin(valid_schemes, url);
     new_apis.insert(mojom::APIPermissionID::kTab);
 
     if (permissions_data->HasAPIPermission(
diff --git a/chrome/browser/extensions/api/vpn_provider/OWNERS b/chrome/browser/extensions/api/vpn_provider/OWNERS
index a913a05..499be61f 100644
--- a/chrome/browser/extensions/api/vpn_provider/OWNERS
+++ b/chrome/browser/extensions/api/vpn_provider/OWNERS
@@ -1,2 +1,3 @@
 bartfab@chromium.org
 emaxx@chromium.org
+greengrape@google.com
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index b6e4df3..5280289 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -117,7 +117,6 @@
     &shared_highlighting::kSharedHighlightingAmp,
     &features::kElasticOverscroll,
     &features::kElidePrioritizationOfPreNativeBootstrapTasks,
-    &features::kElideTabPreloadAtStartup,
     &features::kGiveJavaUiThreadDefaultTaskTraitsUserBlockingPriority,
     &features::kPrivacyGuide,
     &features::kPushMessagingDisallowSenderIDs,
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
index 637bfda..11eb8762 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
@@ -58,7 +58,6 @@
                     .put(ChromeFeatureList.EARLY_LIBRARY_LOAD, true)
                     .put(ChromeFeatureList.ELASTIC_OVERSCROLL, true)
                     .put(ChromeFeatureList.ELIDE_PRIORITIZATION_OF_PRE_NATIVE_BOOTSTRAP_TASKS, true)
-                    .put(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP, true)
                     .put(ChromeFeatureList
                                     .GIVE_JAVA_UI_THREAD_DEFAULT_TASK_TRAITS_USER_BLOCKING_PRIORITY,
                             false)
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 8aa7e2c..ab455bf 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
@@ -332,7 +332,6 @@
     public static final String EARLY_LIBRARY_LOAD = "EarlyLibraryLoad";
     public static final String ELIDE_PRIORITIZATION_OF_PRE_NATIVE_BOOTSTRAP_TASKS =
             "ElidePrioritizationOfPreNativeBootstrapTasks";
-    public static final String ELIDE_TAB_PRELOAD_AT_STARTUP = "ElideTabPreloadAtStartup";
     public static final String ENABLE_AUTOMATIC_SNOOZE = "EnableAutomaticSnooze";
     public static final String ELASTIC_OVERSCROLL = "ElasticOverscroll";
     public static final String EXPERIMENTS_FOR_AGSA = "ExperimentsForAgsa";
diff --git a/chrome/browser/nearby_sharing/nearby_notification_manager_unittest.cc b/chrome/browser/nearby_sharing/nearby_notification_manager_unittest.cc
index 7ec1c8f..f7a7faf 100644
--- a/chrome/browser/nearby_sharing/nearby_notification_manager_unittest.cc
+++ b/chrome/browser/nearby_sharing/nearby_notification_manager_unittest.cc
@@ -579,7 +579,7 @@
 
 TEST_P(NearbyNotificationManagerTest, ShowProgress_DeviceNameEncoding) {
   ShareTarget share_target;
-  share_target.device_name = u8"\xf0\x9f\x8c\xb5";  // Cactus emoji.
+  share_target.device_name = "🌵";
   TransferMetadata transfer_metadata =
       TransferMetadataBuilder().set_progress(75.0).build();
 
@@ -869,7 +869,7 @@
 TEST_P(NearbyNotificationManagerTest,
        ShowConnectionRequest_DeviceNameEncoding) {
   ShareTarget share_target;
-  share_target.device_name = u8"\xf0\x9f\x8c\xb5";  // Cactus emoji.
+  share_target.device_name = "🌵";
 
   manager()->ShowConnectionRequest(share_target,
                                    TransferMetadataBuilder().build());
@@ -1017,7 +1017,7 @@
 
 TEST_P(NearbyNotificationManagerTest, ShowSuccess_DeviceNameEncoding) {
   ShareTarget share_target;
-  share_target.device_name = u8"\xf0\x9f\x8c\xb5";  // Cactus emoji.
+  share_target.device_name = "🌵";
 
   manager()->ShowSuccess(share_target);
   std::vector<message_center::Notification> notifications =
@@ -1036,7 +1036,7 @@
 
 TEST_P(NearbyNotificationManagerTest, ShowCancelled_DeviceNameEncoding) {
   ShareTarget share_target;
-  share_target.device_name = u8"\xf0\x9f\x8c\xb5";  // Cactus emoji.
+  share_target.device_name = "🌵";
 
   manager()->ShowCancelled(share_target);
   std::vector<message_center::Notification> notifications =
@@ -1069,7 +1069,7 @@
 
 TEST_P(NearbyNotificationManagerTest, ShowFailure_DeviceNameEncoding) {
   ShareTarget share_target;
-  share_target.device_name = u8"\xf0\x9f\x8c\xb5";  // Cactus emoji.
+  share_target.device_name = "🌵";
 
   manager()->ShowFailure(share_target, TransferMetadataBuilder().build());
   std::vector<message_center::Notification> notifications =
diff --git a/chrome/browser/net/system_network_context_manager.cc b/chrome/browser/net/system_network_context_manager.cc
index 0269a741..dbac783 100644
--- a/chrome/browser/net/system_network_context_manager.cc
+++ b/chrome/browser/net/system_network_context_manager.cc
@@ -124,7 +124,7 @@
   kMaxValue = kDisabledBecauseOfFailedLaunch
 };
 
-// The global instance of the SystemNetworkContextmanager.
+// The global instance of the SystemNetworkContextManager.
 SystemNetworkContextManager* g_system_network_context_manager = nullptr;
 
 // Whether or not any instance of the system network context manager has
@@ -216,7 +216,7 @@
 #endif
   // Note: intentionally checking the feature state here rather than falling
   // back to CertVerifierImpl::kDefault, as browser-side network context
-  // initializition for TrialComparisonCertVerifier depends on knowing which
+  // initialization for TrialComparisonCertVerifier depends on knowing which
   // verifier will be used.
   return base::FeatureList::IsEnabled(
       net::features::kCertVerifierBuiltinFeature);
@@ -229,7 +229,7 @@
 bool ShouldUseChromeRootStore(PrefService* local_state) {
   // Note: intentionally checking the feature state here rather than falling
   // back to ChromeRootImpl::kRootDefault, as browser-side network context
-  // initializition for TrialComparisonCertVerifier depends on knowing which
+  // initialization for TrialComparisonCertVerifier depends on knowing which
   // verifier will be used.
   return base::FeatureList::IsEnabled(net::features::kChromeRootStoreUsed);
 }
diff --git a/chrome/browser/net/system_network_context_manager.h b/chrome/browser/net/system_network_context_manager.h
index bcfa282..52bd8ae 100644
--- a/chrome/browser/net/system_network_context_manager.h
+++ b/chrome/browser/net/system_network_context_manager.h
@@ -111,7 +111,7 @@
   void DisableQuic();
 
   // Returns an mojo::PendingReceiver<SSLConfigClient> that can be passed as a
-  // NetorkContextParam.
+  // NetworkContextParam.
   mojo::PendingReceiver<network::mojom::SSLConfigClient>
   GetSSLConfigClientReceiver();
 
diff --git a/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.cc
index 5b74d44..d5256d1 100644
--- a/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.cc
@@ -22,11 +22,13 @@
     "Background";
 }  // namespace internal
 
-// TODO(https://crbug.com/1317494): Audit and use appropriate policy.
 page_load_metrics::PageLoadMetricsObserver::ObservePolicy
 DocumentWritePageLoadMetricsObserver::OnFencedFramesStart(
     content::NavigationHandle* navigation_handle,
     const GURL& currently_committed_url) {
+  // This class is interested in events that are dispatched only for the primary
+  // page or preprocessed by PageLoadTracker to be per-outermost page. So, no
+  // need to forward events at the observer layer.
   return STOP_OBSERVING;
 }
 
diff --git a/chrome/browser/page_load_metrics/observers/https_engagement_metrics/https_engagement_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/https_engagement_metrics/https_engagement_page_load_metrics_observer.cc
index 54de87fd..1b9c04c 100644
--- a/chrome/browser/page_load_metrics/observers/https_engagement_metrics/https_engagement_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/https_engagement_metrics/https_engagement_page_load_metrics_observer.cc
@@ -19,11 +19,12 @@
       HttpsEngagementServiceFactory::GetForBrowserContext(context);
 }
 
-// TODO(https://crbug.com/1317494): Audit and use appropriate policy.
 page_load_metrics::PageLoadMetricsObserver::ObservePolicy
 HttpsEngagementPageLoadMetricsObserver::OnFencedFramesStart(
     content::NavigationHandle* navigation_handle,
     const GURL& currently_committed_url) {
+  // This class is interested only in the primary page's end of life timing,
+  // and doesn't need to continue observing FencedFrame pages.
   return STOP_OBSERVING;
 }
 
diff --git a/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer.cc
index 77c1115..96c1770 100644
--- a/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer.cc
@@ -101,11 +101,15 @@
   return CONTINUE_OBSERVING;
 }
 
-// TODO(https://crbug.com/1317494): Audit and use appropriate policy.
 page_load_metrics::PageLoadMetricsObserver::ObservePolicy
 SecurityStatePageLoadMetricsObserver::OnFencedFramesStart(
     content::NavigationHandle* navigation_handle,
     const GURL& currently_committed_url) {
+  // All data aggregation are done in SiteEngagementService and
+  // SecurityStateTabHelper, and this class just monitors the timings to record
+  // the aggregated data. As the outermost page's OnCommit and OnComplete are
+  // the timing this class is interested in, it just stops observing
+  // FencedFrames.
   return STOP_OBSERVING;
 }
 
diff --git a/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer_browsertest.cc
index 7cde8e8..a00447a 100644
--- a/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer_browsertest.cc
+++ b/chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer_browsertest.cc
@@ -665,11 +665,8 @@
   content::test::FencedFrameTestHelper fenced_frame_helper_;
 };
 
-// TODO(crbug.com/1301880): This test will be enabled after toyoshim@'s CL
-// restricts call to SecurityStatePageLoadMetricsObserver::OnCommit for fenced
-// frames"
 IN_PROC_BROWSER_TEST_F(SecurityStatePageLoadMetricsFencedFrameBrowserTest,
-                       DISABLED_DoNotRecordOnCommitSecurityLevelHistogram) {
+                       DoNotRecordOnCommitSecurityLevelHistogram) {
   StartHttpsServer(net::EmbeddedTestServer::CERT_OK);
 
   GURL https_url = https_test_server()->GetURL("/title1.html");
diff --git a/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.cc
index 15b5589c..6162a6f 100644
--- a/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.cc
@@ -106,11 +106,12 @@
 
 ServiceWorkerPageLoadMetricsObserver::ServiceWorkerPageLoadMetricsObserver() {}
 
-// TODO(https://crbug.com/1317494): Audit and use appropriate policy.
 page_load_metrics::PageLoadMetricsObserver::ObservePolicy
 ServiceWorkerPageLoadMetricsObserver::OnFencedFramesStart(
     content::NavigationHandle* navigation_handle,
     const GURL& currently_committed_url) {
+  // All events this class is interested in are preprocessed and forwarded at
+  // PageLoadTracker and observer doesn't need to care for forwarding.
   return STOP_OBSERVING;
 }
 
diff --git a/chrome/browser/page_load_metrics/observers/session_restore_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/session_restore_page_load_metrics_observer.cc
index 4ba952a..b41e0699 100644
--- a/chrome/browser/page_load_metrics/observers/session_restore_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/session_restore_page_load_metrics_observer.cc
@@ -49,11 +49,12 @@
   return CONTINUE_OBSERVING;
 }
 
-// TODO(https://crbug.com/1317494): Audit and use appropriate policy.
 page_load_metrics::PageLoadMetricsObserver::ObservePolicy
 SessionRestorePageLoadMetricsObserver::OnFencedFramesStart(
     content::NavigationHandle* navigation_handle,
     const GURL& currently_committed_url) {
+  // This class is interested only in preprocessed lifecycle events that are
+  // already dispatched also to the outermost page observer.
   return STOP_OBSERVING;
 }
 
diff --git a/chrome/browser/page_load_metrics/observers/signed_exchange_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/signed_exchange_page_load_metrics_observer.cc
index f431cb2c..6e44968 100644
--- a/chrome/browser/page_load_metrics/observers/signed_exchange_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/signed_exchange_page_load_metrics_observer.cc
@@ -104,11 +104,13 @@
 SignedExchangePageLoadMetricsObserver::SignedExchangePageLoadMetricsObserver() {
 }
 
-// TODO(https://crbug.com/1317494): Audit and use appropriate policy.
 page_load_metrics::PageLoadMetricsObserver::ObservePolicy
 SignedExchangePageLoadMetricsObserver::OnFencedFramesStart(
     content::NavigationHandle* navigation_handle,
     const GURL& currently_committed_url) {
+  // This class is interested only in events that are preprocessed and
+  // dispatched also to the outermost page at PageLoadTracker. So, this class
+  // doesn't need to forward events for FencedFrames.
   return STOP_OBSERVING;
 }
 
diff --git a/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc b/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc
index be14080e..ca2a450 100644
--- a/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc
+++ b/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc
@@ -68,9 +68,6 @@
 
 using TestEncryptionKeyAttached = MockFunction<void(SignedEncryptionInfo)>;
 
-// TODO(https://crbug.com/1297261): Change the various out params in the helper
-// functions below to return by value instead.
-
 class RecordHandlerImplTest : public ::testing::TestWithParam<
                                   ::testing::tuple</*need_encryption_key*/ bool,
                                                    /*force_confirm*/ bool>> {
diff --git a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_browsertest.cc b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_browsertest.cc
index 68508d68..be148e3 100644
--- a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_browsertest.cc
+++ b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_browsertest.cc
@@ -4246,11 +4246,14 @@
                          ukm::builders::PrefetchProxy_AfterSRPClick::
                              kSRPClickPrefetchStatusName));
 
+  // In addition to "prefetch.js" and "prefetch-redirect-start.js",
+  // "favicon.ico" is also counted here, because the favicon loading is
+  // triggered from `FrameLoader::DidFinishNavigation()` at the end of NSP.
   histogram_tester.ExpectUniqueSample(
-      "PrefetchProxy.Prefetch.Subresources.NetError", net::OK, 2);
+      "PrefetchProxy.Prefetch.Subresources.NetError", net::OK, 3);
   histogram_tester.ExpectUniqueSample(
       "PrefetchProxy.Prefetch.Subresources.Quantity", 4, 1);
-  histogram_tester.ExpectUniqueSample(
+  histogram_tester.ExpectBucketCount(
       "PrefetchProxy.Prefetch.Subresources.RespCode", 200, 2);
   histogram_tester.ExpectUniqueSample(
       "PrefetchProxy.AfterClick.Subresources.UsedCache", true, 2);
diff --git a/chrome/browser/resources/chromeos/arc_account_picker/BUILD.gn b/chrome/browser/resources/chromeos/arc_account_picker/BUILD.gn
index 785b10e..7437fca 100644
--- a/chrome/browser/resources/chromeos/arc_account_picker/BUILD.gn
+++ b/chrome/browser/resources/chromeos/arc_account_picker/BUILD.gn
@@ -67,6 +67,7 @@
   deps = [
     ":arc_account_picker_browser_proxy",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+    "//ui/webui/resources/js:load_time_data.m",
   ]
 }
 
diff --git a/chrome/browser/resources/chromeos/arc_account_picker/arc_account_picker_app.html b/chrome/browser/resources/chromeos/arc_account_picker/arc_account_picker_app.html
index 278e2a4..bd83db56 100644
--- a/chrome/browser/resources/chromeos/arc_account_picker/arc_account_picker_app.html
+++ b/chrome/browser/resources/chromeos/arc_account_picker/arc_account_picker_app.html
@@ -94,44 +94,68 @@
   #addAccountButton > .account-name > .primary {
     margin-bottom: 0;
   }
+
+  .use-two-column-layout.main-container {
+    /* Add top margin to account for the button bar and match next pages */
+    --margin-top: 96px;
+    display: flex;
+    flex-direction: row;
+    height: calc(100% - var(--margin-top));
+    margin-top: var(--margin-top);
+  }
+
+  .use-two-column-layout .column-1 {
+    flex: 1 1 0;
+    margin-inline-end: 80px;
+  }
+
+  .use-two-column-layout .column-2 {
+    flex: 1.5 1 0;
+    /* Size of the icon + margin */
+    margin-top: calc(24px + 28px);
+  }
 </style>
 
-<div class="main-container">
-  <if expr="_google_chrome">
-    <img class="google-full-logo"
-            src="chrome://theme/IDR_LOGO_GOOGLE_COLOR_90" alt="">
-  </if>
+<div class$="[[getMainContainerClass_(useTwoColumnLayout)]]">
+  <div class="column-1">
+    <if expr="_google_chrome">
+      <img class="google-full-logo"
+              src="chrome://theme/IDR_LOGO_GOOGLE_COLOR_90" alt="">
+    </if>
 
-  <h1>$i18n{accountManagerDialogArcAccountPickerTitle}</h1>
-  <p class="secondary text-body"
+    <h1>$i18n{accountManagerDialogArcAccountPickerTitle}</h1>
+    <p class="secondary text-body"
       >$i18nRaw{accountManagerDialogArcAccountPickerBody}</p>
+  </div>
 
-  <template is="dom-repeat" id="accountsContainer" items="[[accounts_]]">
-    <div class="account-item" on-click="makeAvailableInArc_"
-        on-keypress="onAccountKeyPress_"
-        tabindex="0" role="button"
-        aria-labelledby$="fullName-[[index]] email-[[index]]"
-        aria-description="$i18n{accountUseInArcButtonLabel}">
-      <div class="account-icon" aria-hidden="true"
-          style="background-image: [[getIconImageSet_(item.image)]]">
+  <div class="column-2">
+    <template is="dom-repeat" id="accountsContainer" items="[[accounts_]]">
+      <div class="account-item" on-click="makeAvailableInArc_"
+          on-keypress="onAccountKeyPress_"
+          tabindex="0" role="button"
+          aria-labelledby$="fullName-[[index]] email-[[index]]"
+          aria-description="$i18n{accountUseInArcButtonLabel}">
+        <div class="account-icon" aria-hidden="true"
+            style="background-image: [[getIconImageSet_(item.image)]]">
+        </div>
+        <div class="account-name">
+          <span class="primary" id="fullName-[[index]]"
+              aria-hidden="true">[[item.fullName]]</span>
+          <span class="secondary" id="email-[[index]]"
+              aria-hidden="true">[[item.email]]</span>
+        </div>
       </div>
-      <div class="account-name">
-        <span class="primary" id="fullName-[[index]]"
-            aria-hidden="true">[[item.fullName]]</span>
-        <span class="secondary" id="email-[[index]]"
-            aria-hidden="true">[[item.email]]</span>
-      </div>
-    </div>
-  </template>
+    </template>
 
-  <div class="account-item" id="addAccountButton" on-click="addAccount_"
-      on-keypress="onAddAccountKeyPress_" tabindex="0" role="button"
-      aria-label="$i18n{addAccountLabel}">
-    <div class="account-icon" aria-hidden="true">
-      <div class="add-icon"></div>
-    </div>
-    <div class="account-name" aria-hidden="true">
-      <span class="primary">$i18n{addAccountLabel}</span>
+    <div class="account-item" id="addAccountButton" on-click="addAccount_"
+        on-keypress="onAddAccountKeyPress_" tabindex="0" role="button"
+        aria-label="[[getAddAccountButtonLabel_(isChildUser_)]]">
+      <div class="account-icon" aria-hidden="true">
+        <div class="add-icon"></div>
+      </div>
+      <div class="account-name" aria-hidden="true">
+        <span class="primary">[[getAddAccountButtonLabel_(isChildUser_)]]</span>
+      </div>
     </div>
   </div>
 
diff --git a/chrome/browser/resources/chromeos/arc_account_picker/arc_account_picker_app.js b/chrome/browser/resources/chromeos/arc_account_picker/arc_account_picker_app.js
index 4307a37..7926fd1 100644
--- a/chrome/browser/resources/chromeos/arc_account_picker/arc_account_picker_app.js
+++ b/chrome/browser/resources/chromeos/arc_account_picker/arc_account_picker_app.js
@@ -3,9 +3,12 @@
 // found in the LICENSE file.
 
 import '../account_manager_shared_css.js';
+import '../strings.m.js';
 
 import {getImage} from '//resources/js/icon.js';
 import {html, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
+
 import {Account, ArcAccountPickerBrowserProxy, ArcAccountPickerBrowserProxyImpl} from './arc_account_picker_browser_proxy.js';
 
 /**
@@ -39,6 +42,23 @@
   static get properties() {
     return {
       /**
+       * Whether two column layout should be used.
+       * @public {boolean}
+       */
+      useTwoColumnLayout: {
+        type: Boolean,
+        value: false,
+      },
+
+      /** @private {boolean} */
+      isChildUser_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('isChild');
+        },
+      },
+
+      /**
        * Accounts which are not available in ARC and are shown on the ARC picker
        * screen.
        * @private {!Array<!Account>}
@@ -84,6 +104,27 @@
   }
 
   /**
+   * @return {string} A class name list for the main container.
+   * @private
+   */
+  getMainContainerClass_() {
+    if (this.useTwoColumnLayout) {
+      return 'main-container use-two-column-layout';
+    }
+
+    return 'main-container';
+  }
+
+  /**
+   * @return {string} A label for 'add account' button.
+   * @private
+   */
+  getAddAccountButtonLabel_() {
+    return loadTimeData.getString(
+        this.isChildUser_ ? 'addSchoolAccountLabel' : 'addAccountLabel');
+  }
+
+  /**
    * @param {string} iconUrl
    * @return {string} A CSS image-set for multiple scale factors.
    * @private
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_app.html b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_app.html
index d64cca5..51c4a90 100644
--- a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_app.html
+++ b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_app.html
@@ -6,6 +6,7 @@
    <edu-coexistence-error id="edu-coexistence-error"  slot="view">
    </edu-coexistence-error>
    <arc-account-picker-app id="arc-account-picker" slot="view"
+      use-two-column-layout="true"
       on-opened-new-window="closeDialog_"
       on-add-account="showAddAccount_">
    </arc-account-picker-app>
diff --git a/chrome/browser/resources/chromeos/login/security_token_pin_browsertest.js b/chrome/browser/resources/chromeos/login/security_token_pin_browsertest.js
index 0e41c14..c28547f 100644
--- a/chrome/browser/resources/chromeos/login/security_token_pin_browsertest.js
+++ b/chrome/browser/resources/chromeos/login/security_token_pin_browsertest.js
@@ -38,13 +38,7 @@
   }
 };
 
-// This times out regularly on debug builds, see https://crbug.com/1304295
-GEN('#if !defined(NDEBUG)');
-GEN('#define MAYBE_All DISABLED_All');
-GEN('#else');
-GEN('#define MAYBE_All All');
-GEN('#endif');
-TEST_F('PolymerSecurityTokenPinTest', 'MAYBE_All', function() {
+TEST_F('PolymerSecurityTokenPinTest', 'All', function() {
   const DEFAULT_PARAMETERS = {
     enableUserInput: true,
     hasError: false,
diff --git a/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc b/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc
index c68baea..d568be4 100644
--- a/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc
+++ b/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc
@@ -1618,7 +1618,14 @@
 }
 
 // Check that window.focus works for cross-process popups.
-IN_PROC_BROWSER_TEST_F(SitePerProcessInteractiveBrowserTest, PopupWindowFocus) {
+// Flaky on ChromeOS debug and ASAN builds. https://crbug.com/1326293
+#if BUILDFLAG(IS_CHROMEOS) && (!defined(NDEBUG) || defined(ADDRESS_SANITIZER))
+#define MAYBE_PopupWindowFocus DISABLED_PopupWindowFocus
+#else
+#define MAYBE_PopupWindowFocus PopupWindowFocus
+#endif
+IN_PROC_BROWSER_TEST_F(SitePerProcessInteractiveBrowserTest,
+                       MAYBE_PopupWindowFocus) {
   GURL main_url(embedded_test_server()->GetURL("/page_with_focus_events.html"));
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
 
diff --git a/chrome/browser/sync/test/integration/preferences_helper.cc b/chrome/browser/sync/test/integration/preferences_helper.cc
index b304972..6b7d3df1 100644
--- a/chrome/browser/sync/test/integration/preferences_helper.cc
+++ b/chrome/browser/sync/test/integration/preferences_helper.cc
@@ -75,8 +75,11 @@
   auto pref_store = base::MakeRefCounted<JsonPrefStore>(
       profile->GetPath().Append(chrome::kPreferencesFilename));
   base::ScopedAllowBlockingForTesting allow_blocking;
-  if (pref_store->ReadPrefs() != PersistentPrefStore::PREF_READ_ERROR_NONE) {
-    ADD_FAILURE() << " Failed reading the prefs file into the store.";
+  PersistentPrefStore::PrefReadError result = pref_store->ReadPrefs();
+  if (result != PersistentPrefStore::PREF_READ_ERROR_NONE) {
+    ADD_FAILURE()
+        << " Failed reading the prefs file into the store, error code "
+        << result;
   }
 
   return pref_store;
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 2b055fcf..90f0551 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -3339,8 +3339,8 @@
       "views/hats/hats_next_web_dialog.h",
       "views/privacy_sandbox/privacy_sandbox_dialog_view.cc",
       "views/privacy_sandbox/privacy_sandbox_dialog_view.h",
-      "views/privacy_sandbox/privacy_sandbox_notice_bubble_view.cc",
-      "views/privacy_sandbox/privacy_sandbox_notice_bubble_view.h",
+      "views/privacy_sandbox/privacy_sandbox_notice_bubble.cc",
+      "views/privacy_sandbox/privacy_sandbox_notice_bubble.h",
       "views/profiles/incognito_menu_view.cc",
       "views/profiles/incognito_menu_view.h",
       "views/profiles/profile_menu_view_base.cc",
diff --git a/chrome/browser/ui/views/payments/payment_request_use_stats_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_use_stats_browsertest.cc
index ef0ec58..88ed7e96c 100644
--- a/chrome/browser/ui/views/payments/payment_request_use_stats_browsertest.cc
+++ b/chrome/browser/ui/views/payments/payment_request_use_stats_browsertest.cc
@@ -6,6 +6,8 @@
 
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/scoped_feature_list.h"
+#include "build/build_config.h"
+#include "build/buildflag.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/views/payments/payment_request_browsertest_base.h"
 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h"
@@ -224,7 +226,14 @@
 
 // Tests that use stats for the contact address used in a Payment Request are
 // properly updated upon completion.
-IN_PROC_BROWSER_TEST_F(PaymentRequestContactAddressUseStatsTest, RecordUse) {
+// TODO(crbug.com/1328016): Flaky on Linux, investigate and re-enable.
+#if BUILDFLAG(IS_LINUX)
+#define MAYBE_RecordUse DISABLED_RecordUse
+#else
+#define MAYBE_RecordUse RecordUse
+#endif
+IN_PROC_BROWSER_TEST_F(PaymentRequestContactAddressUseStatsTest,
+                       MAYBE_RecordUse) {
   NavigateTo("/payment_request_name_test.html");
   autofill::TestAutofillClock test_clock;
   test_clock.SetNow(kSomeDate);
@@ -348,8 +357,11 @@
 
 // Tests that use stats for an address that was used both as a shipping and
 // contact address in a Payment Request are properly updated upon completion.
+// TODO(crbug.com/1328016): Flaky on Linux, investigate and re-enable.
+// MAYBE_RecordUse defined above (PaymentRequestContactAddressUseStatsTest
+// fixture).
 IN_PROC_BROWSER_TEST_F(PaymentRequestSameShippingAndContactAddressUseStatsTest,
-                       RecordUse) {
+                       MAYBE_RecordUse) {
   NavigateTo("/payment_request_contact_details_and_free_shipping_test.html");
   autofill::TestAutofillClock test_clock;
   test_clock.SetNow(kSomeDate);
diff --git a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble.cc b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble.cc
new file mode 100644
index 0000000..fe009be
--- /dev/null
+++ b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble.cc
@@ -0,0 +1,135 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble.h"
+
+#include "chrome/browser/privacy_sandbox/privacy_sandbox_service.h"
+#include "chrome/browser/privacy_sandbox/privacy_sandbox_service_factory.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/chrome_pages.h"
+#include "chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt.h"
+#include "chrome/browser/ui/views/bubble_anchor_util_views.h"
+#include "chrome/grit/generated_resources.h"
+#include "chrome/grit/theme_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/views/bubble/bubble_dialog_model_host.h"
+
+using PromptAction = PrivacySandboxService::PromptAction;
+
+namespace {
+
+class PrivacySandboxNoticeBubbleModelDelegate : public ui::DialogModelDelegate {
+ public:
+  explicit PrivacySandboxNoticeBubbleModelDelegate(Browser* browser)
+      : browser_(browser) {
+    if (auto* privacy_sandbox_serivce =
+            PrivacySandboxServiceFactory::GetForProfile(browser_->profile())) {
+      privacy_sandbox_serivce->DialogOpenedForBrowser(browser_);
+    }
+    NotifyServiceAboutPromptAction(PromptAction::kNoticeShown);
+  }
+
+  void OnDialogDestroying() {
+    if (!has_user_interacted_) {
+      NotifyServiceAboutPromptAction(PromptAction::kNoticeClosedNoInteraction);
+    }
+    if (auto* privacy_sandbox_serivce =
+            PrivacySandboxServiceFactory::GetForProfile(browser_->profile())) {
+      privacy_sandbox_serivce->DialogClosedForBrowser(browser_);
+    }
+  }
+
+  void OnOkButtonPressed() {
+    has_user_interacted_ = true;
+    NotifyServiceAboutPromptAction(PromptAction::kNoticeAcknowledge);
+  }
+
+  void OnSettingsLinkPressed() {
+    has_user_interacted_ = true;
+    chrome::ShowPrivacySandboxSettings(browser_);
+    NotifyServiceAboutPromptAction(PromptAction::kNoticeOpenSettings);
+  }
+
+  void OnLearnMoreLinkPressed() {
+    has_user_interacted_ = true;
+    chrome::ShowPrivacySandboxLearnMore(browser_);
+    NotifyServiceAboutPromptAction(PromptAction::kNoticeLearnMore);
+  }
+
+  void OnDialogExplicitlyClosed() {
+    if (!has_user_interacted_) {
+      NotifyServiceAboutPromptAction(PromptAction::kNoticeDismiss);
+    }
+    has_user_interacted_ = true;
+  }
+
+  void NotifyServiceAboutPromptAction(PromptAction action) {
+    if (auto* service =
+            PrivacySandboxServiceFactory::GetForProfile(browser_->profile())) {
+      service->PromptActionOccurred(action);
+    }
+  }
+
+ private:
+  Browser* browser_;
+  bool has_user_interacted_ = false;
+};
+
+}  // namespace
+
+// static
+void ShowPrivacySandboxNoticeBubble(Browser* browser) {
+  auto bubble_delegate_unique =
+      std::make_unique<PrivacySandboxNoticeBubbleModelDelegate>(browser);
+  PrivacySandboxNoticeBubbleModelDelegate* bubble_delegate =
+      bubble_delegate_unique.get();
+  auto& bundle = ui::ResourceBundle::GetSharedInstance();
+  auto dialog_model =
+      ui::DialogModel::Builder(std::move(bubble_delegate_unique))
+          .SetTitle(l10n_util::GetStringUTF16(
+              IDS_PRIVACY_SANDBOX_BUBBLE_NOTICE_TITLE))
+          .SetInternalName(kPrivacySandboxNoticeBubbleName)
+          .SetIcon(ui::ImageModel::FromImageSkia(*bundle.GetImageSkiaNamed(
+                       IDR_PRIVACY_SANDBOX_CONFIRMATION_BANNER)),
+                   ui::ImageModel::FromImageSkia(*bundle.GetImageSkiaNamed(
+                       IDR_PRIVACY_SANDBOX_CONFIRMATION_BANNER_DARK)))
+          .AddBodyText(ui::DialogModelLabel::CreateWithLink(
+              IDS_PRIVACY_SANDBOX_BUBBLE_NOTICE_DESCRIPTION,
+              ui::DialogModelLabel::Link(
+                  IDS_PRIVACY_SANDBOX_BUBBLE_NOTICE_DESCRIPTION_ESTIMATES_INTERESTS_LINK,
+                  base::BindRepeating(&PrivacySandboxNoticeBubbleModelDelegate::
+                                          OnLearnMoreLinkPressed,
+                                      base::Unretained(bubble_delegate)))))
+          .AddOkButton(
+              base::BindRepeating(
+                  &PrivacySandboxNoticeBubbleModelDelegate::OnOkButtonPressed,
+                  base::Unretained(bubble_delegate)),
+              l10n_util::GetStringUTF16(
+                  IDS_PRIVACY_SANDBOX_DIALOG_NOTICE_ACKNOWLEDGE_BUTTON))
+          .AddExtraLink(ui::DialogModelLabel::Link(
+              IDS_PRIVACY_SANDBOX_BUBBLE_NOTICE_SETTINGS_LINK,
+              base::BindRepeating(&PrivacySandboxNoticeBubbleModelDelegate::
+                                      OnSettingsLinkPressed,
+                                  base::Unretained(bubble_delegate))))
+          .SetCloseActionCallback(
+              base::BindOnce(&PrivacySandboxNoticeBubbleModelDelegate::
+                                 OnDialogExplicitlyClosed,
+                             base::Unretained(bubble_delegate)))
+          .SetDialogDestroyingCallback(base::BindOnce(
+              &PrivacySandboxNoticeBubbleModelDelegate::OnDialogDestroying,
+              base::Unretained(bubble_delegate)))
+          .Build();
+
+  bubble_anchor_util::AnchorConfiguration configuration =
+      bubble_anchor_util::GetAppMenuAnchorConfiguration(browser);
+  auto bubble = std::make_unique<views::BubbleDialogModelHost>(
+      std::move(dialog_model), configuration.anchor_view,
+      configuration.bubble_arrow);
+  // The bubble isn't opened as a result of a user action. It shouldn't take the
+  // focus away from the current tasks. Open the bubble starting as inactive
+  // also avoids unintentionally closing it due to focus loss until the user has
+  // interacted with it. After a user interaction, it may be closed on focus
+  // loss.
+  views::BubbleDialogDelegate::CreateBubble(std::move(bubble))->ShowInactive();
+}
diff --git a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble.h b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble.h
new file mode 100644
index 0000000..58e37bb
--- /dev/null
+++ b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble.h
@@ -0,0 +1,11 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_PRIVACY_SANDBOX_PRIVACY_SANDBOX_NOTICE_BUBBLE_H_
+#define CHROME_BROWSER_UI_VIEWS_PRIVACY_SANDBOX_PRIVACY_SANDBOX_NOTICE_BUBBLE_H_
+
+static constexpr char kPrivacySandboxNoticeBubbleName[] =
+    "PrivacySandboxNoticeBubble";
+
+#endif  // CHROME_BROWSER_UI_VIEWS_PRIVACY_SANDBOX_PRIVACY_SANDBOX_NOTICE_BUBBLE_H_
diff --git a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_view_browsertest.cc b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_browsertest.cc
similarity index 82%
rename from chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_view_browsertest.cc
rename to chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_browsertest.cc
index 4ca2773..73dc469 100644
--- a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_browsertest.cc
@@ -13,8 +13,11 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/test/test_browser_dialog.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_view.h"
+#include "chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble.h"
+#include "chrome/common/webui_url_constants.h"
+#include "chrome/test/base/ui_test_utils.h"
 #include "components/privacy_sandbox/privacy_sandbox_features.h"
+#include "components/privacy_sandbox/privacy_sandbox_prefs.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -28,15 +31,14 @@
 namespace {
 
 views::Widget* ShowBubble(Browser* browser) {
-  views::NamedWidgetShownWaiter waiter(
-      views::test::AnyWidgetTestPasskey{},
-      PrivacySandboxNoticeBubbleView::kViewClassName);
+  views::NamedWidgetShownWaiter waiter(views::test::AnyWidgetTestPasskey{},
+                                       kPrivacySandboxNoticeBubbleName);
   ShowPrivacySandboxPrompt(browser, PrivacySandboxService::PromptType::kNotice);
   return waiter.WaitIfNeededAndGet();
 }
 
 void ClickButton(views::BubbleDialogDelegate* bubble_delegate,
-                 views::Button* button) {
+                 views::View* button) {
   // Reset the timer to make sure that test click isn't discarded as possibly
   // unintended.
   bubble_delegate->ResetViewShownTimeStampForTesting();
@@ -50,7 +52,7 @@
 
 }  // namespace
 
-class PrivacySandboxNoticeBubbleViewBrowserTest : public DialogBrowserTest {
+class PrivacySandboxNoticeBubbleBrowserTest : public DialogBrowserTest {
  public:
   void SetUpOnMainThread() override {
     mock_service_ = static_cast<MockPrivacySandboxService*>(
@@ -89,7 +91,7 @@
   base::test::ScopedFeatureList feature_list_;
 };
 
-IN_PROC_BROWSER_TEST_F(PrivacySandboxNoticeBubbleViewBrowserTest,
+IN_PROC_BROWSER_TEST_F(PrivacySandboxNoticeBubbleBrowserTest,
                        InvokeUi_NoticeBubble) {
   EXPECT_CALL(
       *mock_service(),
@@ -101,7 +103,7 @@
   ShowAndVerifyUi();
 }
 
-IN_PROC_BROWSER_TEST_F(PrivacySandboxNoticeBubbleViewBrowserTest,
+IN_PROC_BROWSER_TEST_F(PrivacySandboxNoticeBubbleBrowserTest,
                        EscapeClosesNotice) {
   // Check that when the escape key is pressed, the notice bubble is closed.
   EXPECT_CALL(
@@ -120,8 +122,10 @@
   VerifyBubbleWasClosed(bubble);
 }
 
-IN_PROC_BROWSER_TEST_F(PrivacySandboxNoticeBubbleViewBrowserTest,
-                       AppMenuClosesNotice) {
+// TODO(crbug.com/1321587): Figure out what to do with the bubble when the app
+// menu is shown. Update the test to test that.
+IN_PROC_BROWSER_TEST_F(PrivacySandboxNoticeBubbleBrowserTest,
+                       DISABLED_AppMenuClosesNotice) {
   // Check that when the app menu is opened, the notice bubble is closed.
   EXPECT_CALL(
       *mock_service(),
@@ -139,7 +143,7 @@
   VerifyBubbleWasClosed(bubble);
 }
 
-IN_PROC_BROWSER_TEST_F(PrivacySandboxNoticeBubbleViewBrowserTest,
+IN_PROC_BROWSER_TEST_F(PrivacySandboxNoticeBubbleBrowserTest,
                        AcknowledgeNotice) {
   EXPECT_CALL(
       *mock_service(),
@@ -159,7 +163,7 @@
   VerifyBubbleWasClosed(bubble);
 }
 
-IN_PROC_BROWSER_TEST_F(PrivacySandboxNoticeBubbleViewBrowserTest,
+IN_PROC_BROWSER_TEST_F(PrivacySandboxNoticeBubbleBrowserTest,
                        OpenSettingsNotice) {
   EXPECT_CALL(
       *mock_service(),
@@ -175,12 +179,15 @@
 
   auto* bubble = ShowBubble(browser());
   auto* bubble_delegate = bubble->widget_delegate()->AsBubbleDialogDelegate();
-  ClickButton(bubble_delegate, bubble_delegate->GetCancelButton());
-  VerifyBubbleWasClosed(bubble);
+  ClickButton(bubble_delegate, bubble_delegate->GetExtraView());
+  // TODO(crbug.com/1321587): Bubble should be closed. Figure out why opening
+  // settings page doesn't take over the focus (only in tests).
 }
 
-IN_PROC_BROWSER_TEST_F(PrivacySandboxNoticeBubbleViewBrowserTest,
-                       OpenLearnMoreNotice) {
+// TODO(crbug.com/1321587, crbug.com/1327190): Update how the link is accessed
+// after the API for DialogModel is added.
+IN_PROC_BROWSER_TEST_F(PrivacySandboxNoticeBubbleBrowserTest,
+                       DISABLED_OpenLearnMoreNotice) {
   EXPECT_CALL(
       *mock_service(),
       PromptActionOccurred(PrivacySandboxService::PromptAction::kNoticeShown));
@@ -194,9 +201,6 @@
       .Times(0);
 
   auto* bubble = ShowBubble(browser());
-  auto* label =
-      static_cast<views::StyledLabel*>(bubble->GetRootView()->GetViewByID(
-          PrivacySandboxNoticeBubbleView::kNoticeLearnMoreLinkId));
-  label->ClickLinkForTesting();
+  // TODO(crbug.com/1321587): Get the link from the bubble and click on it.
   VerifyBubbleWasClosed(bubble);
 }
diff --git a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_view.cc b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_view.cc
deleted file mode 100644
index e14f947..0000000
--- a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_view.cc
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_view.h"
-
-#include "chrome/browser/privacy_sandbox/privacy_sandbox_service.h"
-#include "chrome/browser/privacy_sandbox/privacy_sandbox_service_factory.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/chrome_pages.h"
-#include "chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt.h"
-#include "chrome/browser/ui/views/accessibility/theme_tracking_non_accessible_image_view.h"
-#include "chrome/browser/ui/views/bubble_anchor_util_views.h"
-#include "chrome/browser/ui/views/chrome_layout_provider.h"
-#include "chrome/browser/ui/views/frame/app_menu_button.h"
-#include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
-#include "chrome/grit/generated_resources.h"
-#include "chrome/grit/theme_resources.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/metadata/metadata_impl_macros.h"
-#include "ui/views/bubble/bubble_dialog_delegate_view.h"
-#include "ui/views/controls/label.h"
-#include "ui/views/controls/styled_label.h"
-#include "ui/views/layout/box_layout.h"
-#include "ui/views/view_class_properties.h"
-
-using PromptAction = PrivacySandboxService::PromptAction;
-
-namespace {
-
-constexpr int kDialogWidth = 448;
-
-void NotifyServiceAboutPromptAction(Profile* profile, PromptAction action) {
-  if (auto* service = PrivacySandboxServiceFactory::GetForProfile(profile)) {
-    service->PromptActionOccurred(action);
-  }
-}
-
-AppMenuButton* GetAppMenuButton(Browser* browser) {
-  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
-  // The notice bubble is anchored to the browser. If the browser is destroyed,
-  // the bubble will be too. Because of that browser should always be present
-  // while bubble is active.
-  DCHECK(browser_view);
-  return browser_view->toolbar_button_provider()->GetAppMenuButton();
-}
-
-class PrivacySandboxNoticeBubbleDelegate : public views::BubbleDialogDelegate {
- public:
-  explicit PrivacySandboxNoticeBubbleDelegate(
-      bubble_anchor_util::AnchorConfiguration configuration,
-      Browser* browser)
-      : BubbleDialogDelegate(configuration.anchor_view,
-                             configuration.bubble_arrow),
-        browser_(browser) {
-    if (auto* privacy_sandbox_serivce =
-            PrivacySandboxServiceFactory::GetForProfile(browser->profile())) {
-      privacy_sandbox_serivce->DialogOpenedForBrowser(browser);
-    }
-    SetCloseCallback(base::BindOnce(
-        &PrivacySandboxNoticeBubbleDelegate::OnClose, base::Unretained(this)));
-  }
-
-  void OnClose() {
-    if (auto* privacy_sandbox_serivce =
-            PrivacySandboxServiceFactory::GetForProfile(browser_->profile())) {
-      privacy_sandbox_serivce->DialogClosedForBrowser(browser_);
-    }
-  }
-
-  void WindowClosing() override {
-    switch (GetWidget()->closed_reason()) {
-      case views::Widget::ClosedReason::kEscKeyPressed:
-        NotifyServiceAboutPromptAction(browser_->profile(),
-                                       PromptAction::kNoticeDismiss);
-        break;
-      case views::Widget::ClosedReason::kUnspecified:
-        NotifyServiceAboutPromptAction(
-            browser_->profile(), PromptAction::kNoticeClosedNoInteraction);
-        break;
-      default:
-        break;
-    }
-  }
-
- private:
-  Browser* browser_;
-};
-
-}  // namespace
-
-// static
-void ShowPrivacySandboxNoticeBubble(Browser* browser) {
-  auto bubble_delegate = std::make_unique<PrivacySandboxNoticeBubbleDelegate>(
-      bubble_anchor_util::GetAppMenuAnchorConfiguration(browser), browser);
-  bubble_delegate->SetShowTitle(false);
-  bubble_delegate->SetShowCloseButton(false);
-  bubble_delegate->set_close_on_deactivate(false);
-  bubble_delegate->set_margins(
-      ChromeLayoutProvider::Get()->GetInsetsMetric(views::INSETS_DIALOG));
-  bubble_delegate->set_fixed_width(
-      ChromeLayoutProvider::Get()->GetSnappedDialogWidth(kDialogWidth));
-
-  bubble_delegate->SetButtonLabel(
-      ui::DIALOG_BUTTON_OK,
-      l10n_util::GetStringUTF16(
-          IDS_PRIVACY_SANDBOX_DIALOG_NOTICE_ACKNOWLEDGE_BUTTON));
-  bubble_delegate->SetAcceptCallback(base::BindOnce(
-      [](Browser* browser) {
-        NotifyServiceAboutPromptAction(browser->profile(),
-                                       PromptAction::kNoticeAcknowledge);
-      },
-      base::Unretained(browser)));
-
-  bubble_delegate->SetButtonLabel(
-      ui::DIALOG_BUTTON_CANCEL,
-      l10n_util::GetStringUTF16(
-          IDS_PRIVACY_SANDBOX_DIALOG_NOTICE_OPEN_SETTINGS_BUTTON));
-  bubble_delegate->SetCancelCallback(base::BindOnce(
-      [](Browser* browser) {
-        chrome::ShowPrivacySandboxSettings(browser);
-        NotifyServiceAboutPromptAction(browser->profile(),
-                                       PromptAction::kNoticeOpenSettings);
-      },
-      base::Unretained(browser)));
-
-  auto& bundle = ui::ResourceBundle::GetSharedInstance();
-  auto image = std::make_unique<ThemeTrackingNonAccessibleImageView>(
-      *bundle.GetImageSkiaNamed(IDR_PRIVACY_SANDBOX_CONFIRMATION_BANNER),
-      *bundle.GetImageSkiaNamed(IDR_PRIVACY_SANDBOX_CONFIRMATION_BANNER_DARK),
-      base::BindRepeating(&views::BubbleDialogDelegate::GetBackgroundColor,
-                          base::Unretained(bubble_delegate.get())));
-
-  bubble_delegate->SetContentsView(
-      std::make_unique<PrivacySandboxNoticeBubbleView>(browser,
-                                                       std::move(image)));
-  views::BubbleDialogDelegate::CreateBubble(std::move(bubble_delegate))->Show();
-}
-
-PrivacySandboxNoticeBubbleView::PrivacySandboxNoticeBubbleView(
-    Browser* browser,
-    std::unique_ptr<views::View> image)
-    : browser_(browser) {
-  SetLayoutManager(std::make_unique<views::BoxLayout>(
-                       views::BoxLayout::Orientation::kHorizontal))
-      ->set_cross_axis_alignment(views::BoxLayout::CrossAxisAlignment::kStart);
-
-  // Add image view, that was created with the reference to bubble delegate to
-  // support changing color for the theme.
-  AddChildView(std::move(image));
-
-  // Set up the container for the right side. It contains a title and a
-  // description.
-  auto* container = AddChildView(std::make_unique<views::View>());
-  container->SetLayoutManager(std::make_unique<views::BoxLayout>(
-      views::BoxLayout::Orientation::kVertical, gfx::Insets(),
-      ChromeLayoutProvider::Get()->GetDistanceMetric(
-          DISTANCE_CONTENT_LIST_VERTICAL_SINGLE)));
-  container->SetProperty(
-      views::kMarginsKey,
-      gfx::Insets::TLBR(0,
-                        ChromeLayoutProvider::Get()->GetDistanceMetric(
-                            views::DISTANCE_RELATED_LABEL_HORIZONTAL),
-                        0, 0));
-
-  // Create the title view.
-  auto* title_label = container->AddChildView(std::make_unique<views::Label>(
-      l10n_util::GetStringUTF16(IDS_PRIVACY_SANDBOX_BUBBLE_NOTICE_TITLE),
-      views::style::CONTEXT_DIALOG_TITLE));
-  title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-  title_label->SetFontList(
-      views::style::GetFont(views::style::TextContext::CONTEXT_DIALOG_TITLE,
-                            views::style::TextStyle::STYLE_PRIMARY)
-          .DeriveWithWeight(gfx::Font::Weight::MEDIUM));
-
-  // Create the description view.
-  auto* description_label =
-      container->AddChildView(std::make_unique<views::StyledLabel>());
-  description_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-  description_label->SetID(kNoticeLearnMoreLinkId);
-  // The description contains a link that opens settings page. Find the position
-  // of the link by inserting text into the placeholder.
-  auto intesets_settings_link = l10n_util::GetStringUTF16(
-      IDS_PRIVACY_SANDBOX_BUBBLE_NOTICE_DESCRIPTION_ESTIMATES_INTERESTS_LINK);
-  size_t offset;
-  description_label->SetText(
-      l10n_util::GetStringFUTF16(IDS_PRIVACY_SANDBOX_BUBBLE_NOTICE_DESCRIPTION,
-                                 intesets_settings_link, &offset));
-  gfx::Range range(offset, offset + intesets_settings_link.length());
-  views::StyledLabel::RangeStyleInfo link_style =
-      views::StyledLabel::RangeStyleInfo::CreateForLink(base::BindRepeating(
-          &PrivacySandboxNoticeBubbleView::OpenAboutAdPersonalizationSettings,
-          base::Unretained(this)));
-  description_label->AddStyleRange(range, link_style);
-
-  // Observe app menu button to close the bubble when app menu is shown.
-  if (auto* app_menu_button = GetAppMenuButton(browser_)) {
-    app_menu_button->AddObserver(this);
-  }
-
-  NotifyServiceAboutPromptAction(browser_->profile(),
-                                 PromptAction::kNoticeShown);
-}
-
-PrivacySandboxNoticeBubbleView::~PrivacySandboxNoticeBubbleView() {
-  if (auto* app_menu_button = GetAppMenuButton(browser_)) {
-    app_menu_button->RemoveObserver(this);
-  }
-}
-
-void PrivacySandboxNoticeBubbleView::AppMenuShown() {
-  NotifyServiceAboutPromptAction(browser_->profile(),
-                                 PromptAction::kNoticeDismiss);
-  GetWidget()->CloseWithReason(views::Widget::ClosedReason::kLostFocus);
-}
-
-void PrivacySandboxNoticeBubbleView::OpenAboutAdPersonalizationSettings() {
-  chrome::ShowPrivacySandboxLearnMore(browser_);
-  NotifyServiceAboutPromptAction(browser_->profile(),
-                                 PromptAction::kNoticeLearnMore);
-  GetWidget()->CloseWithReason(
-      views::Widget::ClosedReason::kCancelButtonClicked);
-}
-
-BEGIN_METADATA(PrivacySandboxNoticeBubbleView, views::View)
-END_METADATA
diff --git a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_view.h b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_view.h
deleted file mode 100644
index 3477c618..0000000
--- a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_view.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_PRIVACY_SANDBOX_PRIVACY_SANDBOX_NOTICE_BUBBLE_VIEW_H_
-#define CHROME_BROWSER_UI_VIEWS_PRIVACY_SANDBOX_PRIVACY_SANDBOX_NOTICE_BUBBLE_VIEW_H_
-
-#include "chrome/browser/ui/views/frame/app_menu_button_observer.h"
-#include "ui/base/metadata/metadata_header_macros.h"
-#include "ui/views/view.h"
-
-class Browser;
-
-// Content view of PrivacySandboxDialog notice UI. The bubble is anchored to
-// three-dot menu. It contains image, title, description and action buttons.
-class PrivacySandboxNoticeBubbleView : public views::View,
-                                       public AppMenuButtonObserver {
- public:
-  METADATA_HEADER(PrivacySandboxNoticeBubbleView);
-
-  PrivacySandboxNoticeBubbleView(Browser* browser,
-                                 std::unique_ptr<views::View> image);
-  ~PrivacySandboxNoticeBubbleView() override;
-
-  // AppMenuButtonObserver:
-  void AppMenuShown() override;
-
- protected:
-  FRIEND_TEST_ALL_PREFIXES(PrivacySandboxNoticeBubbleViewBrowserTest,
-                           OpenLearnMoreNotice);
-  // View ID of the description label that contains "Learn more" link. Used for
-  // testing.
-  static constexpr int kNoticeLearnMoreLinkId = 1;
-
- private:
-  void OpenAboutAdPersonalizationSettings();
-
-  raw_ptr<Browser> browser_;
-};
-
-#endif  // CHROME_BROWSER_UI_VIEWS_PRIVACY_SANDBOX_PRIVACY_SANDBOX_NOTICE_BUBBLE_VIEW_H_
diff --git a/chrome/browser/ui/web_applications/web_app_launch_utils.cc b/chrome/browser/ui/web_applications/web_app_launch_utils.cc
index 6c447f4..c355bc8 100644
--- a/chrome/browser/ui/web_applications/web_app_launch_utils.cc
+++ b/chrome/browser/ui/web_applications/web_app_launch_utils.cc
@@ -4,18 +4,25 @@
 
 #include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
 
-#include "base/feature_list.h"
+#include <atomic>
+
+#include "base/check.h"
+#include "base/check_op.h"
+#include "base/memory/raw_ptr.h"
+#include "base/metrics/histogram_base.h"
 #include "base/metrics/histogram_macros.h"
-#include "base/strings/string_util.h"
-#include "base/trace_event/base_tracing.h"
+#include "base/metrics/histogram_macros_internal.h"
+#include "base/one_shot_event.h"
+#include "base/time/time.h"
+#include "base/trace_event/typed_macros.h"
+#include "base/tracing/protos/chrome_track_event.pbzero.h"
+#include "build/buildflag.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/app_mode/app_mode_utils.h"
-#include "chrome/browser/buildflags.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sessions/app_session_service.h"
 #include "chrome/browser/sessions/app_session_service_factory.h"
 #include "chrome/browser/sessions/session_service_base.h"
-#include "chrome/browser/sessions/session_service_factory.h"
 #include "chrome/browser/sessions/session_service_lookup.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
@@ -29,20 +36,25 @@
 #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h"
 #include "chrome/browser/ui/web_applications/web_app_browser_controller.h"
 #include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h"
+#include "chrome/browser/web_applications/web_app_constants.h"
 #include "chrome/browser/web_applications/web_app_helpers.h"
+#include "chrome/browser/web_applications/web_app_install_utils.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/browser/web_applications/web_app_sync_bridge.h"
 #include "chrome/browser/web_applications/web_app_tab_helper.h"
-#include "chrome/common/chrome_features.h"
-#include "components/omnibox/browser/location_bar_model.h"
+#include "chrome/browser/web_applications/web_app_utils.h"
 #include "components/site_engagement/content/site_engagement_service.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/common/content_features.h"
+#include "extensions/buildflags/buildflags.h"
 #include "extensions/common/constants.h"
 #include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h"
+#include "ui/base/page_transition_types.h"
+#include "ui/base/ui_base_types.h"
+#include "ui/base/window_open_disposition.h"
 #include "url/gurl.h"
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
@@ -114,11 +126,6 @@
       web_contents->GetMainFrame()->GetLastCommittedURL());
 }
 
-bool IsInScope(const GURL& url, const GURL& scope) {
-  return base::StartsWith(url.spec(), scope.spec(),
-                          base::CompareCase::SENSITIVE);
-}
-
 void PrunePreScopeNavigationHistory(const GURL& scope,
                                     content::WebContents* contents) {
   content::NavigationController& navigation_controller =
diff --git a/chrome/browser/ui/web_applications/web_app_launch_utils.h b/chrome/browser/ui/web_applications/web_app_launch_utils.h
index 9b77e86..7f3cc48 100644
--- a/chrome/browser/ui/web_applications/web_app_launch_utils.h
+++ b/chrome/browser/ui/web_applications/web_app_launch_utils.h
@@ -5,11 +5,12 @@
 #ifndef CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_LAUNCH_UTILS_H_
 #define CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_LAUNCH_UTILS_H_
 
+#include <stdint.h>
 #include <memory>
 #include <string>
 
 #include "chrome/browser/web_applications/web_app_id.h"
-#include "components/services/app_service/public/mojom/types.mojom-forward.h"
+#include "components/services/app_service/public/mojom/types.mojom-shared.h"
 #include "extensions/common/constants.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/rect.h"
@@ -30,8 +31,6 @@
 
 absl::optional<AppId> GetWebAppForActiveTab(Browser* browser);
 
-bool IsInScope(const GURL& url, const GURL& scope_spec);
-
 // Clears navigation history prior to user entering app scope.
 void PrunePreScopeNavigationHistory(const GURL& scope,
                                     content::WebContents* contents);
diff --git a/chrome/browser/ui/web_applications/web_share_target_browsertest.cc b/chrome/browser/ui/web_applications/web_share_target_browsertest.cc
index 9872ac4..3b1ab9c6 100644
--- a/chrome/browser/ui/web_applications/web_share_target_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_share_target_browsertest.cc
@@ -185,6 +185,7 @@
         file_system_context.get(),
         /*origin=*/GURL(),
         /*file_type=*/chromeos::RecentModel::FileType::kAll,
+        /*invalidate_cache=*/false,
         base::BindLambdaForTesting(
             [&result,
              &run_loop](const std::vector<chromeos::RecentFile>& files) {
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_concept.h b/chrome/browser/ui/webui/settings/chromeos/search/search_concept.h
index 156e6c81..7fbeb7d 100644
--- a/chrome/browser/ui/webui/settings/chromeos/search/search_concept.h
+++ b/chrome/browser/ui/webui/settings/chromeos/search/search_concept.h
@@ -25,9 +25,6 @@
   static constexpr size_t kMaxAltTagsPerConcept = 5;
   static constexpr int kAltTagEnd = 0;
 
-  SearchConcept(const SearchConcept& other) = default;
-  SearchConcept& operator=(const SearchConcept& other) = default;
-
   // Message ID (from os_settings_search_tag_strings.grdp) corresponding to the
   // canonical search tag for this concept.
   int canonical_message_id;
diff --git a/chrome/browser/ui/webui/signin/inline_login_ui.cc b/chrome/browser/ui/webui/signin/inline_login_ui.cc
index f530b8c..bff59693d 100644
--- a/chrome/browser/ui/webui/signin/inline_login_ui.cc
+++ b/chrome/browser/ui/webui/signin/inline_login_ui.cc
@@ -96,6 +96,9 @@
   source->AddLocalizedString("eduCoexistenceErrorDescription",
                              IDS_EDU_COEXISTENCE_ERROR_DESCRIPTION);
   source->AddLocalizedString("loadingMessage", IDS_LOGIN_GAIA_LOADING_MESSAGE);
+  source->AddLocalizedString(
+      "addSchoolAccountLabel",
+      IDS_ACCOUNT_MANAGER_DIALOG_ADD_SCHOOL_ACCOUNT_LABEL);
 }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
@@ -283,6 +286,9 @@
             ui::GetChromeOSDeviceName()));
   }
 
+  source->AddBoolean("isChild",
+                     user_manager::UserManager::Get()->IsLoggedInAsChildUser());
+
   user_manager::User* user =
       ash::ProfileHelper::Get()->GetUserByProfile(profile);
   DCHECK(user);
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn
index dab37d9..dff8093 100644
--- a/chrome/browser/web_applications/BUILD.gn
+++ b/chrome/browser/web_applications/BUILD.gn
@@ -460,6 +460,7 @@
     "//components/keyed_service/content",
     "//components/services/app_service/public/cpp:app_update",
     "//components/services/app_service/public/cpp:app_url_handling",
+    "//components/services/app_service/public/cpp:protocol_handling",
     "//components/services/app_service/public/cpp:types",
     "//components/sync:test_support_model",
     "//components/sync_preferences:test_support",
@@ -709,6 +710,7 @@
     "//components/services/app_service/public/cpp:app_update",
     "//components/services/app_service/public/cpp:icon_types",
     "//components/services/app_service/public/cpp:intents",
+    "//components/services/app_service/public/cpp:protocol_handling",
     "//components/services/app_service/public/cpp:run_on_os_login",
     "//components/services/app_service/public/cpp:types",
     "//components/webapps/browser",
diff --git a/chrome/browser/web_applications/alternative_error_page_override_info_browsertest.cc b/chrome/browser/web_applications/alternative_error_page_override_info_browsertest.cc
index bce8375..9fddd99 100644
--- a/chrome/browser/web_applications/alternative_error_page_override_info_browsertest.cc
+++ b/chrome/browser/web_applications/alternative_error_page_override_info_browsertest.cc
@@ -14,6 +14,7 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/url_formatter/url_formatter.h"
+#include "content/public/common/alternative_error_page_override_info.mojom.h"
 #include "content/public/common/content_client.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/test_utils.h"
diff --git a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
index c12c5c9..2eccd9a6 100644
--- a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
+++ b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
@@ -4,35 +4,47 @@
 
 #include "chrome/browser/web_applications/manifest_update_manager.h"
 
+#include <ios>
 #include <map>
 #include <memory>
 #include <string>
+#include <tuple>
+#include <type_traits>
+#include <utility>
 #include <vector>
 
-#include "base/callback_helpers.h"
+#include "base/bind.h"
+#include "base/check.h"
+#include "base/check_op.h"
 #include "base/containers/contains.h"
+#include "base/containers/flat_tree.h"
+#include "base/feature_list.h"
 #include "base/memory/raw_ptr.h"
-#include "base/memory/scoped_refptr.h"
+#include "base/notreached.h"
+#include "base/numerics/clamped_math.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/run_loop.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
 #include "base/test/bind.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
+#include "build/buildflag.h"
 #include "build/chromeos_buildflags.h"
-#include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/browser_features.h"
-#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_dialogs.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
 #include "chrome/browser/web_applications/commands/fetch_manifest_and_install_command.h"
+#include "chrome/browser/web_applications/commands/web_app_command.h"
+#include "chrome/browser/web_applications/external_install_options.h"
 #include "chrome/browser/web_applications/externally_managed_app_manager.h"
+#include "chrome/browser/web_applications/manifest_update_task.h"
 #include "chrome/browser/web_applications/os_integration/os_integration_manager.h"
-#include "chrome/browser/web_applications/os_integration/web_app_file_handler_registration.h"
-#include "chrome/browser/web_applications/os_integration/web_app_shortcut_manager.h"
+#include "chrome/browser/web_applications/os_integration/web_app_shortcut.h"
 #include "chrome/browser/web_applications/system_web_apps/test/test_system_web_app_installation.h"
 #include "chrome/browser/web_applications/test/web_app_icon_test_utils.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
@@ -41,12 +53,15 @@
 #include "chrome/browser/web_applications/test/web_app_test_utils.h"
 #include "chrome/browser/web_applications/user_display_mode.h"
 #include "chrome/browser/web_applications/web_app.h"
+#include "chrome/browser/web_applications/web_app_callback_app_identity.h"
 #include "chrome/browser/web_applications/web_app_command_manager.h"
+#include "chrome/browser/web_applications/web_app_constants.h"
 #include "chrome/browser/web_applications/web_app_helpers.h"
 #include "chrome/browser/web_applications/web_app_icon_generator.h"
+#include "chrome/browser/web_applications/web_app_icon_manager.h"
+#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_install_finalizer.h"
 #include "chrome/browser/web_applications/web_app_install_info.h"
-#include "chrome/browser/web_applications/web_app_install_manager.h"
 #include "chrome/browser/web_applications/web_app_install_params.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
@@ -56,21 +71,37 @@
 #include "chrome/common/chrome_features.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #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.h"
+#include "components/services/app_service/public/cpp/file_handler.h"
+#include "components/services/app_service/public/cpp/icon_info.h"
+#include "components/services/app_service/public/cpp/protocol_handler_info.h"
+#include "components/services/app_service/public/cpp/share_target.h"
+#include "components/services/app_service/public/cpp/url_handler_info.h"
 #include "components/webapps/browser/install_result_code.h"
 #include "components/webapps/browser/installable/installable_metrics.h"
 #include "components/webapps/browser/uninstall_result_code.h"
+#include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/url_loader_interceptor.h"
-#include "extensions/browser/extension_registry.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_status_code.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/mojom/url_loader.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/features.h"
-#include "third_party/blink/public/mojom/manifest/handle_links.mojom.h"
+#include "third_party/blink/public/mojom/manifest/handle_links.mojom-shared.h"
+#include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/gfx/color_utils.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/image/image_family.h"
+#include "url/gurl.h"
+#include "url/origin.h"
 
 #if BUILDFLAG(IS_MAC)
 #include "base/mac/mac_util.h"
@@ -87,6 +118,10 @@
 #include "ash/constants/ash_features.h"
 #endif
 
+#if BUILDFLAG(IS_LINUX)
+#include "chrome/browser/web_applications/os_integration/web_app_file_handler_registration.h"
+#endif
+
 namespace web_app {
 
 namespace {
@@ -3416,6 +3451,200 @@
   EXPECT_TRUE(web_app->protocol_handlers().empty());
 }
 
+class ManifestUpdateManagerBrowserTest_LockScreen
+    : public ManifestUpdateManagerBrowserTest {
+  base::test::ScopedFeatureList feature_list_{
+      blink::features::kWebAppManifestLockScreen};
+};
+
+IN_PROC_BROWSER_TEST_F(ManifestUpdateManagerBrowserTest_LockScreen,
+                       CheckFindsAddedLockScreenStartUrl) {
+  constexpr char kManifestTemplate[] = R"(
+    {
+      "name": "Test app name",
+      "start_url": ".",
+      "scope": "/",
+      "display": "minimal-ui",
+      "icons": $1
+    }
+  )";
+
+  constexpr char kLockScreenStartUrlManifestTemplate[] = R"(
+    {
+      "name": "Test app name",
+      "start_url": ".",
+      "scope": "/",
+      "display": "minimal-ui",
+      "lock_screen": {
+        "start_url": "/lock-screen-start"
+      },
+      "icons": $1
+    }
+  )";
+
+  OverrideManifest(kManifestTemplate, {kInstallableIconList});
+  AppId app_id = InstallWebApp();
+  const WebApp* web_app = GetProvider().registrar().GetAppById(app_id);
+  EXPECT_TRUE(web_app->lock_screen_start_url().is_empty());
+
+  OverrideManifest(kLockScreenStartUrlManifestTemplate, {kInstallableIconList});
+  EXPECT_EQ(ManifestUpdateResult::kAppUpdated,
+            GetResultAfterPageLoad(GetAppURL()));
+  histogram_tester_.ExpectBucketCount(kUpdateHistogramName,
+                                      ManifestUpdateResult::kAppUpdated, 1);
+  EXPECT_EQ(http_server_.GetURL("/lock-screen-start"),
+            web_app->lock_screen_start_url().spec());
+}
+
+IN_PROC_BROWSER_TEST_F(ManifestUpdateManagerBrowserTest_LockScreen,
+                       CheckIgnoresUnchangedLockScreenStartUrl) {
+  constexpr char kLockScreenStartUrlManifestTemplate[] = R"(
+    {
+      "name": "Test app name",
+      "start_url": ".",
+      "scope": "/",
+      "display": "minimal-ui",
+      "lock_screen": {
+        "start_url": "/lock-screen-start"
+      },
+      "icons": $1
+    }
+  )";
+
+  OverrideManifest(kLockScreenStartUrlManifestTemplate, {kInstallableIconList});
+  AppId app_id = InstallWebApp();
+  const WebApp* web_app = GetProvider().registrar().GetAppById(app_id);
+  EXPECT_EQ(http_server_.GetURL("/lock-screen-start"),
+            web_app->lock_screen_start_url().spec());
+
+  OverrideManifest(kLockScreenStartUrlManifestTemplate, {kInstallableIconList});
+  EXPECT_EQ(ManifestUpdateResult::kAppUpToDate,
+            GetResultAfterPageLoad(GetAppURL()));
+  histogram_tester_.ExpectBucketCount(kUpdateHistogramName,
+                                      ManifestUpdateResult::kAppUpToDate, 1);
+  EXPECT_EQ(http_server_.GetURL("/lock-screen-start"),
+            web_app->lock_screen_start_url().spec());
+}
+
+IN_PROC_BROWSER_TEST_F(ManifestUpdateManagerBrowserTest_LockScreen,
+                       CheckFindsChangedLockScreenStartUrl) {
+  constexpr char kLockScreenStartUrlManifestTemplate[] = R"(
+    {
+      "name": "Test app name",
+      "start_url": ".",
+      "scope": "/",
+      "display": "minimal-ui",
+      "lock_screen": {
+        "start_url": "$1"
+      },
+      "icons": $2
+    }
+  )";
+
+  OverrideManifest(kLockScreenStartUrlManifestTemplate,
+                   {"old-relative-url", kInstallableIconList});
+  AppId app_id = InstallWebApp();
+  const WebApp* web_app = GetProvider().registrar().GetAppById(app_id);
+  // URL parsed relative to manifest URL, which is in /banners/.
+  EXPECT_EQ(http_server_.GetURL("/banners/old-relative-url"),
+            web_app->lock_screen_start_url().spec());
+
+  OverrideManifest(kLockScreenStartUrlManifestTemplate,
+                   {"/lock-screen-starter", kInstallableIconList});
+  EXPECT_EQ(ManifestUpdateResult::kAppUpdated,
+            GetResultAfterPageLoad(GetAppURL()));
+  histogram_tester_.ExpectBucketCount(kUpdateHistogramName,
+                                      ManifestUpdateResult::kAppUpdated, 1);
+  EXPECT_EQ(http_server_.GetURL("/lock-screen-starter"),
+            web_app->lock_screen_start_url().spec());
+}
+
+IN_PROC_BROWSER_TEST_F(ManifestUpdateManagerBrowserTest_LockScreen,
+                       CheckFindsDeletedLockScreenStartUrl) {
+  constexpr char kLockScreenStartUrlManifestTemplate[] = R"(
+    {
+      "name": "Test app name",
+      "start_url": ".",
+      "scope": "/",
+      "display": "minimal-ui",
+      "lock_screen": {
+        "start_url": "/lock-screen-start"
+      },
+      "icons": $1
+    }
+  )";
+
+  constexpr char kManifestTemplate[] = R"(
+    {
+      "name": "Test app name",
+      "start_url": ".",
+      "scope": "/",
+      "display": "minimal-ui",
+      "icons": $1
+    }
+  )";
+
+  OverrideManifest(kLockScreenStartUrlManifestTemplate, {kInstallableIconList});
+  AppId app_id = InstallWebApp();
+  const WebApp* web_app = GetProvider().registrar().GetAppById(app_id);
+  EXPECT_FALSE(web_app->lock_screen_start_url().is_empty());
+
+  OverrideManifest(kManifestTemplate, {kInstallableIconList});
+  EXPECT_EQ(ManifestUpdateResult::kAppUpdated,
+            GetResultAfterPageLoad(GetAppURL()));
+  histogram_tester_.ExpectBucketCount(kUpdateHistogramName,
+                                      ManifestUpdateResult::kAppUpdated, 1);
+  EXPECT_TRUE(web_app->lock_screen_start_url().is_empty());
+}
+
+class ManifestUpdateManagerBrowserTest_NoLockScreen
+    : public ManifestUpdateManagerBrowserTest {
+ public:
+  ManifestUpdateManagerBrowserTest_NoLockScreen() {
+    feature_list_.InitAndDisableFeature(
+        blink::features::kWebAppManifestLockScreen);
+  }
+  base::test::ScopedFeatureList feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(ManifestUpdateManagerBrowserTest_NoLockScreen,
+                       WithoutLockScreenFlag_CheckIgnoresLockScreenStartUrl) {
+  constexpr char kManifestTemplate[] = R"(
+    {
+      "name": "Test app name",
+      "start_url": ".",
+      "scope": "/",
+      "display": "minimal-ui",
+      "icons": $1
+    }
+  )";
+
+  constexpr char kLockScreenStartUrlManifestTemplate[] = R"(
+    {
+      "name": "Test app name",
+      "start_url": ".",
+      "scope": "/",
+      "display": "minimal-ui",
+      "lock_screen": {
+        "start_url": "/lock-screen-start"
+      },
+      "icons": $1
+    }
+  )";
+
+  OverrideManifest(kManifestTemplate, {kInstallableIconList});
+  AppId app_id = InstallWebApp();
+  const WebApp* web_app = GetProvider().registrar().GetAppById(app_id);
+  EXPECT_TRUE(web_app->lock_screen_start_url().is_empty());
+
+  OverrideManifest(kLockScreenStartUrlManifestTemplate, {kInstallableIconList});
+  EXPECT_EQ(ManifestUpdateResult::kAppUpToDate,
+            GetResultAfterPageLoad(GetAppURL()));
+  histogram_tester_.ExpectBucketCount(kUpdateHistogramName,
+                                      ManifestUpdateResult::kAppUpToDate, 1);
+  EXPECT_TRUE(web_app->lock_screen_start_url().is_empty());
+}
+
 IN_PROC_BROWSER_TEST_F(ManifestUpdateManagerBrowserTest,
                        CheckFindsAddedNewNoteUrl) {
   constexpr char kManifestTemplate[] = R"(
diff --git a/chrome/browser/web_applications/manifest_update_task.cc b/chrome/browser/web_applications/manifest_update_task.cc
index 2ab0f1bc..febb8fd 100644
--- a/chrome/browser/web_applications/manifest_update_task.cc
+++ b/chrome/browser/web_applications/manifest_update_task.cc
@@ -387,6 +387,12 @@
   if (install_info_->url_handlers != app->url_handlers())
     return true;
 
+  if (base::FeatureList::IsEnabled(
+          blink::features::kWebAppManifestLockScreen) &&
+      install_info_->lock_screen_start_url != app->lock_screen_start_url()) {
+    return true;
+  }
+
   if (install_info_->note_taking_new_note_url !=
       app->note_taking_new_note_url()) {
     return true;
diff --git a/chrome/browser/web_applications/proto/web_app.proto b/chrome/browser/web_applications/proto/web_app.proto
index ee11410..0f2557bc 100644
--- a/chrome/browser/web_applications/proto/web_app.proto
+++ b/chrome/browser/web_applications/proto/web_app.proto
@@ -346,4 +346,7 @@
   // The amount of storage (in bytes) used by the app and its related data.
   optional uint64 app_size_in_bytes = 54;
   optional uint64 data_size_in_bytes = 55;
+
+  // If present, the URL to use to launch the app on the lock screen.
+  optional string lock_screen_start_url = 56;
 }
diff --git a/chrome/browser/web_applications/test/web_app_test_utils.cc b/chrome/browser/web_applications/test/web_app_test_utils.cc
index 3b9171d..34ba680 100644
--- a/chrome/browser/web_applications/test/web_app_test_utils.cc
+++ b/chrome/browser/web_applications/test/web_app_test_utils.cc
@@ -4,32 +4,67 @@
 
 #include "chrome/browser/web_applications/test/web_app_test_utils.h"
 
+#include <algorithm>
+#include <cstdint>
+#include <ostream>
 #include <random>
+#include <set>
+#include <string>
+#include <type_traits>
+#include <utility>
+#include <vector>
 
+#include "base/bind.h"
+#include "base/check.h"
+#include "base/check_op.h"
+#include "base/containers/flat_map.h"
+#include "base/containers/flat_set.h"
 #include "base/json/json_reader.h"
+#include "base/location.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/numerics/clamped_math.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/run_loop.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/task/single_thread_task_runner.h"
 #include "base/test/bind.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/web_applications/test/web_app_test_observers.h"
 #include "chrome/browser/web_applications/user_display_mode.h"
+#include "chrome/browser/web_applications/web_app.h"
+#include "chrome/browser/web_applications/web_app_chromeos_data.h"
 #include "chrome/browser/web_applications/web_app_constants.h"
 #include "chrome/browser/web_applications/web_app_helpers.h"
 #include "chrome/browser/web_applications/web_app_install_info.h"
 #include "chrome/browser/web_applications/web_app_utils.h"
 #include "chrome/common/pref_names.h"
+#include "components/prefs/pref_service.h"
+#include "components/services/app_service/public/cpp/file_handler.h"
+#include "components/services/app_service/public/cpp/icon_info.h"
+#include "components/services/app_service/public/cpp/protocol_handler_info.h"
+#include "components/services/app_service/public/cpp/share_target.h"
 #include "components/services/app_service/public/cpp/url_handler_info.h"
-#include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "components/webapps/browser/installable/installable_metrics.h"
 #include "content/public/browser/service_worker_context.h"
 #include "content/public/browser/storage_partition.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/manifest/manifest.h"
+#include "third_party/blink/public/common/permissions_policy/permissions_policy.h"
 #include "third_party/blink/public/common/permissions_policy/policy_helper_public.h"
+#include "third_party/blink/public/common/storage_key/storage_key.h"
+#include "third_party/blink/public/mojom/manifest/capture_links.mojom-shared.h"
+#include "third_party/blink/public/mojom/manifest/handle_links.mojom-shared.h"
+#include "third_party/skia/include/core/SkColor.h"
 #include "url/gurl.h"
+#include "url/origin.h"
 
 namespace {
 
@@ -428,6 +463,10 @@
   app->SetProtocolHandlers(CreateRandomProtocolHandlers(random.next_uint()));
   app->SetUrlHandlers(CreateRandomUrlHandlers(random.next_uint()));
   if (random.next_bool()) {
+    app->SetLockScreenStartUrl(scope.Resolve(
+        "lock_screen_start_url" + base::NumberToString(random.next_uint())));
+  }
+  if (random.next_bool()) {
     app->SetNoteTakingNewNoteUrl(
         scope.Resolve("new_note" + base::NumberToString(random.next_uint())));
   }
diff --git a/chrome/browser/web_applications/test/web_app_test_utils.h b/chrome/browser/web_applications/test/web_app_test_utils.h
index af752c8..1b7585e4 100644
--- a/chrome/browser/web_applications/test/web_app_test_utils.h
+++ b/chrome/browser/web_applications/test/web_app_test_utils.h
@@ -5,16 +5,19 @@
 #ifndef CHROME_BROWSER_WEB_APPLICATIONS_TEST_WEB_APP_TEST_UTILS_H_
 #define CHROME_BROWSER_WEB_APPLICATIONS_TEST_WEB_APP_TEST_UTILS_H_
 
+#include <stdint.h>
 #include <memory>
 
-#include "chrome/browser/web_applications/web_app.h"
+#include "base/strings/string_piece_forward.h"
+#include "chrome/browser/web_applications/web_app_constants.h"
+#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_install_params.h"
-#include "chrome/browser/web_applications/web_app_install_utils.h"
 #include "content/public/browser/service_worker_context.h"
+#include "url/gurl.h"
 
-struct WebAppInstallInfo;
 class Browser;
-class GURL;
+class Profile;
+struct WebAppInstallInfo;
 
 namespace content {
 class StoragePartition;
@@ -22,6 +25,9 @@
 }  // namespace content
 
 namespace web_app {
+
+class WebApp;
+
 namespace test {
 
 std::unique_ptr<WebApp> CreateWebApp(
diff --git a/chrome/browser/web_applications/web_app.cc b/chrome/browser/web_applications/web_app.cc
index 78965d7..2f9ee3d 100644
--- a/chrome/browser/web_applications/web_app.cc
+++ b/chrome/browser/web_applications/web_app.cc
@@ -286,6 +286,11 @@
   url_handlers_ = std::move(url_handlers);
 }
 
+void WebApp::SetLockScreenStartUrl(const GURL& lock_screen_start_url) {
+  DCHECK(lock_screen_start_url.is_empty() || lock_screen_start_url.is_valid());
+  lock_screen_start_url_ = lock_screen_start_url;
+}
+
 void WebApp::SetNoteTakingNewNoteUrl(const GURL& note_taking_new_note_url) {
   DCHECK(note_taking_new_note_url.is_empty() ||
          note_taking_new_note_url.is_valid());
@@ -507,6 +512,7 @@
         app.allowed_launch_protocols_,
         app.disallowed_launch_protocols_,
         app.url_handlers_,
+        app.lock_screen_start_url_,
         app.note_taking_new_note_url_,
         app.last_badging_time_,
         app.last_launch_time_,
@@ -731,6 +737,9 @@
 
   root.SetStringKey("manifest_url", ConvertToString(manifest_url_));
 
+  root.SetStringKey("lock_screen_start_url",
+                    ConvertToString(lock_screen_start_url_));
+
   root.SetStringKey("note_taking_new_note_url",
                     ConvertToString(note_taking_new_note_url_));
 
diff --git a/chrome/browser/web_applications/web_app.h b/chrome/browser/web_applications/web_app.h
index d0ca130..67bb1ad 100644
--- a/chrome/browser/web_applications/web_app.h
+++ b/chrome/browser/web_applications/web_app.h
@@ -180,6 +180,10 @@
     return disallowed_launch_protocols_;
   }
 
+  // URL within scope to launch for a "show on lock screen" action. Valid iff
+  // this is considered a lock-screen-capable app.
+  const GURL& lock_screen_start_url() const { return lock_screen_start_url_; }
+
   // URL within scope to launch for a "new note" action. Valid iff this is
   // considered a note-taking app.
   const GURL& note_taking_new_note_url() const {
@@ -350,6 +354,7 @@
   void SetDisallowedLaunchProtocols(
       base::flat_set<std::string> disallowed_launch_protocols);
   void SetUrlHandlers(apps::UrlHandlers url_handlers);
+  void SetLockScreenStartUrl(const GURL& lock_screen_start_url);
   void SetNoteTakingNewNoteUrl(const GURL& note_taking_new_note_url);
   void SetLastBadgingTime(const base::Time& time);
   void SetLastLaunchTime(const base::Time& time);
@@ -434,6 +439,7 @@
   base::flat_set<std::string> allowed_launch_protocols_;
   base::flat_set<std::string> disallowed_launch_protocols_;
   apps::UrlHandlers url_handlers_;
+  GURL lock_screen_start_url_;
   GURL note_taking_new_note_url_;
   base::Time last_badging_time_;
   base::Time last_launch_time_;
@@ -485,7 +491,9 @@
   //  - WebAppDatabase::CreateWebApp()
   //  - WebAppDatabase::CreateWebAppProto()
   //  - CreateRandomWebApp()
+  // If parsed from manifest, also add to:
   //  - ManifestUpdateTask::IsUpdateNeededForManifest()
+  //  - SetWebAppManifestFields()
 };
 
 // For logging and debug purposes.
diff --git a/chrome/browser/web_applications/web_app_database.cc b/chrome/browser/web_applications/web_app_database.cc
index a2fe38e..bbbf16a 100644
--- a/chrome/browser/web_applications/web_app_database.cc
+++ b/chrome/browser/web_applications/web_app_database.cc
@@ -603,6 +603,11 @@
     url_handler_proto->set_has_origin_wildcard(url_handler.has_origin_wildcard);
   }
 
+  if (web_app.lock_screen_start_url().is_valid()) {
+    local_data->set_lock_screen_start_url(
+        web_app.lock_screen_start_url().spec());
+  }
+
   if (web_app.note_taking_new_note_url().is_valid()) {
     local_data->set_note_taking_new_note_url(
         web_app.note_taking_new_note_url().spec());
@@ -1139,6 +1144,10 @@
   }
   web_app->SetUrlHandlers(std::move(url_handlers));
 
+  if (local_data.has_lock_screen_start_url()) {
+    web_app->SetLockScreenStartUrl(GURL(local_data.lock_screen_start_url()));
+  }
+
   if (local_data.has_note_taking_new_note_url()) {
     web_app->SetNoteTakingNewNoteUrl(
         GURL(local_data.note_taking_new_note_url()));
diff --git a/chrome/browser/web_applications/web_app_install_info.h b/chrome/browser/web_applications/web_app_install_info.h
index 19324bb8..6e96223 100644
--- a/chrome/browser/web_applications/web_app_install_info.h
+++ b/chrome/browser/web_applications/web_app_install_info.h
@@ -294,6 +294,10 @@
   // information.
   apps::UrlHandlers url_handlers;
 
+  // URL within scope to launch on the lock screen for a "show on lock screen"
+  // action. Valid iff this is considered a lock-screen-capable app.
+  GURL lock_screen_start_url;
+
   // URL within scope to launch for a "new note" action. Valid iff this is
   // considered a note-taking app.
   GURL note_taking_new_note_url;
diff --git a/chrome/browser/web_applications/web_app_install_utils.cc b/chrome/browser/web_applications/web_app_install_utils.cc
index 17655066..344a33f 100644
--- a/chrome/browser/web_applications/web_app_install_utils.cc
+++ b/chrome/browser/web_applications/web_app_install_utils.cc
@@ -35,7 +35,10 @@
 #include "chrome/browser/web_applications/os_integration/os_integration_manager.h"
 #include "chrome/browser/web_applications/os_integration/web_app_file_handler_manager.h"
 #include "chrome/browser/web_applications/web_app.h"
+#include "chrome/browser/web_applications/web_app_chromeos_data.h"
 #include "chrome/browser/web_applications/web_app_icon_generator.h"
+#include "chrome/browser/web_applications/web_app_install_params.h"
+#include "chrome/browser/web_applications/web_app_system_web_app_data.h"
 #include "chrome/browser/web_applications/web_app_utils.h"
 #include "chrome/common/chrome_features.h"
 #include "components/services/app_service/public/cpp/icon_info.h"
@@ -542,7 +545,19 @@
 
   web_app_info->url_handlers = ToWebAppUrlHandlers(manifest.url_handlers);
 
-  if (manifest.note_taking && manifest.note_taking->new_note_url.is_valid()) {
+  GURL inferred_scope = web_app_info->scope.is_valid() ? web_app_info->scope
+                        : web_app_info->start_url.is_valid()
+                            ? web_app_info->start_url.GetWithoutFilename()
+                            : GURL();
+  if (base::FeatureList::IsEnabled(
+          blink::features::kWebAppManifestLockScreen) &&
+      manifest.lock_screen && manifest.lock_screen->start_url.is_valid() &&
+      IsInScope(manifest.lock_screen->start_url, inferred_scope)) {
+    web_app_info->lock_screen_start_url = manifest.lock_screen->start_url;
+  }
+
+  if (manifest.note_taking && manifest.note_taking->new_note_url.is_valid() &&
+      IsInScope(manifest.note_taking->new_note_url, inferred_scope)) {
     web_app_info->note_taking_new_note_url = manifest.note_taking->new_note_url;
   }
 
@@ -952,6 +967,10 @@
   web_app.SetShareTarget(web_app_info.share_target);
   web_app.SetProtocolHandlers(web_app_info.protocol_handlers);
   web_app.SetUrlHandlers(web_app_info.url_handlers);
+
+  if (base::FeatureList::IsEnabled(blink::features::kWebAppManifestLockScreen))
+    web_app.SetLockScreenStartUrl(web_app_info.lock_screen_start_url);
+
   web_app.SetNoteTakingNewNoteUrl(web_app_info.note_taking_new_note_url);
 
   web_app.SetCaptureLinks(web_app_info.capture_links);
diff --git a/chrome/browser/web_applications/web_app_install_utils.h b/chrome/browser/web_applications/web_app_install_utils.h
index 1d8d6b0..91944be 100644
--- a/chrome/browser/web_applications/web_app_install_utils.h
+++ b/chrome/browser/web_applications/web_app_install_utils.h
@@ -13,7 +13,6 @@
 #include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_install_finalizer.h"
 #include "chrome/browser/web_applications/web_app_install_info.h"
-#include "chrome/browser/web_applications/web_app_install_params.h"
 #include "components/services/app_service/public/cpp/file_handler.h"
 #include "third_party/blink/public/mojom/manifest/manifest.mojom-forward.h"
 
@@ -38,6 +37,7 @@
 
 class WebApp;
 class WebAppRegistrar;
+struct WebAppInstallParams;
 
 enum class ForInstallableSite {
   kYes,
diff --git a/chrome/browser/web_applications/web_app_install_utils_unittest.cc b/chrome/browser/web_applications/web_app_install_utils_unittest.cc
index c402e99..b8ecf07 100644
--- a/chrome/browser/web_applications/web_app_install_utils_unittest.cc
+++ b/chrome/browser/web_applications/web_app_install_utils_unittest.cc
@@ -96,8 +96,10 @@
 }  // namespace
 
 TEST(WebAppInstallUtils, UpdateWebAppInfoFromManifest) {
-  base::test::ScopedFeatureList feature_list(
-      blink::features::kFileHandlingIcons);
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures({blink::features::kFileHandlingIcons,
+                                 blink::features::kWebAppManifestLockScreen},
+                                /*disabled_features=*/{});
 
   WebAppInstallInfo web_app_info;
   web_app_info.title = kAlternativeAppTestTitle;
@@ -113,7 +115,6 @@
   manifest.scope = kAppUrl.GetWithoutFilename();
   manifest.short_name = kAppTestShortName;
 
-  const GURL kFileHandlingIcon("fav1.png");
   {
     auto handler = blink::mojom::ManifestFileHandler::New();
     handler->action = GURL("http://example.com/open-files");
@@ -121,7 +122,7 @@
     handler->name = u"Images";
     {
       blink::Manifest::ImageResource icon;
-      icon.src = kFileHandlingIcon;
+      icon.src = GURL("fav1.png");
       icon.purpose = {Purpose::ANY, Purpose::MONOCHROME};
       handler->icons.push_back(icon);
     }
@@ -155,7 +156,8 @@
   }
 
   {
-    // Ensure an empty NoteTaking struct is ignored.
+    // Ensure empty structs are ignored.
+    manifest.lock_screen = blink::mojom::ManifestLockScreen::New();
     manifest.note_taking = blink::mojom::ManifestNoteTaking::New();
   }
 
@@ -167,6 +169,7 @@
   EXPECT_EQ(DisplayMode::kBrowser, web_app_info.display_mode);
   EXPECT_TRUE(web_app_info.display_override.empty());
   EXPECT_EQ(kAppManifestUrl, web_app_info.manifest_url);
+  EXPECT_TRUE(web_app_info.lock_screen_start_url.is_empty());
   EXPECT_TRUE(web_app_info.note_taking_new_note_url.is_empty());
 
   // The icon info from |web_app_info| should be left as is, since the manifest
@@ -199,9 +202,16 @@
   manifest.display_override.push_back(DisplayMode::kStandalone);
 
   {
+    auto lock_screen = blink::mojom::ManifestLockScreen::New();
+    lock_screen->start_url =
+        GURL("http://www.chromium.org/lock-screen-start-url");
+    manifest.lock_screen = std::move(lock_screen);
+  }
+
+  {
     // Update with a valid new_note_url.
     auto note_taking = blink::mojom::ManifestNoteTaking::New();
-    note_taking->new_note_url = GURL("http://example.com/new-note-url");
+    note_taking->new_note_url = GURL("http://www.chromium.org/new-note-url");
     manifest.note_taking = std::move(note_taking);
   }
 
@@ -240,7 +250,11 @@
   EXPECT_EQ(url_handler.origin,
             url::Origin::Create(GURL("https://url_handlers_origin.com/")));
   EXPECT_FALSE(url_handler.has_origin_wildcard);
-  EXPECT_EQ(GURL("http://example.com/new-note-url"),
+
+  EXPECT_EQ(GURL("http://www.chromium.org/lock-screen-start-url"),
+            web_app_info.lock_screen_start_url);
+
+  EXPECT_EQ(GURL("http://www.chromium.org/new-note-url"),
             web_app_info.note_taking_new_note_url);
 
   // Check permissions policy was updated.
@@ -391,8 +405,8 @@
 
 // Tests that WebAppInfo is correctly updated when Manifest contains Shortcuts.
 TEST(WebAppInstallUtils, UpdateWebAppInfoFromManifestWithShortcuts) {
-  base::test::ScopedFeatureList feature_list;
-  feature_list.InitWithFeatures({blink::features::kFileHandlingIcons}, {});
+  base::test::ScopedFeatureList feature_list(
+      blink::features::kFileHandlingIcons);
 
   WebAppInstallInfo web_app_info;
   web_app_info.title = kAlternativeAppTestTitle;
@@ -408,7 +422,6 @@
   manifest.scope = kAppUrl.GetWithoutFilename();
   manifest.short_name = kAppTestShortName;
 
-  const GURL kFileHandlingIcon("fav1.png");
   {
     auto handler = blink::mojom::ManifestFileHandler::New();
     handler->action = GURL("http://example.com/open-files");
@@ -416,7 +429,7 @@
     handler->name = u"Images";
     {
       blink::Manifest::ImageResource icon;
-      icon.src = kFileHandlingIcon;
+      icon.src = GURL("fav1.png");
       icon.purpose = {Purpose::ANY, Purpose::MONOCHROME};
       handler->icons.push_back(icon);
     }
@@ -692,6 +705,67 @@
   EXPECT_EQ(2U, all_icons.size());
 }
 
+TEST(WebAppInstallUtils,
+     UpdateWebAppInfoFromManifest_CrossOriginUrls_DropsFields) {
+  base::test::ScopedFeatureList feature_list(
+      blink::features::kWebAppManifestLockScreen);
+
+  WebAppInstallInfo install_info;
+
+  blink::mojom::Manifest manifest;
+  const GURL kAppUrl("http://www.chromium.org/index.html");
+  manifest.start_url = kAppUrl;
+  manifest.scope = kAppUrl.GetWithoutFilename();
+
+  {
+    auto lock_screen = blink::mojom::ManifestLockScreen::New();
+    lock_screen->start_url =
+        GURL("http://www.some-other-origin.com/lock-screen-start-url");
+    manifest.lock_screen = std::move(lock_screen);
+  }
+
+  {
+    auto note_taking = blink::mojom::ManifestNoteTaking::New();
+    note_taking->new_note_url =
+        GURL("http://www.some-other-origin.com/new-note-url");
+    manifest.note_taking = std::move(note_taking);
+  }
+
+  UpdateWebAppInfoFromManifest(
+      manifest, GURL("http://www.chromium.org/manifest.json"), &install_info);
+
+  EXPECT_EQ(kAppUrl, install_info.start_url);
+  EXPECT_TRUE(install_info.lock_screen_start_url.is_empty());
+  EXPECT_TRUE(install_info.note_taking_new_note_url.is_empty());
+}
+
+TEST(WebAppInstallUtils,
+     UpdateWebAppInfoFromManifest_WithoutLockscreenFlag_DropsField) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndDisableFeature(
+      blink::features::kWebAppManifestLockScreen);
+
+  WebAppInstallInfo install_info;
+
+  blink::mojom::Manifest manifest;
+  const GURL kAppUrl("http://www.chromium.org/index.html");
+  manifest.start_url = kAppUrl;
+  manifest.scope = kAppUrl.GetWithoutFilename();
+
+  {
+    auto lock_screen = blink::mojom::ManifestLockScreen::New();
+    lock_screen->start_url =
+        GURL("http://www.chromium.org/lock-screen-start-url");
+    manifest.lock_screen = std::move(lock_screen);
+  }
+
+  UpdateWebAppInfoFromManifest(
+      manifest, GURL("http://www.chromium.org/manifest.json"), &install_info);
+
+  EXPECT_EQ(kAppUrl, install_info.start_url);
+  EXPECT_TRUE(install_info.lock_screen_start_url.is_empty());
+}
+
 // Tests that SkBitmaps associated with shortcut item icons are populated in
 // their own map in web_app_info.
 TEST(WebAppInstallUtils, PopulateShortcutItemIcons) {
@@ -951,7 +1025,7 @@
 class FileHandlersFromManifestTest : public ::testing::TestWithParam<bool> {
  public:
   FileHandlersFromManifestTest() {
-    feature_list_.InitWithFeatures({blink::features::kFileHandlingIcons}, {});
+    feature_list_.InitAndEnableFeature(blink::features::kFileHandlingIcons);
     WebAppFileHandlerManager::SetIconsSupportedByOsForTesting(GetParam());
   }
 
@@ -1137,8 +1211,8 @@
 class RegisterOsSettingsTest : public testing::Test {
  public:
   RegisterOsSettingsTest() {
-    feature_list_.InitWithFeatures(
-        {features::kEnableWebAppUninstallFromOsSettings}, {});
+    feature_list_.InitAndEnableFeature(
+        features::kEnableWebAppUninstallFromOsSettings);
   }
   ~RegisterOsSettingsTest() override = default;
 
diff --git a/chrome/browser/web_applications/web_app_unittest.cc b/chrome/browser/web_applications/web_app_unittest.cc
index 2a6074c..be51ba2d 100644
--- a/chrome/browser/web_applications/web_app_unittest.cc
+++ b/chrome/browser/web_applications/web_app_unittest.cc
@@ -171,18 +171,18 @@
    "!app_id": "empty_app",
    "!name": "",
    "additional_search_terms": [  ],
+   "allowed_launch_protocols": [  ],
    "app_service_icon_url": "chrome://app-icon/empty_app/32",
    "app_size_in_bytes": "",
-   "allowed_launch_protocols": [  ],
    "background_color": "none",
-   "dark_mode_theme_color": "none",
-   "dark_mode_background_color": "none",
-   "data_size_in_bytes": "",
    "capture_links": "kUndefined",
    "chromeos_data": null,
    "client_data": {
       "system_web_app_data": null
    },
+   "dark_mode_background_color": "none",
+   "dark_mode_theme_color": "none",
+   "data_size_in_bytes": "",
    "description": "",
    "disallowed_launch_protocols": [  ],
    "display_mode": "",
@@ -196,12 +196,11 @@
    "file_handler_approval_state": "kRequiresPrompt",
    "file_handler_os_integration_state": "kDisabled",
    "file_handlers": [  ],
-   "manifest_icons": [  ],
    "handle_links": "kUndefined",
-   "install_time": "1601-01-01 00:00:00.000 UTC",
    "install_source_for_metrics": "not set",
-   "is_generated_icon": false,
+   "install_time": "1601-01-01 00:00:00.000 UTC",
    "is_from_sync_and_pending_installation": false,
+   "is_generated_icon": false,
    "is_locally_installed": true,
    "is_storage_isolated": false,
    "is_uninstalling": false,
@@ -209,7 +208,10 @@
    "last_launch_time": "1601-01-01 00:00:00.000 UTC",
    "launch_handler": null,
    "launch_query_params": null,
-   "management_type_to_external_configuration_map": {},
+   "lock_screen_start_url": "",
+   "management_type_to_external_configuration_map": {
+   },
+   "manifest_icons": [  ],
    "manifest_id": null,
    "manifest_update_time": "1601-01-01 00:00:00.000 UTC",
    "manifest_url": "",
@@ -247,12 +249,12 @@
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
 
   EXPECT_EQ(base::JSONReader::Read(R"JSON({
- "!app_id": "eajjdjobhihlgobdfaehiiheinneagde",
+  "!app_id": "eajjdjobhihlgobdfaehiiheinneagde",
    "!name": "Name1234",
    "additional_search_terms": [ "Foo_1234_0" ],
-   "allowed_launch_protocols": [  ],
+   "allowed_launch_protocols": [ "web+test_1234_0", "web+test_1234_1" ],
    "app_service_icon_url": "chrome://app-icon/eajjdjobhihlgobdfaehiiheinneagde/32",
-   "app_size_in_bytes": "2093990537",
+   "app_size_in_bytes": "3687618762",
    "background_color": "rgba(77,188,194,0.9686274509803922)",
    "capture_links": "kNone",
    "chromeos_data": null,
@@ -261,7 +263,7 @@
    },
    "dark_mode_background_color": "none",
    "dark_mode_theme_color": "none",
-   "data_size_in_bytes": "2659692452",
+   "data_size_in_bytes": "2102337622",
    "description": "Description1234",
    "disallowed_launch_protocols": [ "web+disallowed_1234_0", "web+disallowed_1234_1", "web+disallowed_1234_2", "web+disallowed_1234_3" ],
    "display_mode": "standalone",
@@ -277,14 +279,14 @@
       "MONOCHROME": [  ],
       "index": 0
    }, {
-      "ANY": [ 218 ],
-      "MASKABLE": [ 183 ],
-      "MONOCHROME": [ 203 ],
+      "ANY": [ 118 ],
+      "MASKABLE": [ 38 ],
+      "MONOCHROME": [ 228 ],
       "index": 1
    }, {
-      "ANY": [ 87, 136 ],
-      "MASKABLE": [ 187, 128 ],
-      "MONOCHROME": [ 78, 130 ],
+      "ANY": [ 80, 47 ],
+      "MASKABLE": [ 240, 164 ],
+      "MONOCHROME": [ 138, 107 ],
       "index": 2
    } ],
    "file_handler_approval_state": "kRequiresPrompt",
@@ -390,8 +392,8 @@
       "launch_type": "kSingleClient",
       "name": "2591174844 file"
    } ],
-   "handle_links": "kAuto",
-   "install_source_for_metrics": 13,
+   "handle_links": "kUndefined",
+   "install_source_for_metrics": 2,
    "install_time": "1970-01-10 21:57:36.131 UTC",
    "is_from_sync_and_pending_installation": false,
    "is_generated_icon": true,
@@ -400,28 +402,25 @@
    "is_uninstalling": false,
    "last_badging_time": "1970-01-13 20:12:59.451 UTC",
    "last_launch_time": "1970-01-04 17:38:34.900 UTC",
-   "launch_handler": null,
+   "launch_handler": {
+      "route_to": "kExistingClientNavigate"
+   },
    "launch_query_params": "986688382",
+   "lock_screen_start_url": "https://example.com/scope1234/lock_screen_start_url3206632378",
    "management_type_to_external_configuration_map": {
-        "Default": {
-            "install_urls": [
-                "https://example.com/installer1_1234/"
-            ],
-            "is_placeholder": false
-        },
-        "SubApp": {
-            "install_urls": [
-                "https://example.com/installer1_1234/"
-            ],
-            "is_placeholder": false
-        },
-        "WebAppStore": {
-            "install_urls": [
-                "https://example.com/installer2_1234/"
-            ],
-            "is_placeholder": false
-        }
-    },
+      "Default": {
+         "install_urls": [ "https://example.com/installer1_1234/" ],
+         "is_placeholder": true
+      },
+      "SubApp": {
+         "install_urls": [ "https://example.com/installer2_1234/" ],
+         "is_placeholder": false
+      },
+      "WebAppStore": {
+         "install_urls": [ "https://example.com/installer1_1234/" ],
+         "is_placeholder": true
+      }
+   },
    "manifest_icons": [ {
       "purpose": "kAny",
       "square_size_px": 256,
@@ -432,10 +431,10 @@
       "url": "https://example.com/icon944292860"
    } ],
    "manifest_id": null,
-   "manifest_update_time": "1970-01-22 23:19:09.029 UTC",
+   "manifest_update_time": "1970-01-21 01:09:01.170 UTC",
    "manifest_url": "https://example.com/manifest1234.json",
-   "note_taking_new_note_url": "https://example.com/scope1234/new_note3206632378",
-   "parent_app_id": "2353265476",
+   "note_taking_new_note_url": "",
+   "parent_app_id": "1112833914",
    "protocol_handlers": [ {
       "protocol": "web+test24741963850",
       "url": "https://example.com/24741963850"
@@ -460,105 +459,47 @@
       "icons": {
          "ANY": [  ],
          "MASKABLE": [ {
-            "square_size_px": 20,
-            "url": "https://example.com/shortcuts/icon358829003342"
-         }, {
-            "square_size_px": 11,
-            "url": "https://example.com/shortcuts/icon358829003341"
-         }, {
-            "square_size_px": 4,
-            "url": "https://example.com/shortcuts/icon358829003340"
+            "square_size_px": 9,
+            "url": "https://example.com/shortcuts/icon302299027120"
          } ],
-         "MONOCHROME": [  ]
+         "MONOCHROME": [ {
+            "square_size_px": 18,
+            "url": "https://example.com/shortcuts/icon302299027121"
+         } ]
       },
-      "name": "shortcut35882900334",
-      "url": "https://example.com/scope1234/shortcut35882900334"
+      "name": "shortcut30229902712",
+      "url": "https://example.com/scope1234/shortcut30229902712"
    }, {
       "icons": {
          "ANY": [ {
-            "square_size_px": 41,
-            "url": "https://example.com/shortcuts/icon358829003334"
+            "square_size_px": 14,
+            "url": "https://example.com/shortcuts/icon302299027111"
+         } ],
+         "MASKABLE": [ {
+            "square_size_px": 29,
+            "url": "https://example.com/shortcuts/icon302299027112"
          }, {
+            "square_size_px": 7,
+            "url": "https://example.com/shortcuts/icon302299027110"
+         } ],
+         "MONOCHROME": [  ]
+      },
+      "name": "shortcut30229902711",
+      "url": "https://example.com/scope1234/shortcut30229902711"
+   }, {
+      "icons": {
+         "ANY": [ {
             "square_size_px": 0,
-            "url": "https://example.com/shortcuts/icon358829003330"
+            "url": "https://example.com/shortcuts/icon302299027100"
          } ],
-         "MASKABLE": [ {
-            "square_size_px": 32,
-            "url": "https://example.com/shortcuts/icon358829003333"
-         } ],
+         "MASKABLE": [  ],
          "MONOCHROME": [ {
-            "square_size_px": 23,
-            "url": "https://example.com/shortcuts/icon358829003332"
-         }, {
             "square_size_px": 16,
-            "url": "https://example.com/shortcuts/icon358829003331"
+            "url": "https://example.com/shortcuts/icon302299027101"
          } ]
       },
-      "name": "shortcut35882900333",
-      "url": "https://example.com/scope1234/shortcut35882900333"
-   }, {
-      "icons": {
-         "ANY": [ {
-            "square_size_px": 11,
-            "url": "https://example.com/shortcuts/icon358829003321"
-         } ],
-         "MASKABLE": [ {
-            "square_size_px": 21,
-            "url": "https://example.com/shortcuts/icon358829003322"
-         }, {
-            "square_size_px": 7,
-            "url": "https://example.com/shortcuts/icon358829003320"
-         } ],
-         "MONOCHROME": [  ]
-      },
-      "name": "shortcut35882900332",
-      "url": "https://example.com/scope1234/shortcut35882900332"
-   }, {
-      "icons": {
-         "ANY": [ {
-            "square_size_px": 4,
-            "url": "https://example.com/shortcuts/icon358829003310"
-         } ],
-         "MASKABLE": [ {
-            "square_size_px": 34,
-            "url": "https://example.com/shortcuts/icon358829003313"
-         } ],
-         "MONOCHROME": [ {
-            "square_size_px": 44,
-            "url": "https://example.com/shortcuts/icon358829003314"
-         }, {
-            "square_size_px": 25,
-            "url": "https://example.com/shortcuts/icon358829003312"
-         }, {
-            "square_size_px": 10,
-            "url": "https://example.com/shortcuts/icon358829003311"
-         } ]
-      },
-      "name": "shortcut35882900331",
-      "url": "https://example.com/scope1234/shortcut35882900331"
-   }, {
-      "icons": {
-         "ANY": [ {
-            "square_size_px": 33,
-            "url": "https://example.com/shortcuts/icon358829003303"
-         }, {
-            "square_size_px": 26,
-            "url": "https://example.com/shortcuts/icon358829003302"
-         } ],
-         "MASKABLE": [ {
-            "square_size_px": 11,
-            "url": "https://example.com/shortcuts/icon358829003301"
-         } ],
-         "MONOCHROME": [ {
-            "square_size_px": 45,
-            "url": "https://example.com/shortcuts/icon358829003304"
-         }, {
-            "square_size_px": 7,
-            "url": "https://example.com/shortcuts/icon358829003300"
-         } ]
-      },
-      "name": "shortcut35882900330",
-      "url": "https://example.com/scope1234/shortcut35882900330"
+      "name": "shortcut30229902710",
+      "url": "https://example.com/scope1234/shortcut30229902710"
    } ],
    "sources": [ "SubApp", "WebAppStore", "Sync", "Default" ],
    "start_url": "https://example.com/scope1234/start1234",
diff --git a/chrome/browser/web_applications/web_app_utils.cc b/chrome/browser/web_applications/web_app_utils.cc
index fc40cb91..5b7c85a2 100644
--- a/chrome/browser/web_applications/web_app_utils.cc
+++ b/chrome/browser/web_applications/web_app_utils.cc
@@ -4,29 +4,47 @@
 
 #include "chrome/browser/web_applications/web_app_utils.h"
 
+#include <algorithm>
+#include <bitset>
+#include <iterator>
+#include <set>
+#include <type_traits>
 #include <utility>
 
 #include "base/base64.h"
+#include "base/bind.h"
+#include "base/check.h"
+#include "base/check_op.h"
 #include "base/containers/contains.h"
-#include "base/feature_list.h"
+#include "base/containers/flat_set.h"
+#include "base/containers/flat_tree.h"
 #include "base/files/file_path.h"
+#include "base/strings/string_piece_forward.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
 #include "build/build_config.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/web_applications/os_integration/os_integration_manager.h"
 #include "chrome/browser/web_applications/web_app.h"
+#include "chrome/browser/web_applications/web_app_constants.h"
 #include "chrome/browser/web_applications/web_app_icon_manager.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
-#include "chrome/browser/web_applications/web_app_registry_update.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/browser/web_applications/web_app_sync_bridge.h"
 #include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_features.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/custom_handlers/protocol_handler.h"
 #include "components/grit/components_resources.h"
 #include "components/site_engagement/content/site_engagement_service.h"
 #include "components/strings/grit/components_strings.h"
+#include "content/public/common/alternative_error_page_override_info.mojom-forward.h"
+#include "content/public/common/alternative_error_page_override_info.mojom.h"
+#include "mojo/public/cpp/bindings/struct_ptr.h"
 #include "skia/ext/skia_utils_base.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkColor.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/codec/png_codec.h"
 #include "url/gurl.h"
@@ -479,4 +497,12 @@
   return provider->registrar().IsLocallyInstalled(app_id);
 }
 
+bool IsInScope(const GURL& url, const GURL& scope) {
+  if (!scope.is_valid())
+    return false;
+
+  return base::StartsWith(url.spec(), scope.spec(),
+                          base::CompareCase::SENSITIVE);
+}
+
 }  // namespace web_app
diff --git a/chrome/browser/web_applications/web_app_utils.h b/chrome/browser/web_applications/web_app_utils.h
index 4ef9128f..50900bb2 100644
--- a/chrome/browser/web_applications/web_app_utils.h
+++ b/chrome/browser/web_applications/web_app_utils.h
@@ -5,15 +5,18 @@
 #ifndef CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_UTILS_H_
 #define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_UTILS_H_
 
+#include <stddef.h>
 #include <string>
+#include <tuple>
 #include <vector>
 
-#include "base/callback.h"
+#include "base/callback_forward.h"
+#include "build/build_config.h"
+#include "build/buildflag.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/web_applications/web_app.h"
 #include "chrome/browser/web_applications/web_app_id.h"
 #include "components/services/app_service/public/cpp/file_handler.h"
-#include "content/public/common/alternative_error_page_override_info.mojom.h"
 
 class GURL;
 class Profile;
@@ -160,6 +163,9 @@
 // Check if |url|'s path is an installed web app.
 bool HasAppSettingsPage(Profile* profile, const GURL& url);
 
+// Returns whether `url` is in scope `scope`. False if scope is invalid.
+bool IsInScope(const GURL& url, const GURL& scope);
+
 #if BUILDFLAG(IS_CHROMEOS)
 // The kLacrosPrimary and kWebAppsCrosapi features are each independently
 // sufficient to enable the web apps Crosapi (used for Lacros web app
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index c237c170..6487ec61 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1653257309-efa8e931c3f435bcf0a6b5f3d59546fe559d64c8.profdata
+chrome-linux-main-1653285310-05ab8e44ff839714d80ecd7b81dd58d047710853.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index df95975d..674037c 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1653257309-a96b1a463206393066c30bdc173870125e250990.profdata
+chrome-mac-arm-main-1653285310-33ae798904d1454f1b7f7317369b87c48fe902e3.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index e2c4051b..dd487bc 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1653257309-f8c7b5e83e2b2faf432dfc9230022c4890b9dbb6.profdata
+chrome-mac-main-1653285310-8776e0cabafaab2134539e8077bc208d5b83c1de.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 3084c61..5874648 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1653257309-dec949c51dcbaf1801f91da9e0e9d1f750465f3d.profdata
+chrome-win32-main-1653296201-d65cbd52699822181f14833c5d6cb9010b3469a2.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index d2d31c4..1a7f4a7d 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1653257309-ddaa0d9f1ab247ab4b678de6ff0cc424c2d08e4c.profdata
+chrome-win64-main-1653296201-52b223a5b458bfbdd58f2891cbdd48ac7b1b0506.profdata
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index ff727a14..202a0e5c5 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -383,13 +383,6 @@
     base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
-#if BUILDFLAG(IS_ANDROID)
-// Under this flag tab preloading at startup will be elided (i.e., not
-// performed).
-const base::Feature kElideTabPreloadAtStartup = {
-    "ElideTabPreloadAtStartup", base::FEATURE_ENABLED_BY_DEFAULT};
-#endif
-
 // Enables all registered system web apps, regardless of their respective
 // feature flags.
 const base::Feature kEnableAllSystemWebApps{"EnableAllSystemWebApps",
@@ -625,9 +618,11 @@
     "IncognitoBrandConsistencyForAndroid", base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
+#if BUILDFLAG(IS_ANDROID)
 // When enabled, users will see a warning when downloading from Incognito.
 const base::Feature kIncognitoDownloadsWarning{
     "IncognitoDownloadsWarning", base::FEATURE_DISABLED_BY_DEFAULT};
+#endif
 
 // When enabled, users will see updated UI in Incognito NTP
 const base::Feature kIncognitoNtpRevamp{"IncognitoNtpRevamp",
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index 3ab6dea..54d3797f 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -260,11 +260,6 @@
 extern const base::Feature kElidePrioritizationOfPreNativeBootstrapTasks;
 #endif
 
-#if BUILDFLAG(IS_ANDROID)
-COMPONENT_EXPORT(CHROME_FEATURES)
-extern const base::Feature kElideTabPreloadAtStartup;
-#endif
-
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kEnableAllSystemWebApps;
 
@@ -437,8 +432,10 @@
 extern const base::Feature kIncognitoBrandConsistencyForAndroid;
 #endif
 
+#if BUILDFLAG(IS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kIncognitoDownloadsWarning;
+#endif
 
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kIncognitoNtpRevamp;
diff --git a/chrome/common/extensions/api/file_manager_private.idl b/chrome/common/extensions/api/file_manager_private.idl
index e026cd5..de18d77d 100644
--- a/chrome/common/extensions/api/file_manager_private.idl
+++ b/chrome/common/extensions/api/file_manager_private.idl
@@ -1043,6 +1043,9 @@
 // cancel the task.
 callback StartCopyCallback = void(long copyId);
 
+// |taskId| ID of the task that was started. Can be used to cancel ongoing task.
+callback IOTaskIdCallback = void(long taskId);
+
 // |sizeStats| Name/value pairs of size stats. Will be undefined if stats could
 // not be determined.
 callback GetSizeStatsCallback = void(optional MountPointSizeStats sizeStats);
@@ -1502,6 +1505,7 @@
   [nocompile]
   static void getRecentFiles(SourceRestriction restriction,
                              RecentFileType fileType,
+                             boolean invalidateCache,
                              GetRecentFilesCallback callback);
 
   // Requests the root directory of the volume with the ID specified in
@@ -1650,7 +1654,8 @@
   static void startIOTask(
       IOTaskType type,
       [instanceof=Entry] object[] entries,
-      IOTaskParams params);
+      IOTaskParams params,
+      optional IOTaskIdCallback callback);
 
   // Cancels an I/O task by id. Task ids are communicated to the Files App in
   // each I/O task's progress status.
diff --git a/chrome/common/extensions/api/file_manager_private_internal.idl b/chrome/common/extensions/api/file_manager_private_internal.idl
index 1e75ae3..c7af1499 100644
--- a/chrome/common/extensions/api/file_manager_private_internal.idl
+++ b/chrome/common/extensions/api/file_manager_private_internal.idl
@@ -36,6 +36,7 @@
   callback GetDisallowedTransfersCallback =
       void(EntryDescription[] entries);
   callback StartCopyCallback = void(long copyId);
+  callback IOTaskIdCallback = void(long taskId);
   callback ZipSelectionCallback = void(long zipId, double totalBytes);
   callback ValidatePathNameLengthCallback = void(boolean result);
   callback GetDirectorySizeCallback = void(double size);
@@ -112,6 +113,7 @@
                               GetVolumeRootCallback callback);
     static void getRecentFiles(fileManagerPrivate.SourceRestriction restriction,
                                fileManagerPrivate.RecentFileType file_type,
+                               boolean invalidate_cache,
                                GetRecentFilesCallback callback);
     static void sharePathsWithCrostini(DOMString vmName, DOMString[] urls,
                                        boolean persist,
@@ -146,6 +148,7 @@
                                           optional SimpleCallback callback);
     static void startIOTask(fileManagerPrivate.IOTaskType type,
                             DOMString[] urls,
-                            IOTaskParams params);
+                            IOTaskParams params,
+                            optional IOTaskIdCallback callback);
   };
 };
diff --git a/chrome/installer/setup/install_worker.cc b/chrome/installer/setup/install_worker.cc
index b87def5..9a70296 100644
--- a/chrome/installer/setup/install_worker.cc
+++ b/chrome/installer/setup/install_worker.cc
@@ -564,7 +564,7 @@
     // languages is a superset of Chrome's set of translations with this one
     // exception: what Chrome calls "en-us", Omaha calls "en".  sigh.
     std::wstring language(GetCurrentTranslation());
-    if (base::LowerCaseEqualsASCII(language, "en-us"))
+    if (base::EqualsCaseInsensitiveASCII(language, "en-us"))
       language.resize(2);
     list->AddSetRegValueWorkItem(root, clients_key, KEY_WOW64_32KEY,
                                  google_update::kRegLangField, language,
diff --git a/chrome/renderer/autofill/autofill_renderer_browsertest.cc b/chrome/renderer/autofill/autofill_renderer_browsertest.cc
index ca947383..8c05963 100644
--- a/chrome/renderer/autofill/autofill_renderer_browsertest.cc
+++ b/chrome/renderer/autofill/autofill_renderer_browsertest.cc
@@ -98,11 +98,13 @@
                               const FormFieldData& field,
                               const gfx::RectF& bounding_box) override {}
 
-  void AskForValuesToFill(int32_t id,
+  void AskForValuesToFill(int32_t query_id,
                           const FormData& form,
                           const FormFieldData& field,
                           const gfx::RectF& bounding_box,
-                          bool autoselect_first_suggestion) override {}
+                          bool autoselect_first_suggestion,
+                          TouchToFillEligible touch_to_fill_eligible) override {
+  }
 
   void HidePopup() override {}
 
diff --git a/chrome/renderer/autofill/form_autocomplete_browsertest.cc b/chrome/renderer/autofill/form_autocomplete_browsertest.cc
index 7b16d85d..b345ff2 100644
--- a/chrome/renderer/autofill/form_autocomplete_browsertest.cc
+++ b/chrome/renderer/autofill/form_autocomplete_browsertest.cc
@@ -96,11 +96,12 @@
     select_control_changed_ = std::make_unique<FormFieldData>(field);
   }
 
-  void AskForValuesToFill(int32_t id,
+  void AskForValuesToFill(int32_t query_id,
                           const FormData& form,
                           const FormFieldData& field,
                           const gfx::RectF& bounding_box,
-                          bool autoselect_first_field) override {}
+                          bool autoselect_first_field,
+                          TouchToFillEligible touch_to_fill_eliible) override {}
 
   void HidePopup() override {}
 
diff --git a/chrome/renderer/resources/extensions/file_manager_private_custom_bindings.js b/chrome/renderer/resources/extensions/file_manager_private_custom_bindings.js
index 5c6b8fba..0cb6741 100644
--- a/chrome/renderer/resources/extensions/file_manager_private_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/file_manager_private_custom_bindings.js
@@ -253,9 +253,9 @@
   });
 
   apiFunctions.setHandleRequest('getRecentFiles', function(
-        restriction, file_type, callback) {
-    fileManagerPrivateInternal.getRecentFiles(restriction, file_type, function(
-          entryDescriptions) {
+        restriction, file_type, invalidate_cache, callback) {
+    fileManagerPrivateInternal.getRecentFiles(restriction, file_type,
+          invalidate_cache, function(entryDescriptions) {
       callback(entryDescriptions.map(function(description) {
         return GetExternalFileEntry(description);
       }));
@@ -367,14 +367,16 @@
             urls, added, callback);
       });
 
-  apiFunctions.setHandleRequest('startIOTask', function(type, entries, params) {
-    const urls = entries.map(entry => getEntryURL(entry));
-    let newParams = {};
-    if (params.destinationFolder) {
-      newParams.destinationFolderUrl = getEntryURL(params.destinationFolder);
-    }
-    fileManagerPrivateInternal.startIOTask(type, urls, newParams);
-  });
+  apiFunctions.setHandleRequest(
+      'startIOTask', function(type, entries, params, callback) {
+        const urls = entries.map(entry => getEntryURL(entry));
+        let newParams = {};
+        if (params.destinationFolder) {
+          newParams.destinationFolderUrl =
+              getEntryURL(params.destinationFolder);
+        }
+        fileManagerPrivateInternal.startIOTask(type, urls, newParams, callback);
+      });
 });
 
 bindingUtil.registerEventArgumentMassager(
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 77e062d4..328f6ab 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -2150,7 +2150,7 @@
       "../browser/ui/views/hats/hats_browsertest.cc",
       "../browser/ui/views/incognito_clear_browsing_data_dialog_browsertest.cc",
       "../browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view_browsertest.cc",
-      "../browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_view_browsertest.cc",
+      "../browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_browsertest.cc",
       "../browser/ui/views/reader_mode/reader_mode_icon_view_browsertest.cc",
       "../browser/ui/views/sharing/remote_copy_browsertest.cc",
       "../browser/ui/views/sharing/shared_clipboard_browsertest.cc",
diff --git a/chrome/test/chromedriver/chrome/frame_tracker.cc b/chrome/test/chromedriver/chrome/frame_tracker.cc
index 2e48918..8b729a05 100644
--- a/chrome/test/chromedriver/chrome/frame_tracker.cc
+++ b/chrome/test/chromedriver/chrome/frame_tracker.cc
@@ -22,8 +22,8 @@
 
 FrameTracker::~FrameTracker() {}
 
-Status FrameTracker::GetContextIdForFrame(
-    const std::string& frame_id, int* context_id) {
+Status FrameTracker::GetContextIdForFrame(const std::string& frame_id,
+                                          std::string* context_id) {
   if (frame_to_context_map_.count(frame_id) == 0) {
     return Status(kNoSuchExecutionContext,
                   "frame does not have execution context");
@@ -105,7 +105,7 @@
     std::string frame_id;
     bool is_default = true;
 
-    absl::optional<int> context_id = context->GetDict().FindInt("id");
+    const std::string* context_id = context->GetDict().FindString("uniqueId");
     if (!context_id) {
       std::string json;
       base::JSONWriter::Write(*context, &json);
@@ -131,14 +131,22 @@
     if (is_default && !frame_id.empty())
       frame_to_context_map_[frame_id] = *context_id;
   } else if (method == "Runtime.executionContextDestroyed") {
-    absl::optional<int> execution_context_id =
-        params.GetDict().FindInt("executionContextId");
-    if (!execution_context_id)
-      return Status(kUnknownError, method + " missing 'executionContextId'");
-    for (auto entry : frame_to_context_map_) {
-      if (entry.second == *execution_context_id) {
-        frame_to_context_map_.erase(entry.first);
-        break;
+    const base::Value::Dict* context = params.GetDict().FindDict("context");
+    // TODO(nechaev): Interpret the missing 'context' as an error
+    // after https://crbug.com/chromedriver/4120 is fixed.
+    if (context) {
+      const std::string* context_id = context->FindString("uniqueId");
+      if (!context_id) {
+        std::string json;
+        base::JSONWriter::Write(*context, &json);
+        return Status(kUnknownError,
+                      method + " has invalid 'context': " + json);
+      }
+      for (auto entry : frame_to_context_map_) {
+        if (entry.second == *context_id) {
+          frame_to_context_map_.erase(entry.first);
+          break;
+        }
       }
     }
   } else if (method == "Runtime.executionContextsCleared") {
@@ -153,6 +161,9 @@
   } else if (method == "Page.frameDetached") {
     if (const std::string* frame_id = params.GetDict().FindString("frameId")) {
       attached_frames_.erase(*frame_id);
+      // TODO(nechaev): Remove the following line
+      // after https://crbug.com/chromedriver/4120 is fixed.
+      frame_to_context_map_.erase(*frame_id);
     } else {
       return Status(kUnknownError,
                     "missing frameId in Page.frameDetached event");
diff --git a/chrome/test/chromedriver/chrome/frame_tracker.h b/chrome/test/chromedriver/chrome/frame_tracker.h
index f467dc5..c64cafe 100644
--- a/chrome/test/chromedriver/chrome/frame_tracker.h
+++ b/chrome/test/chromedriver/chrome/frame_tracker.h
@@ -33,7 +33,8 @@
 
   ~FrameTracker() override;
 
-  Status GetContextIdForFrame(const std::string& frame_id, int* context_id);
+  Status GetContextIdForFrame(const std::string& frame_id,
+                              std::string* context_id);
   WebView* GetTargetForFrame(const std::string& frame_id);
   bool IsKnownFrame(const std::string& frame_id) const;
   void DeleteTargetForFrame(const std::string& frame_id);
@@ -45,7 +46,7 @@
                  const base::DictionaryValue& params) override;
 
  private:
-  std::map<std::string, int> frame_to_context_map_;
+  std::map<std::string, std::string> frame_to_context_map_;
   std::map<std::string, std::unique_ptr<WebView>> frame_to_target_map_;
   std::unordered_set<std::string> attached_frames_;
   raw_ptr<WebView> web_view_;
diff --git a/chrome/test/chromedriver/chrome/frame_tracker_unittest.cc b/chrome/test/chromedriver/chrome/frame_tracker_unittest.cc
index dd49da9..b044b8f0 100644
--- a/chrome/test/chromedriver/chrome/frame_tracker_unittest.cc
+++ b/chrome/test/chromedriver/chrome/frame_tracker_unittest.cc
@@ -14,12 +14,13 @@
 TEST(FrameTracker, GetContextIdForFrame) {
   StubDevToolsClient client;
   FrameTracker tracker(&client);
-  int context_id = -1;
+  std::string context_id;
   ASSERT_TRUE(tracker.GetContextIdForFrame("f", &context_id).IsError());
-  ASSERT_EQ(-1, context_id);
+  ASSERT_EQ("", context_id);
 
   const char context[] =
-      "{\"id\":100,\"auxData\":{\"frameId\":\"f\",\"isDefault\":true}}";
+      "{\"uniqueId\":\"100\",\"auxData\":{\"frameId\":\"f\",\"isDefault\":true}"
+      "}";
   base::DictionaryValue params;
   params.GetDict().Set("context",
                        std::move(*base::JSONReader::ReadDeprecated(context)));
@@ -28,9 +29,9 @@
                 .code());
   ASSERT_EQ(kNoSuchExecutionContext,
             tracker.GetContextIdForFrame("foo", &context_id).code());
-  ASSERT_EQ(-1, context_id);
+  ASSERT_EQ("", context_id);
   ASSERT_TRUE(tracker.GetContextIdForFrame("f", &context_id).IsOk());
-  ASSERT_EQ(100, context_id);
+  ASSERT_EQ("100", context_id);
 
   base::DictionaryValue nav_params;
   nav_params.GetDict().SetByDottedPath("frame.parentId", "1");
@@ -47,11 +48,11 @@
 TEST(FrameTracker, AuxData) {
   StubDevToolsClient client;
   FrameTracker tracker(&client);
-  int context_id = -1;
+  std::string context_id;
   ASSERT_TRUE(tracker.GetContextIdForFrame("f", &context_id).IsError());
-  ASSERT_EQ(-1, context_id);
+  ASSERT_EQ("", context_id);
 
-  const char context[] = "{\"id\":100,\"auxData\":{}}";
+  const char context[] = "{\"uniqueId\":\"100\",\"auxData\":{}}";
   base::DictionaryValue params;
   params.GetDict().Set("context",
                        std::move(*base::JSONReader::ReadDeprecated(context)));
@@ -62,9 +63,9 @@
                 .code());
   ASSERT_EQ(kNoSuchExecutionContext,
             tracker.GetContextIdForFrame("foo", &context_id).code());
-  ASSERT_EQ(-1, context_id);
+  ASSERT_EQ("", context_id);
   ASSERT_TRUE(tracker.GetContextIdForFrame("f", &context_id).IsOk());
-  ASSERT_EQ(100, context_id);
+  ASSERT_EQ("100", context_id);
 }
 
 TEST(FrameTracker, CanUpdateFrameContextId) {
@@ -72,23 +73,23 @@
   FrameTracker tracker(&client);
 
   const char context[] =
-      "{\"id\":1,\"auxData\":{\"frameId\":\"f\",\"isDefault\":true}}";
+      "{\"uniqueId\":\"1\",\"auxData\":{\"frameId\":\"f\",\"isDefault\":true}}";
   base::DictionaryValue params;
   params.GetDict().Set("context",
                        std::move(*base::JSONReader::ReadDeprecated(context)));
   ASSERT_EQ(kOk,
             tracker.OnEvent(&client, "Runtime.executionContextCreated", params)
                 .code());
-  int context_id = -1;
+  std::string context_id;
   ASSERT_TRUE(tracker.GetContextIdForFrame("f", &context_id).IsOk());
-  ASSERT_EQ(1, context_id);
+  ASSERT_EQ("1", context_id);
 
-  params.GetDict().SetByDottedPath("context.id", 2);
+  params.GetDict().SetByDottedPath("context.uniqueId", "2");
   ASSERT_EQ(kOk,
             tracker.OnEvent(&client, "Runtime.executionContextCreated", params)
                 .code());
   ASSERT_TRUE(tracker.GetContextIdForFrame("f", &context_id).IsOk());
-  ASSERT_EQ(2, context_id);
+  ASSERT_EQ("2", context_id);
 }
 
 TEST(FrameTracker, DontTrackContentScriptContexts) {
@@ -96,22 +97,22 @@
   FrameTracker tracker(&client);
 
   const char context[] =
-      "{\"id\":1,\"auxData\":{\"frameId\":\"f\",\"isDefault\":true}}";
+      "{\"uniqueId\":\"1\",\"auxData\":{\"frameId\":\"f\",\"isDefault\":true}}";
   base::DictionaryValue params;
   params.GetDict().Set("context",
                        std::move(*base::JSONReader::ReadDeprecated(context)));
   ASSERT_EQ(kOk,
             tracker.OnEvent(&client, "Runtime.executionContextCreated", params)
                 .code());
-  int context_id = -1;
+  std::string context_id;
   ASSERT_TRUE(tracker.GetContextIdForFrame("f", &context_id).IsOk());
-  ASSERT_EQ(1, context_id);
+  ASSERT_EQ("1", context_id);
 
-  params.GetDict().SetByDottedPath("context.id", 2);
+  params.GetDict().SetByDottedPath("context.uniqueId", "2");
   params.GetDict().SetByDottedPath("context.auxData.isDefault", false);
   ASSERT_EQ(kOk,
             tracker.OnEvent(&client, "Runtime.executionContextCreated", params)
                 .code());
   ASSERT_TRUE(tracker.GetContextIdForFrame("f", &context_id).IsOk());
-  ASSERT_EQ(1, context_id);
+  ASSERT_EQ("1", context_id);
 }
diff --git a/chrome/test/chromedriver/chrome/web_view_impl.cc b/chrome/test/chromedriver/chrome/web_view_impl.cc
index 2f5af109..0efeb33 100644
--- a/chrome/test/chromedriver/chrome/web_view_impl.cc
+++ b/chrome/test/chromedriver/chrome/web_view_impl.cc
@@ -47,9 +47,10 @@
 
 Status GetContextIdForFrame(WebViewImpl* web_view,
                             const std::string& frame,
-                            int* context_id) {
+                            std::string* context_id) {
+  DCHECK(context_id);
   if (frame.empty() || frame == web_view->GetId()) {
-    *context_id = 0;
+    context_id->clear();
     return Status(kOk);
   }
   Status status =
@@ -587,7 +588,7 @@
                                              awaitPromise, result);
   }
 
-  int context_id;
+  std::string context_id;
   Status status = GetContextIdForFrame(this, frame, &context_id);
   if (status.IsError())
     return status;
@@ -680,7 +681,7 @@
     return target->GetFrameByFunction(frame, function, args, out_frame);
   }
 
-  int context_id;
+  std::string context_id;
   Status status = GetContextIdForFrame(this, frame, &context_id);
   if (status.IsError())
     return status;
@@ -1136,7 +1137,7 @@
                                               int* backend_node_id) {
   if (!element.is_dict())
     return Status(kUnknownError, "'element' is not a dictionary");
-  int context_id;
+  std::string context_id;
   Status status = GetContextIdForFrame(this, frame, &context_id);
   if (status.IsError())
     return status;
@@ -1535,7 +1536,7 @@
 namespace internal {
 
 Status EvaluateScript(DevToolsClient* client,
-                      int context_id,
+                      const std::string& context_id,
                       const std::string& expression,
                       EvaluateScriptReturnType return_type,
                       const base::TimeDelta& timeout,
@@ -1544,8 +1545,9 @@
   base::DictionaryValue params;
   base::Value::Dict& dict = params.GetDict();
   dict.Set("expression", expression);
-  if (context_id)
-    dict.Set("contextId", context_id);
+  if (!context_id.empty()) {
+    dict.Set("uniqueContextId", context_id);
+  }
   dict.Set("returnByValue", return_type == ReturnByValue);
   dict.Set("awaitPromise", awaitPromise);
   base::Value cmd_result;
@@ -1575,7 +1577,7 @@
 }
 
 Status EvaluateScriptAndGetObject(DevToolsClient* client,
-                                  int context_id,
+                                  const std::string& context_id,
                                   const std::string& expression,
                                   const base::TimeDelta& timeout,
                                   const bool awaitPromise,
@@ -1599,7 +1601,7 @@
 }
 
 Status EvaluateScriptAndGetValue(DevToolsClient* client,
-                                 int context_id,
+                                 const std::string& context_id,
                                  const std::string& expression,
                                  const base::TimeDelta& timeout,
                                  const bool awaitPromise,
@@ -1650,7 +1652,7 @@
 }
 
 Status GetBackendNodeIdFromFunction(DevToolsClient* client,
-                                    int context_id,
+                                    const std::string& context_id,
                                     const std::string& function,
                                     const base::ListValue& args,
                                     bool* found_node,
@@ -1715,7 +1717,7 @@
 }
 
 Status GetFrameIdFromFunction(DevToolsClient* client,
-                              int context_id,
+                              const std::string& context_id,
                               const std::string& function,
                               const base::ListValue& args,
                               bool* found_node,
diff --git a/chrome/test/chromedriver/chrome/web_view_impl.h b/chrome/test/chromedriver/chrome/web_view_impl.h
index ffe361f..a996845b 100644
--- a/chrome/test/chromedriver/chrome/web_view_impl.h
+++ b/chrome/test/chromedriver/chrome/web_view_impl.h
@@ -255,21 +255,21 @@
   ReturnByObject
 };
 Status EvaluateScript(DevToolsClient* client,
-                      int context_id,
+                      const std::string& context_id,
                       const std::string& expression,
                       EvaluateScriptReturnType return_type,
                       const base::TimeDelta& timeout,
                       const bool awaitPromise,
                       std::unique_ptr<base::DictionaryValue>* result);
 Status EvaluateScriptAndGetObject(DevToolsClient* client,
-                                  int context_id,
+                                  const std::string& context_id,
                                   const std::string& expression,
                                   const base::TimeDelta& timeout,
                                   const bool awaitPromise,
                                   bool* got_object,
                                   std::string* object_id);
 Status EvaluateScriptAndGetValue(DevToolsClient* client,
-                                 int context_id,
+                                 const std::string& context_id,
                                  const std::string& expression,
                                  const base::TimeDelta& timeout,
                                  const bool awaitPromise,
@@ -277,14 +277,14 @@
 Status ParseCallFunctionResult(const base::Value& temp_result,
                                std::unique_ptr<base::Value>* result);
 Status GetBackendNodeIdFromFunction(DevToolsClient* client,
-                                    int context_id,
+                                    const std::string& context_id,
                                     const std::string& function,
                                     const base::ListValue& args,
                                     bool* found_node,
                                     int* backend_node_id,
                                     bool w3c_compliant);
 Status GetFrameIdFromFunction(DevToolsClient* client,
-                              int context_id,
+                              const std::string& context_id,
                               const std::string& function,
                               const base::ListValue& args,
                               bool* found_node,
diff --git a/chrome/test/chromedriver/chrome/web_view_impl_unittest.cc b/chrome/test/chromedriver/chrome/web_view_impl_unittest.cc
index 000e9c5..d45a0c5 100644
--- a/chrome/test/chromedriver/chrome/web_view_impl_unittest.cc
+++ b/chrome/test/chromedriver/chrome/web_view_impl_unittest.cc
@@ -57,7 +57,7 @@
   FakeDevToolsClient client;
   client.set_result(command_result);
   Status status = internal::EvaluateScript(
-      &client, 0, std::string(), internal::ReturnByValue,
+      &client, "context", std::string(), internal::ReturnByValue,
       base::TimeDelta::Max(), false, &result);
   ASSERT_EQ(kUnknownError, status.code());
   ASSERT_FALSE(result);
@@ -70,7 +70,7 @@
   FakeDevToolsClient client;
   client.set_status(Status(kUnknownError));
   Status status = internal::EvaluateScript(
-      &client, 0, std::string(), internal::ReturnByValue,
+      &client, "context", std::string(), internal::ReturnByValue,
       base::TimeDelta::Max(), false, &result);
   ASSERT_EQ(kUnknownError, status.code());
   ASSERT_FALSE(result);
@@ -95,7 +95,7 @@
   dict.GetDict().SetByDottedPath("result.key", 100);
   FakeDevToolsClient client;
   client.set_result(dict);
-  ASSERT_TRUE(internal::EvaluateScript(&client, 0, std::string(),
+  ASSERT_TRUE(internal::EvaluateScript(&client, "context", std::string(),
                                        internal::ReturnByValue,
                                        base::TimeDelta::Max(), false, &result)
                   .IsOk());
@@ -109,9 +109,9 @@
   base::DictionaryValue dict;
   dict.GetDict().SetByDottedPath("result.value", 1);
   client.set_result(dict);
-  ASSERT_TRUE(internal::EvaluateScriptAndGetValue(&client, 0, std::string(),
-                                                  base::TimeDelta::Max(), false,
-                                                  &result)
+  ASSERT_TRUE(internal::EvaluateScriptAndGetValue(
+                  &client, "context", std::string(), base::TimeDelta::Max(),
+                  false, &result)
                   .IsError());
 }
 
@@ -122,7 +122,8 @@
   dict.GetDict().SetByDottedPath("result.type", "undefined");
   client.set_result(dict);
   Status status = internal::EvaluateScriptAndGetValue(
-      &client, 0, std::string(), base::TimeDelta::Max(), false, &result);
+      &client, "context", std::string(), base::TimeDelta::Max(), false,
+      &result);
   ASSERT_EQ(kOk, status.code());
   ASSERT_TRUE(result && result->is_none());
 }
@@ -135,7 +136,8 @@
   dict.GetDict().SetByDottedPath("result.value", 1);
   client.set_result(dict);
   Status status = internal::EvaluateScriptAndGetValue(
-      &client, 0, std::string(), base::TimeDelta::Max(), false, &result);
+      &client, "context", std::string(), base::TimeDelta::Max(), false,
+      &result);
   ASSERT_EQ(kOk, status.code());
   ASSERT_TRUE(result && result->is_int());
   ASSERT_EQ(1, result->GetInt());
@@ -149,8 +151,8 @@
   bool got_object;
   std::string object_id;
   ASSERT_TRUE(internal::EvaluateScriptAndGetObject(
-                  &client, 0, std::string(), base::TimeDelta::Max(), false,
-                  &got_object, &object_id)
+                  &client, "context", std::string(), base::TimeDelta::Max(),
+                  false, &got_object, &object_id)
                   .IsOk());
   ASSERT_FALSE(got_object);
   ASSERT_TRUE(object_id.empty());
@@ -164,8 +166,8 @@
   bool got_object;
   std::string object_id;
   ASSERT_TRUE(internal::EvaluateScriptAndGetObject(
-                  &client, 0, std::string(), base::TimeDelta::Max(), false,
-                  &got_object, &object_id)
+                  &client, "context", std::string(), base::TimeDelta::Max(),
+                  false, &got_object, &object_id)
                   .IsOk());
   ASSERT_TRUE(got_object);
   ASSERT_STREQ("id", object_id.c_str());
diff --git a/chrome/test/chromedriver/element_util.cc b/chrome/test/chromedriver/element_util.cc
index acc461d..1b73c355 100644
--- a/chrome/test/chromedriver/element_util.cc
+++ b/chrome/test/chromedriver/element_util.cc
@@ -529,8 +529,7 @@
                                "document.contentType", false, &contentType);
   if (status.IsError())
           return status;
-  if (base::LowerCaseEqualsASCII(contentType->GetString(),
-                                 "text/xml"))
+  if (base::EqualsCaseInsensitiveASCII(contentType->GetString(), "text/xml"))
     *is_xml_document = true;
   else
     *is_xml_document = false;
@@ -567,7 +566,7 @@
     return status;
   if (result->is_string()) {
     *is_equal =
-        base::LowerCaseEqualsASCII(result->GetString(), attribute_value);
+        base::EqualsCaseInsensitiveASCII(result->GetString(), attribute_value);
   } else {
     *is_equal = false;
   }
diff --git a/chrome/test/data/extensions/api_test/automation/sites/add_remove_event_listeners.html b/chrome/test/data/extensions/api_test/automation/sites/add_remove_event_listeners.html
index cbd9bc3..4c123ec 100644
--- a/chrome/test/data/extensions/api_test/automation/sites/add_remove_event_listeners.html
+++ b/chrome/test/data/extensions/api_test/automation/sites/add_remove_event_listeners.html
@@ -8,17 +8,11 @@
     <title>Automation Tests - Add Remove Event Listeners</title>
   </head>
   <body>
-    <button id="remove">remove</button>
-    <button id="close">close</button>
+    <button></button>
     <script>
-      const removeButton = document.getElementById('remove');
-      removeButton.addEventListener('click', () => {
-          removeButton.remove();
-      });
-
-      const closeButton = document.getElementById('close');
-      closeButton.addEventListener('click', () => {
-        window.close();
+      const button = document.querySelector('button');
+      button.addEventListener('click', () => {
+        button.setAttribute('aria-hidden', true);
       });
     </script>
   </body>
diff --git a/chrome/test/data/extensions/api_test/automation/tests/desktop/add_remove_event_listeners.js b/chrome/test/data/extensions/api_test/automation/tests/desktop/add_remove_event_listeners.js
index 5d9c5436..af7258ce 100644
--- a/chrome/test/data/extensions/api_test/automation/tests/desktop/add_remove_event_listeners.js
+++ b/chrome/test/data/extensions/api_test/automation/tests/desktop/add_remove_event_listeners.js
@@ -50,28 +50,17 @@
     desktop.removeEventListener(
         chrome.automation.EventType.FOCUS, focusHandler);
 
-    // This does get the current desktop as well, prior to disabling. Doing this
-    // checks that repeated calls still work prior to the disable coming
-    // through.
+    // This sends an enableDesktop call, which should be processed after the
+    // disableDesktop request.
     const newDesktop = await new Promise(r => chrome.automation.getDesktop(r));
 
-    // Both |desktop| and |newDesktop| should be valid and refer to the
+    // Finally, both |desktop| and |newDesktop| should be valid and refer to the
     // same tree.
     assertTrue(!!desktop);
     assertTrue(!!newDesktop);
     assertEq(newDesktop, desktop);
     assertEq(chrome.automation.RoleType.DESKTOP, newDesktop.role);
 
-    // Finally, the disabling above (from removing the event listeners) comes
-    // some time later. Wait for it so that it does not impact other tests.
-    await new Promise(r => {
-      setInterval(() => {
-        if (desktop.role === undefined) {
-          r();
-        }
-      }, 100);
-    });
-
     chrome.test.succeed();
   },
 
@@ -79,16 +68,8 @@
     const desktop = await new Promise(r => chrome.automation.getDesktop(r));
     assertTrue(!!desktop);
 
-    const button = await new Promise(r => {
-      setInterval(() => {
-        let node;
-        if (node = findAutomationNode(desktop, n => n.name === 'remove')) {
-          r(node);
-        }
-      }, 100);
-    });
+    const button = desktop.find({role: chrome.automation.RoleType.BUTTON});
     assertTrue(!!button);
-    assertEq('remove', button.name);
 
     // Adding a listener should have no effect.
     const focusHandler = () => {};
@@ -113,55 +94,6 @@
     // The tree is completely cleared.
     assertEq(undefined, desktop.role);
     chrome.test.succeed();
-  },
-
-  // Note that these tests run on the *same* webpage, so the above test already
-  // removed/hide one of the buttons.
-  async function testWindowClose() {
-    const desktop = await new Promise(r => chrome.automation.getDesktop(r));
-    assertTrue(!!desktop);
-
-    const button = await new Promise(r => {
-      setInterval(() => {
-        let node;
-        if (node = findAutomationNode(desktop, n => n.name === 'close')) {
-          r(node);
-        }
-      }, 100);
-    });
-    assertTrue(!!button);
-    assertEq('close', button.name);
-
-    // Adding a listener should have no effect.
-    const focusHandler = () => {};
-    button.addEventListener(chrome.automation.EventType.FOCUS, focusHandler);
-    assertEq(chrome.automation.RoleType.DESKTOP, desktop.role);
-
-    // The click/do default action triggers the window to close.
-    button.doDefault();
-
-    // We can't add event listeners to observe the deletions as to not trigger
-    // adds, so poll for the change.
-    await new Promise(r => {
-      const checkForButton = () => {
-        if (button.role === undefined) {
-          r();
-          clearInterval(id);
-        }
-      };
-      const id = setInterval(checkForButton, 10);
-    });
-
-    // The tree is completely cleared after some time.
-    await new Promise(r => {
-      setInterval(() => {
-        if (desktop.role === undefined) {
-          r();
-        }
-      }, 100);
-    });
-
-    chrome.test.succeed();
   }
 ];
 
diff --git a/chrome/test/data/extensions/api_test/file_browser/recent_test/test.js b/chrome/test/data/extensions/api_test/file_browser/recent_test/test.js
index 89f4d77..6c296bb5 100644
--- a/chrome/test/data/extensions/api_test/file_browser/recent_test/test.js
+++ b/chrome/test/data/extensions/api_test/file_browser/recent_test/test.js
@@ -46,7 +46,7 @@
   chrome.test.runTests([
     function testGetRecentFiles() {
       chrome.fileManagerPrivate.getRecentFiles(
-          'native_source', 'all', chrome.test.callbackPass(entries => {
+          'native_source', 'all', false, chrome.test.callbackPass(entries => {
             chrome.test.assertTrue(
                 exists(entries, 'all-justice.jpg'),
                 'all-justice.jpg not found');
@@ -60,7 +60,7 @@
     },
     function testGetRecentAudioFiles() {
       chrome.fileManagerPrivate.getRecentFiles(
-          'native_source', 'audio', chrome.test.callbackPass(entries => {
+          'native_source', 'audio', false, chrome.test.callbackPass(entries => {
             chrome.test.assertFalse(
                 exists(entries, 'all-justice.jpg'),
                 'all-justice.jpg unexpectedly found');
@@ -74,7 +74,7 @@
     },
     function testGetRecentImageFiles() {
       chrome.fileManagerPrivate.getRecentFiles(
-          'native_source', 'image', chrome.test.callbackPass(entries => {
+          'native_source', 'image', false, chrome.test.callbackPass(entries => {
             chrome.test.assertTrue(
                 exists(entries, 'all-justice.jpg'),
                 'all-justice.jpg not found');
@@ -88,7 +88,7 @@
     },
     function testGetRecentVideoFiles() {
       chrome.fileManagerPrivate.getRecentFiles(
-          'native_source', 'video', chrome.test.callbackPass(entries => {
+          'native_source', 'video', false, chrome.test.callbackPass(entries => {
             chrome.test.assertFalse(
                 exists(entries, 'all-justice.jpg'),
                 'all-justice.jpg unexpectedly found');
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js
index d1c3bbb..c29a3215 100644
--- a/chrome/test/data/webui/settings/cr_settings_browsertest.js
+++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -519,8 +519,16 @@
         runMochaSuite('PrivacyGuidePage');
     });
 
+// TODO(crbug.com/1328037): Flaky on Linux Tests(dbg).
+GEN('#if BUILDFLAG(IS_LINUX) && !defined(NDEBUG)');
+GEN('#define MAYBE_PrivacyGuideFragmentMetricsTests \\');
+GEN('  DISABLED_PrivacyGuideFragmentMetricsTests');
+GEN('#else');
+GEN('#define MAYBE_PrivacyGuideFragmentMetricsTests \\');
+GEN('  PrivacyGuideFragmentMetricsTests');
+GEN('#endif');
 TEST_F(
-    'CrSettingsPrivacyGuidePageTest', 'PrivacyGuideFragmentMetricsTests',
+    'CrSettingsPrivacyGuidePageTest', 'MAYBE_PrivacyGuideFragmentMetricsTests',
     function() {
       runMochaSuite('PrivacyGuideFragmentMetrics');
     });
diff --git a/chrome/updater/test/integration_test_commands.h b/chrome/updater/test/integration_test_commands.h
index 39a797bb..eff3830a 100644
--- a/chrome/updater/test/integration_test_commands.h
+++ b/chrome/updater/test/integration_test_commands.h
@@ -94,8 +94,6 @@
   virtual void ExpectLastStarted() const = 0;
   virtual void UninstallApp(const std::string& app_id) const = 0;
 
-  virtual void RunOfflineInstall() = 0;
-
  protected:
   friend class base::RefCountedThreadSafe<IntegrationTestCommands>;
 
diff --git a/chrome/updater/test/integration_test_commands_system.cc b/chrome/updater/test/integration_test_commands_system.cc
index 8a22b04..e9baada 100644
--- a/chrome/updater/test/integration_test_commands_system.cc
+++ b/chrome/updater/test/integration_test_commands_system.cc
@@ -270,10 +270,6 @@
     RunCommand("uninstall_app", {Param("app_id", app_id)});
   }
 
-  void RunOfflineInstall() override {
-    updater::test::RunOfflineInstall(updater_scope_);
-  }
-
  private:
   ~IntegrationTestCommandsSystem() override = default;
 
diff --git a/chrome/updater/test/integration_test_commands_user.cc b/chrome/updater/test/integration_test_commands_user.cc
index 421e5f1..be1c375 100644
--- a/chrome/updater/test/integration_test_commands_user.cc
+++ b/chrome/updater/test/integration_test_commands_user.cc
@@ -234,10 +234,6 @@
     updater::test::UninstallApp(updater_scope_, app_id);
   }
 
-  void RunOfflineInstall() override {
-    updater::test::RunOfflineInstall(updater_scope_);
-  }
-
  private:
   ~IntegrationTestCommandsUser() override = default;
 
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc
index 7cca93b..3f8db104 100644
--- a/chrome/updater/test/integration_tests.cc
+++ b/chrome/updater/test/integration_tests.cc
@@ -301,8 +301,6 @@
 
   void ExpectLastStarted() { test_commands_->ExpectLastStarted(); }
 
-  void RunOfflineInstall() { test_commands_->RunOfflineInstall(); }
-
   scoped_refptr<IntegrationTestCommands> test_commands_;
 
  private:
@@ -753,13 +751,6 @@
   Uninstall();
 }
 
-TEST_F(IntegrationTest, OfflineInstall) {
-  Install();
-  ExpectInstalled();
-  RunOfflineInstall();
-  Uninstall();
-}
-
 #endif  // BUILDFLAG(IS_WIN) || !defined(COMPONENT_BUILD)
 
 }  // namespace test
diff --git a/chrome/updater/test/integration_tests_impl.h b/chrome/updater/test/integration_tests_impl.h
index 29d6a7f..1f332f6 100644
--- a/chrome/updater/test/integration_tests_impl.h
+++ b/chrome/updater/test/integration_tests_impl.h
@@ -216,8 +216,6 @@
 
 void UninstallApp(UpdaterScope scope, const std::string& app_id);
 
-void RunOfflineInstall(UpdaterScope scope);
-
 }  // namespace test
 }  // namespace updater
 
diff --git a/chrome/updater/test/integration_tests_linux.cc b/chrome/updater/test/integration_tests_linux.cc
index 8f23697..c1add23 100644
--- a/chrome/updater/test/integration_tests_linux.cc
+++ b/chrome/updater/test/integration_tests_linux.cc
@@ -102,9 +102,5 @@
   NOTREACHED();
 }
 
-void RunOfflineInstall(UpdaterScope scope) {
-  NOTREACHED();
-}
-
 }  // namespace test
 }  // namespace updater
diff --git a/chrome/updater/test/integration_tests_mac.mm b/chrome/updater/test/integration_tests_mac.mm
index f8e5212..5c583ffe 100644
--- a/chrome/updater/test/integration_tests_mac.mm
+++ b/chrome/updater/test/integration_tests_mac.mm
@@ -418,9 +418,5 @@
                           base::FilePath(FILE_PATH_LITERAL("NONE")));
 }
 
-void RunOfflineInstall(UpdaterScope scope) {
-  // TODO(crbug.com/1286574).
-}
-
 }  // namespace test
 }  // namespace updater
diff --git a/chrome/updater/test/integration_tests_win.cc b/chrome/updater/test/integration_tests_win.cc
index 0f38438..c42a017 100644
--- a/chrome/updater/test/integration_tests_win.cc
+++ b/chrome/updater/test/integration_tests_win.cc
@@ -13,11 +13,9 @@
 #include <vector>
 
 #include "base/command_line.h"
-#include "base/containers/contains.h"
 #include "base/containers/flat_map.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
 #include "base/json/json_writer.h"
 #include "base/logging.h"
 #include "base/path_service.h"
@@ -31,7 +29,6 @@
 #include "base/task/task_traits.h"
 #include "base/task/thread_pool.h"
 #include "base/test/bind.h"
-#include "base/test/test_timeouts.h"
 #include "base/time/time.h"
 #include "base/timer/elapsed_timer.h"
 #include "base/values.h"
@@ -54,10 +51,6 @@
 #include "chrome/updater/util.h"
 #include "chrome/updater/win/setup/setup_util.h"
 #include "chrome/updater/win/task_scheduler.h"
-#include "chrome/updater/win/test/test_executables.h"
-#include "chrome/updater/win/test/test_strings.h"
-#include "chrome/updater/win/ui/l10n_util.h"
-#include "chrome/updater/win/ui/resources/updater_installer_strings.h"
 #include "chrome/updater/win/win_constants.h"
 #include "chrome/updater/win/win_util.h"
 #include "components/crx_file/crx_verifier.h"
@@ -340,63 +333,6 @@
   VLOG(2) << "Sleep complete.";
 }
 
-class WindowEnumerator {
- public:
-  WindowEnumerator(HWND parent,
-                   base::RepeatingCallback<bool(HWND hwnd)> filter,
-                   base::RepeatingCallback<void(HWND hwnd)> action)
-      : parent_(parent), filter_(filter), action_(action) {}
-
-  WindowEnumerator(const WindowEnumerator&) = delete;
-  WindowEnumerator& operator=(const WindowEnumerator&) = delete;
-
-  void Run() const {
-    ::EnumChildWindows(parent_, &OnWindowProc, reinterpret_cast<LPARAM>(this));
-  }
-
-  static std::wstring GetWindowClass(HWND hwnd) {
-    constexpr int kMaxWindowClassNameLength = 256;
-    wchar_t buffer[kMaxWindowClassNameLength + 1] = {0};
-    int name_len = ::GetClassName(hwnd, buffer, std::size(buffer));
-    if (name_len <= 0 || name_len > kMaxWindowClassNameLength)
-      return std::wstring();
-
-    return std::wstring(&buffer[0], name_len);
-  }
-
-  static bool IsSystemDialog(HWND hwnd) {
-    constexpr wchar_t kSystemDialogClass[] = L"#32770";
-    return GetWindowClass(hwnd) == kSystemDialogClass;
-  }
-
-  static std::wstring GetWindowText(HWND hwnd) {
-    const int num_chars = ::GetWindowTextLength(hwnd);
-    if (!num_chars)
-      return std::wstring();
-    std::vector<wchar_t> text(num_chars + 1);
-    if (!::GetWindowText(hwnd, &text.front(), text.size()))
-      return std::wstring();
-    return std::wstring(text.begin(), text.end());
-  }
-
- private:
-  bool OnWindow(HWND hwnd) const {
-    if (filter_.Run(hwnd))
-      action_.Run(hwnd);
-
-    // Returns true to keep enumerating.
-    return true;
-  }
-
-  static BOOL CALLBACK OnWindowProc(HWND hwnd, LPARAM lparam) {
-    return reinterpret_cast<WindowEnumerator*>(lparam)->OnWindow(hwnd);
-  }
-
-  const HWND parent_;
-  base::RepeatingCallback<bool(HWND hwnd)> filter_;
-  base::RepeatingCallback<void(HWND hwnd)> action_;
-};
-
 }  // namespace
 
 base::FilePath GetSetupExecutablePath() {
@@ -1041,128 +977,5 @@
   ASSERT_EQ(key.DeleteKey(base::SysUTF8ToWide(app_id).c_str()), ERROR_SUCCESS);
 }
 
-void RunOfflineInstall(UpdaterScope scope) {
-  const char kManifestFormat[] =
-      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-      "<response protocol=\"3.0\">"
-      "  <app appid=\"{CDABE316-39CD-43BA-8440-6D1E0547AEE6}\" status=\"ok\">"
-      "    <updatecheck status=\"ok\">"
-      "      <manifest version=\"1.2.3.4\">"
-      "        <packages>"
-      "          <package hash_sha256=\"sha256hash_foobar\""
-      "              name=\"%s\""
-      "              required=\"true\""
-      "              size=\"%lld\"/>"
-      "        </packages>"
-      "        <actions>"
-      "          <action event=\"install\" needsadmin=\"false\""
-      "              run=\"%s\""
-      "              arguments=\"--%s=%s\"/>"
-      "        </actions>"
-      "      </manifest>"
-      "    </updatecheck>"
-      "    <data index=\"verboselogging\" name=\"install\" status=\"ok\">"
-      "      {\"distribution\": { \"verbose_logging\": true}}"
-      "    </data>"
-      "  </app>"
-      "</response>";
-
-  // Create a unique name for a shared event to be waited for in this process
-  // and signaled by the app installer to confirm that app installer is run.
-  const std::wstring event_name =
-      base::StrCat({kTestProcessExecutableName, L"-",
-                    base::NumberToWString(::GetCurrentProcessId())});
-  NamedObjectAttributes attr;
-  GetNamedObjectAttributes(event_name.c_str(), scope, &attr);
-
-  base::WaitableEvent event(base::win::ScopedHandle(
-      ::CreateEvent(&attr.sa, FALSE, FALSE, attr.name.c_str())));
-  ASSERT_NE(event.handle(), nullptr);
-
-  base::FilePath exe_dir;
-  ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &exe_dir));
-  base::FilePath exe_path = exe_dir.Append(updater::kTestProcessExecutableName);
-  ASSERT_TRUE(base::PathExists(exe_path));
-
-  base::ScopedTempDir temp_dir;
-  EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
-  const base::FilePath& offline_dir = temp_dir.GetPath();
-
-  // Create manifest file.
-  const std::string exe_name = base::SysWideToUTF8(kTestProcessExecutableName);
-  base::FilePath manifest_path =
-      offline_dir.Append(FILE_PATH_LITERAL("OfflineManifest.gup"));
-  int64_t exe_size = 0;
-  EXPECT_TRUE(base::GetFileSize(exe_path, &exe_size));
-  const std::string manifest =
-      base::StringPrintf(kManifestFormat,
-                         exe_name.c_str(),    // `name` in <package>.
-                         exe_size,            // `size` in <package>.
-                         exe_name.c_str(),    // `run` in <action>.
-                         kTestEventToSignal,  // `arguments` in <action>.
-                         base::SysWideToUTF8(attr.name).c_str());
-  EXPECT_TRUE(base::WriteFile(manifest_path, manifest));
-
-  // Copy app installer.
-  ASSERT_TRUE(
-      base::CopyFile(exe_path, offline_dir.Append(exe_path.BaseName())));
-
-  // Trigger offline install.
-  const absl::optional<base::FilePath> updater_exe =
-      GetInstalledExecutablePath(scope);
-  ASSERT_TRUE(updater_exe.has_value());
-  base::CommandLine offline_install_cmd(updater_exe.value());
-
-  offline_install_cmd.AppendSwitch(kEnableLoggingSwitch);
-  offline_install_cmd.AppendSwitchASCII(kLoggingModuleSwitch,
-                                        kLoggingModuleSwitchValue);
-  if (scope == UpdaterScope::kSystem)
-    offline_install_cmd.AppendSwitch(kSystemSwitch);
-
-  offline_install_cmd.AppendSwitchASCII(
-      updater::kHandoffSwitch,
-      "appguid={CDABE316-39CD-43BA-8440-6D1E0547AEE6}&lang=en&installdataindex="
-      "verboselogging");
-  offline_install_cmd.AppendSwitchASCII(
-      updater::kSessionIdSwitch, "{E85204C6-6F2F-40BF-9E6C-4952208BB977}");
-  offline_install_cmd.AppendSwitchNative(updater::kOfflineDirSwitch,
-                                         offline_dir.value());
-
-  base::Process process = base::LaunchProcess(offline_install_cmd, {});
-  EXPECT_TRUE(process.IsValid());
-
-  // Dismiss the installation completion dialog, then wait for the process exit.
-  WaitFor(base::BindRepeating([]() {
-    // Enumerate the top-level dialogs to find the setup dialog.
-    WindowEnumerator(
-        ::GetDesktopWindow(), base::BindRepeating([](HWND hwnd) {
-          return WindowEnumerator::IsSystemDialog(hwnd) &&
-                 base::Contains(
-                     WindowEnumerator::GetWindowText(hwnd),
-                     GetLocalizedStringF(
-                         IDS_INSTALLER_DISPLAY_NAME_BASE,
-                         GetLocalizedString(IDS_FRIENDLY_COMPANY_NAME_BASE)));
-        }),
-        base::BindRepeating([](HWND hwnd) {
-          // Enumerates the dialog items to search for installation complete
-          // message. Once found, close the dialog.
-          WindowEnumerator(
-              hwnd, base::BindRepeating([](HWND hwnd) {
-                return base::Contains(
-                    WindowEnumerator::GetWindowText(hwnd),
-                    GetLocalizedString(IDS_BUNDLE_INSTALLED_SUCCESSFULLY_BASE));
-              }),
-              base::BindRepeating([](HWND hwnd) {
-                ::PostMessage(::GetParent(hwnd), WM_CLOSE, 0, 0);
-              }))
-              .Run();
-        }))
-        .Run();
-    return !IsUpdaterRunning();
-  }));
-
-  EXPECT_TRUE(event.TimedWait(TestTimeouts::action_timeout()));
-}
-
 }  // namespace test
 }  // namespace updater
diff --git a/chromecast/media/cma/backend/alsa/BUILD.gn b/chromecast/media/cma/backend/alsa/BUILD.gn
index ed3dc90..2a2a9797 100644
--- a/chromecast/media/cma/backend/alsa/BUILD.gn
+++ b/chromecast/media/cma/backend/alsa/BUILD.gn
@@ -46,6 +46,8 @@
   sources = [
     "alsa_volume_control.cc",
     "alsa_volume_control.h",
+    "scoped_alsa_mixer.cc",
+    "scoped_alsa_mixer.h",
   ]
 
   libs = [ "asound" ]
diff --git a/chromecast/media/cma/backend/alsa/alsa_volume_control.cc b/chromecast/media/cma/backend/alsa/alsa_volume_control.cc
index d6cb1009..fac9b76 100644
--- a/chromecast/media/cma/backend/alsa/alsa_volume_control.cc
+++ b/chromecast/media/cma/backend/alsa/alsa_volume_control.cc
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/check.h"
 #include "base/command_line.h"
 #include "base/location.h"
 #include "base/logging.h"
@@ -15,6 +16,7 @@
 #include "base/task/current_thread.h"
 #include "chromecast/base/chromecast_switches.h"
 #include "chromecast/base/metrics/cast_metrics_helper.h"
+#include "chromecast/media/cma/backend/alsa/scoped_alsa_mixer.h"
 #include "media/base/media_switches.h"
 
 #define ALSA_ASSERT(func, ...)                                        \
@@ -36,76 +38,6 @@
 
 }  // namespace
 
-class AlsaVolumeControl::ScopedAlsaMixer {
- public:
-  ScopedAlsaMixer(::media::AlsaWrapper* alsa,
-                  const std::string& mixer_device_name,
-                  const std::string& mixer_element_name)
-      : alsa_(alsa),
-        mixer_device_name_(mixer_device_name),
-        mixer_element_name_(mixer_element_name) {
-    DCHECK(alsa_);
-    Refresh();
-  }
-
-  ~ScopedAlsaMixer() {
-    if (mixer) {
-      alsa_->MixerClose(mixer);
-    }
-  }
-
-  void Refresh() {
-    if (mixer) {
-      alsa_->MixerClose(mixer);
-      DVLOG(2) << "Reopening mixer element \"" << mixer_element_name_
-               << "\" on device \"" << mixer_device_name_ << "\"";
-    } else {
-      LOG(INFO) << "Opening mixer element \"" << mixer_element_name_
-                << "\" on device \"" << mixer_device_name_ << "\"";
-    }
-
-    int alsa_err = alsa_->MixerOpen(&mixer, 0);
-    if (alsa_err < 0) {
-      LOG(ERROR) << "MixerOpen error: " << alsa_->StrError(alsa_err);
-      mixer = nullptr;
-      return;
-    }
-    alsa_err = alsa_->MixerAttach(mixer, mixer_device_name_.c_str());
-    if (alsa_err < 0) {
-      LOG(ERROR) << "MixerAttach error: " << alsa_->StrError(alsa_err);
-      alsa_->MixerClose(mixer);
-      mixer = nullptr;
-      return;
-    }
-    ALSA_ASSERT(MixerElementRegister, mixer, NULL, NULL);
-    alsa_err = alsa_->MixerLoad(mixer);
-    if (alsa_err < 0) {
-      LOG(ERROR) << "MixerLoad error: " << alsa_->StrError(alsa_err);
-      alsa_->MixerClose(mixer);
-      mixer = nullptr;
-      return;
-    }
-    snd_mixer_selem_id_t* sid = NULL;
-    ALSA_ASSERT(MixerSelemIdMalloc, &sid);
-    alsa_->MixerSelemIdSetIndex(sid, 0);
-    alsa_->MixerSelemIdSetName(sid, mixer_element_name_.c_str());
-    element = alsa_->MixerFindSelem(mixer, sid);
-    if (!element) {
-      LOG(ERROR) << "Simple mixer control element \"" << mixer_element_name_
-                 << "\" not found.";
-    }
-    alsa_->MixerSelemIdFree(sid);
-  }
-
-  snd_mixer_elem_t* element = nullptr;
-  snd_mixer_t* mixer = nullptr;
-
- private:
-  ::media::AlsaWrapper* const alsa_;
-  const std::string mixer_device_name_;
-  const std::string mixer_element_name_;
-};
-
 // static
 std::string AlsaVolumeControl::GetVolumeElementName() {
   std::string mixer_element_name =
@@ -270,7 +202,8 @@
       mute_mixer_ptr_ = mute_mixer_.get();
 
       alsa_->MixerElemSetCallback(
-          mute_mixer_->element, &AlsaVolumeControl::VolumeOrMuteChangeCallback);
+          mute_mixer_->element,
+          &AlsaVolumeControl::VolumeOrMuteChangeCallback);
       alsa_->MixerElemSetCallbackPrivate(mute_mixer_->element,
                                          reinterpret_cast<void*>(this));
       RefreshMixerFds(mute_mixer_.get());
diff --git a/chromecast/media/cma/backend/alsa/alsa_volume_control.h b/chromecast/media/cma/backend/alsa/alsa_volume_control.h
index 72656104..16261f37 100644
--- a/chromecast/media/cma/backend/alsa/alsa_volume_control.h
+++ b/chromecast/media/cma/backend/alsa/alsa_volume_control.h
@@ -17,6 +17,7 @@
 
 namespace chromecast {
 namespace media {
+class ScopedAlsaMixer;
 
 // SystemVolumeControl implementation for ALSA.
 class AlsaVolumeControl : public SystemVolumeControl,
@@ -41,8 +42,6 @@
   void CheckPowerSave();
 
  private:
-  class ScopedAlsaMixer;
-
   static std::string GetVolumeElementName();
   static std::string GetVolumeDeviceName();
   static std::string GetMuteElementName(::media::AlsaWrapper* alsa,
diff --git a/chromecast/media/cma/backend/alsa/scoped_alsa_mixer.cc b/chromecast/media/cma/backend/alsa/scoped_alsa_mixer.cc
new file mode 100644
index 0000000..1703304
--- /dev/null
+++ b/chromecast/media/cma/backend/alsa/scoped_alsa_mixer.cc
@@ -0,0 +1,79 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromecast/media/cma/backend/alsa/scoped_alsa_mixer.h"
+
+#include "base/check.h"
+#include "base/logging.h"
+
+#define ALSA_ASSERT(func, ...)                                        \
+  do {                                                                \
+    int err = alsa_->func(__VA_ARGS__);                               \
+    LOG_ASSERT(err >= 0) << #func " error: " << alsa_->StrError(err); \
+  } while (0)
+
+namespace chromecast {
+namespace media {
+
+ScopedAlsaMixer::ScopedAlsaMixer(::media::AlsaWrapper* alsa,
+                                 const std::string& mixer_device_name,
+                                 const std::string& mixer_element_name)
+    : alsa_(alsa),
+      mixer_device_name_(mixer_device_name),
+      mixer_element_name_(mixer_element_name) {
+  DCHECK(alsa_);
+  Refresh();
+}
+
+ScopedAlsaMixer::~ScopedAlsaMixer() {
+  if (mixer) {
+    alsa_->MixerClose(mixer);
+  }
+}
+
+void ScopedAlsaMixer::Refresh() {
+  if (mixer) {
+    alsa_->MixerClose(mixer);
+    DVLOG(2) << "Reopening mixer element \"" << mixer_element_name_
+             << "\" on device \"" << mixer_device_name_ << "\"";
+  } else {
+    LOG(INFO) << "Opening mixer element \"" << mixer_element_name_
+              << "\" on device \"" << mixer_device_name_ << "\"";
+  }
+
+  int alsa_err = alsa_->MixerOpen(&mixer, 0);
+  if (alsa_err < 0) {
+    LOG(ERROR) << "MixerOpen error: " << alsa_->StrError(alsa_err);
+    mixer = nullptr;
+    return;
+  }
+  alsa_err = alsa_->MixerAttach(mixer, mixer_device_name_.c_str());
+  if (alsa_err < 0) {
+    LOG(ERROR) << "MixerAttach error: " << alsa_->StrError(alsa_err);
+    alsa_->MixerClose(mixer);
+    mixer = nullptr;
+    return;
+  }
+  ALSA_ASSERT(MixerElementRegister, mixer, nullptr, nullptr);
+  alsa_err = alsa_->MixerLoad(mixer);
+  if (alsa_err < 0) {
+    LOG(ERROR) << "MixerLoad error: " << alsa_->StrError(alsa_err);
+    alsa_->MixerClose(mixer);
+    mixer = nullptr;
+    return;
+  }
+  snd_mixer_selem_id_t* sid = nullptr;
+  ALSA_ASSERT(MixerSelemIdMalloc, &sid);
+  alsa_->MixerSelemIdSetIndex(sid, 0);
+  alsa_->MixerSelemIdSetName(sid, mixer_element_name_.c_str());
+  element = alsa_->MixerFindSelem(mixer, sid);
+  if (!element) {
+    LOG(ERROR) << "Simple mixer control element \"" << mixer_element_name_
+               << "\" not found.";
+  }
+  alsa_->MixerSelemIdFree(sid);
+}
+
+}  // namespace media
+}  // namespace chromecast
diff --git a/chromecast/media/cma/backend/alsa/scoped_alsa_mixer.h b/chromecast/media/cma/backend/alsa/scoped_alsa_mixer.h
new file mode 100644
index 0000000..75f3be7
--- /dev/null
+++ b/chromecast/media/cma/backend/alsa/scoped_alsa_mixer.h
@@ -0,0 +1,39 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMECAST_MEDIA_CMA_BACKEND_ALSA_SCOPED_ALSA_MIXER_H_
+#define CHROMECAST_MEDIA_CMA_BACKEND_ALSA_SCOPED_ALSA_MIXER_H_
+
+#include <string>
+
+#include "media/audio/alsa/alsa_wrapper.h"
+
+namespace chromecast {
+namespace media {
+
+class ScopedAlsaMixer {
+ public:
+  ScopedAlsaMixer(::media::AlsaWrapper* alsa,
+                  const std::string& mixer_device_name,
+                  const std::string& mixer_element_name);
+  ~ScopedAlsaMixer();
+  ScopedAlsaMixer(const ScopedAlsaMixer&) = delete;
+  ScopedAlsaMixer& operator=(const ScopedAlsaMixer&) = delete;
+
+  void Refresh();
+
+  snd_mixer_elem_t* element = nullptr;
+  snd_mixer_t* mixer = nullptr;
+
+ private:
+  ::media::AlsaWrapper* const alsa_;
+
+  const std::string mixer_device_name_;
+  const std::string mixer_element_name_;
+};
+
+}  // namespace media
+}  // namespace chromecast
+
+#endif  // CHROMECAST_MEDIA_CMA_BACKEND_ALSA_SCOPED_ALSA_MIXER_H_
diff --git a/chromeos/ash/components/dbus/concierge/concierge_client.cc b/chromeos/ash/components/dbus/concierge/concierge_client.cc
index b3c5ecb..e563231 100644
--- a/chromeos/ash/components/dbus/concierge/concierge_client.cc
+++ b/chromeos/ash/components/dbus/concierge/concierge_client.cc
@@ -139,17 +139,16 @@
     CallMethod(concierge::kListVmDisksMethod, request, std::move(callback));
   }
 
-  void StartTerminaVm(
+  void StartVm(
       const concierge::StartVmRequest& request,
       DBusMethodCallback<concierge::StartVmResponse> callback) override {
     CallMethod(concierge::kStartVmMethod, request, std::move(callback));
   }
 
-  void StartTerminaVmWithFd(
-      base::ScopedFD fd,
-      const vm_tools::concierge::StartVmRequest& request,
-      DBusMethodCallback<vm_tools::concierge::StartVmResponse> callback)
-      override {
+  void StartVmWithFd(base::ScopedFD fd,
+                     const vm_tools::concierge::StartVmRequest& request,
+                     DBusMethodCallback<vm_tools::concierge::StartVmResponse>
+                         callback) override {
     CallMethodWithFd(concierge::kStartVmMethod, request, std::move(fd),
                      std::move(callback));
   }
diff --git a/chromeos/ash/components/dbus/concierge/concierge_client.h b/chromeos/ash/components/dbus/concierge/concierge_client.h
index 6c2e7cbe..d2445721 100644
--- a/chromeos/ash/components/dbus/concierge/concierge_client.h
+++ b/chromeos/ash/components/dbus/concierge/concierge_client.h
@@ -167,14 +167,14 @@
 
   // Starts a Termina VM if there is not already one running.
   // |callback| is called after the method call finishes.
-  virtual void StartTerminaVm(
+  virtual void StartVm(
       const vm_tools::concierge::StartVmRequest& request,
       DBusMethodCallback<vm_tools::concierge::StartVmResponse> callback) = 0;
 
   // Starts a Termina VM if there is not already one running.
   // |fd| references an extra image for concierge to use.
   // |callback| is called after the method call finishes.
-  virtual void StartTerminaVmWithFd(
+  virtual void StartVmWithFd(
       base::ScopedFD fd,
       const vm_tools::concierge::StartVmRequest& request,
       DBusMethodCallback<vm_tools::concierge::StartVmResponse> callback) = 0;
diff --git a/chromeos/ash/components/dbus/concierge/fake_concierge_client.cc b/chromeos/ash/components/dbus/concierge/fake_concierge_client.cc
index 8296574..d6fb7de 100644
--- a/chromeos/ash/components/dbus/concierge/fake_concierge_client.cc
+++ b/chromeos/ash/components/dbus/concierge/fake_concierge_client.cc
@@ -183,10 +183,10 @@
       FROM_HERE, base::BindOnce(std::move(callback), list_vm_disks_response_));
 }
 
-void FakeConciergeClient::StartTerminaVm(
+void FakeConciergeClient::StartVm(
     const vm_tools::concierge::StartVmRequest& request,
     DBusMethodCallback<vm_tools::concierge::StartVmResponse> callback) {
-  start_termina_vm_call_count_++;
+  start_vm_call_count_++;
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE, base::BindOnce(std::move(callback), start_vm_response_),
       send_start_vm_response_delay_);
@@ -218,11 +218,11 @@
                                 std::move(vm_started_signal)));
 }
 
-void FakeConciergeClient::StartTerminaVmWithFd(
+void FakeConciergeClient::StartVmWithFd(
     base::ScopedFD fd,
     const vm_tools::concierge::StartVmRequest& request,
     DBusMethodCallback<vm_tools::concierge::StartVmResponse> callback) {
-  StartTerminaVm(std::move(request), std::move(callback));
+  StartVm(std::move(request), std::move(callback));
 }
 
 void FakeConciergeClient::NotifyTremplinStarted(
diff --git a/chromeos/ash/components/dbus/concierge/fake_concierge_client.h b/chromeos/ash/components/dbus/concierge/fake_concierge_client.h
index 7345e91..f5398eb 100644
--- a/chromeos/ash/components/dbus/concierge/fake_concierge_client.h
+++ b/chromeos/ash/components/dbus/concierge/fake_concierge_client.h
@@ -74,14 +74,13 @@
   void ListVmDisks(const vm_tools::concierge::ListVmDisksRequest& request,
                    DBusMethodCallback<vm_tools::concierge::ListVmDisksResponse>
                        callback) override;
-  void StartTerminaVm(const vm_tools::concierge::StartVmRequest& request,
-                      DBusMethodCallback<vm_tools::concierge::StartVmResponse>
-                          callback) override;
-  void StartTerminaVmWithFd(
-      base::ScopedFD fd,
-      const vm_tools::concierge::StartVmRequest& request,
-      DBusMethodCallback<vm_tools::concierge::StartVmResponse> callback)
-      override;
+  void StartVm(const vm_tools::concierge::StartVmRequest& request,
+               DBusMethodCallback<vm_tools::concierge::StartVmResponse>
+                   callback) override;
+  void StartVmWithFd(base::ScopedFD fd,
+                     const vm_tools::concierge::StartVmRequest& request,
+                     DBusMethodCallback<vm_tools::concierge::StartVmResponse>
+                         callback) override;
   void StopVm(const vm_tools::concierge::StopVmRequest& request,
               DBusMethodCallback<vm_tools::concierge::StopVmResponse> callback)
       override;
@@ -171,9 +170,7 @@
     return import_disk_image_call_count_;
   }
   int list_vm_disks_call_count() const { return list_vm_disks_call_count_; }
-  int start_termina_vm_call_count() const {
-    return start_termina_vm_call_count_;
-  }
+  int start_vm_call_count() const { return start_vm_call_count_; }
   int stop_vm_call_count() const { return stop_vm_call_count_; }
   int get_vm_info_call_count() const { return get_vm_info_call_count_; }
   int get_vm_enterprise_reporting_info_call_count() const {
@@ -364,7 +361,7 @@
   int import_disk_image_call_count_ = 0;
   int disk_image_status_call_count_ = 0;
   int list_vm_disks_call_count_ = 0;
-  int start_termina_vm_call_count_ = 0;
+  int start_vm_call_count_ = 0;
   int stop_vm_call_count_ = 0;
   int get_vm_info_call_count_ = 0;
   int get_vm_enterprise_reporting_info_call_count_ = 0;
diff --git a/components/android_autofill/browser/android_autofill_manager.cc b/components/android_autofill/browser/android_autofill_manager.cc
index aba3742c..945ddfc 100644
--- a/components/android_autofill/browser/android_autofill_manager.cc
+++ b/components/android_autofill/browser/android_autofill_manager.cc
@@ -94,10 +94,12 @@
     const FormData& form,
     const FormFieldData& field,
     const gfx::RectF& bounding_box,
-    bool autoselect_first_suggestion) {
+    bool autoselect_first_suggestion,
+    TouchToFillEligible touch_to_fill_eligible) {
   if (auto* provider = GetAutofillProvider()) {
     provider->OnAskForValuesToFill(this, query_id, form, field, bounding_box,
-                                   autoselect_first_suggestion);
+                                   autoselect_first_suggestion,
+                                   touch_to_fill_eligible);
   }
 }
 
diff --git a/components/android_autofill/browser/android_autofill_manager.h b/components/android_autofill/browser/android_autofill_manager.h
index d99d684..a19fa3f3 100644
--- a/components/android_autofill/browser/android_autofill_manager.h
+++ b/components/android_autofill/browser/android_autofill_manager.h
@@ -99,11 +99,13 @@
                                 const FormFieldData& field,
                                 const gfx::RectF& bounding_box) override;
 
-  void OnAskForValuesToFillImpl(int query_id,
-                                const FormData& form,
-                                const FormFieldData& field,
-                                const gfx::RectF& bounding_box,
-                                bool autoselect_first_suggestion) override;
+  void OnAskForValuesToFillImpl(
+      int query_id,
+      const FormData& form,
+      const FormFieldData& field,
+      const gfx::RectF& bounding_box,
+      bool autoselect_first_suggestion,
+      TouchToFillEligible touch_to_fill_eligible) override;
 
   void OnFocusOnFormFieldImpl(const FormData& form,
                               const FormFieldData& field,
diff --git a/components/android_autofill/browser/autofill_provider.h b/components/android_autofill/browser/autofill_provider.h
index dca4a6b..685d1b9 100644
--- a/components/android_autofill/browser/autofill_provider.h
+++ b/components/android_autofill/browser/autofill_provider.h
@@ -34,12 +34,14 @@
   static bool is_download_manager_disabled_for_testing();
   static void set_is_download_manager_disabled_for_testing();
 
-  virtual void OnAskForValuesToFill(AndroidAutofillManager* manager,
-                                    int32_t id,
-                                    const FormData& form,
-                                    const FormFieldData& field,
-                                    const gfx::RectF& bounding_box,
-                                    bool autoselect_first_suggestion) = 0;
+  virtual void OnAskForValuesToFill(
+      AndroidAutofillManager* manager,
+      int32_t query_id,
+      const FormData& form,
+      const FormFieldData& field,
+      const gfx::RectF& bounding_box,
+      bool autoselect_first_suggestion,
+      TouchToFillEligible touch_to_fill_eligible) = 0;
 
   virtual void OnTextFieldDidChange(AndroidAutofillManager* manager,
                                     const FormData& form,
diff --git a/components/android_autofill/browser/autofill_provider_android.cc b/components/android_autofill/browser/autofill_provider_android.cc
index f8b9fe77..01768e8 100644
--- a/components/android_autofill/browser/autofill_provider_android.cc
+++ b/components/android_autofill/browser/autofill_provider_android.cc
@@ -102,16 +102,17 @@
 
 void AutofillProviderAndroid::OnAskForValuesToFill(
     AndroidAutofillManager* manager,
-    int32_t id,
+    int32_t query_id,
     const FormData& form,
     const FormFieldData& field,
     const gfx::RectF& bounding_box,
-    bool /*unused_autoselect_first_suggestion*/) {
+    bool /*unused_autoselect_first_suggestion*/,
+    TouchToFillEligible /*unused_touch_to_fill_eligible*/) {
   // The id isn't passed to Java side because Android API guarantees the
   // response is always for current session, so we just use the current id
   // in response, see OnAutofillAvailable.
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  id_ = id;
+  id_ = query_id;
 
   // Focus or field value change will also trigger the query, so it should be
   // ignored if the form is same.
diff --git a/components/android_autofill/browser/autofill_provider_android.h b/components/android_autofill/browser/autofill_provider_android.h
index b8c405a2..873d77f7 100644
--- a/components/android_autofill/browser/autofill_provider_android.h
+++ b/components/android_autofill/browser/autofill_provider_android.h
@@ -49,11 +49,12 @@
   // AutofillProvider:
   void OnAskForValuesToFill(
       AndroidAutofillManager* manager,
-      int32_t id,
+      int32_t query_id,
       const FormData& form,
       const FormFieldData& field,
       const gfx::RectF& bounding_box,
-      bool /*unused_autoselect_first_suggestion*/) override;
+      bool /*unused_autoselect_first_suggestion*/,
+      TouchToFillEligible /*unused_touch_to_fill_eligible*/) override;
   void OnTextFieldDidChange(AndroidAutofillManager* manager,
                             const FormData& form,
                             const FormFieldData& field,
diff --git a/components/android_autofill/browser/autofill_provider_unittest.cc b/components/android_autofill/browser/autofill_provider_unittest.cc
index f4ae486..b205f866 100644
--- a/components/android_autofill/browser/autofill_provider_unittest.cc
+++ b/components/android_autofill/browser/autofill_provider_unittest.cc
@@ -25,7 +25,8 @@
 
   void SimulateOnAskForValuesToFillImpl() {
     OnAskForValuesToFillImpl(0, FormData(), FormFieldData(), gfx::RectF(),
-                             /*autoselect_first_suggestion=*/false);
+                             /*autoselect_first_suggestion=*/false,
+                             TouchToFillEligible(false));
   }
 };
 
@@ -38,12 +39,14 @@
 
  private:
   // AutofillProvider
-  void OnAskForValuesToFill(AndroidAutofillManager* manager,
-                            int32_t id,
-                            const FormData& form,
-                            const FormFieldData& field,
-                            const gfx::RectF& bounding_box,
-                            bool autoselect_first_suggestion) override {
+  void OnAskForValuesToFill(
+      AndroidAutofillManager* manager,
+      int32_t query_id,
+      const FormData& form,
+      const FormFieldData& field,
+      const gfx::RectF& bounding_box,
+      bool autoselect_first_suggestion,
+      TouchToFillEligible touch_to_fill_eligible) override {
     manager_ = manager;
   }
   void OnServerQueryRequestError(AndroidAutofillManager* manager,
diff --git a/components/android_autofill/browser/test_autofill_provider.h b/components/android_autofill/browser/test_autofill_provider.h
index dcb28fa..666b67e 100644
--- a/components/android_autofill/browser/test_autofill_provider.h
+++ b/components/android_autofill/browser/test_autofill_provider.h
@@ -20,12 +20,14 @@
   ~TestAutofillProvider() override = default;
 
   // AutofillProvider:
-  void OnAskForValuesToFill(AndroidAutofillManager* manager,
-                            int32_t id,
-                            const FormData& form,
-                            const FormFieldData& field,
-                            const gfx::RectF& bounding_box,
-                            bool autoselect_first_suggestion) override {}
+  void OnAskForValuesToFill(
+      AndroidAutofillManager* manager,
+      int32_t query_id,
+      const FormData& form,
+      const FormFieldData& field,
+      const gfx::RectF& bounding_box,
+      bool autoselect_first_suggestion,
+      TouchToFillEligible touch_to_fill_eligible) override {}
   void OnTextFieldDidChange(AndroidAutofillManager* manager,
                             const FormData& form,
                             const FormFieldData& field,
diff --git a/components/autofill/content/browser/content_autofill_driver.cc b/components/autofill/content/browser/content_autofill_driver.cc
index 7e13122..2d864b4 100644
--- a/components/autofill/content/browser/content_autofill_driver.cc
+++ b/components/autofill/content/browser/content_autofill_driver.cc
@@ -331,13 +331,15 @@
 }
 
 void ContentAutofillDriver::AskForValuesToFillImpl(
-    int32_t id,
+    int32_t query_id,
     const FormData& form,
     const FormFieldData& field,
     const gfx::RectF& bounding_box,
-    bool autoselect_first_suggestion) {
-  autofill_manager_->OnAskForValuesToFill(id, form, field, bounding_box,
-                                          autoselect_first_suggestion);
+    bool autoselect_first_suggestion,
+    TouchToFillEligible touch_to_fill_eligible) {
+  autofill_manager_->OnAskForValuesToFill(query_id, form, field, bounding_box,
+                                          autoselect_first_suggestion,
+                                          touch_to_fill_eligible);
 }
 
 void ContentAutofillDriver::HidePopupImpl() {
@@ -478,20 +480,21 @@
 }
 
 void ContentAutofillDriver::AskForValuesToFill(
-    int32_t id,
+    int32_t query_id,
     const FormData& raw_form,
     const FormFieldData& raw_field,
     const gfx::RectF& bounding_box,
-    bool autoselect_first_suggestion) {
+    bool autoselect_first_suggestion,
+    TouchToFillEligible touch_to_fill_eligible) {
   if (!bad_message::CheckFrameNotPrerendering(render_frame_host_))
     return;
   FormData form = raw_form;
   FormFieldData field = raw_field;
   SetFrameAndFormMetaData(form, &field);
   GetAutofillRouter().AskForValuesToFill(
-      this, id, form, field,
+      this, query_id, form, field,
       TransformBoundingBoxToViewportCoordinates(bounding_box),
-      autoselect_first_suggestion);
+      autoselect_first_suggestion, touch_to_fill_eligible);
 }
 
 void ContentAutofillDriver::HidePopup() {
diff --git a/components/autofill/content/browser/content_autofill_driver.h b/components/autofill/content/browser/content_autofill_driver.h
index 03159d93..28c1099 100644
--- a/components/autofill/content/browser/content_autofill_driver.h
+++ b/components/autofill/content/browser/content_autofill_driver.h
@@ -221,11 +221,12 @@
   void SelectControlDidChange(const FormData& form,
                               const FormFieldData& field,
                               const gfx::RectF& bounding_box) override;
-  void AskForValuesToFill(int32_t id,
+  void AskForValuesToFill(int32_t query_id,
                           const FormData& form,
                           const FormFieldData& field,
                           const gfx::RectF& bounding_box,
-                          bool autoselect_first_suggestion) override;
+                          bool autoselect_first_suggestion,
+                          TouchToFillEligible touch_to_fill_eligible) override;
   void HidePopup() override;
   void FocusNoLongerOnForm(bool had_interacted_form) override;
   void FocusOnFormField(const FormData& form,
@@ -255,11 +256,12 @@
   void SelectControlDidChangeImpl(const FormData& form,
                                   const FormFieldData& field,
                                   const gfx::RectF& bounding_box);
-  void AskForValuesToFillImpl(int32_t id,
+  void AskForValuesToFillImpl(int32_t query_id,
                               const FormData& form,
                               const FormFieldData& field,
                               const gfx::RectF& bounding_box,
-                              bool autoselect_first_suggestion);
+                              bool autoselect_first_suggestion,
+                              TouchToFillEligible touch_to_fill_eligible);
   void HidePopupImpl();
   void FocusNoLongerOnFormImpl(bool had_interacted_form);
   void FocusOnFormFieldImpl(const FormData& form,
diff --git a/components/autofill/content/browser/content_autofill_driver_factory_unittest.cc b/components/autofill/content/browser/content_autofill_driver_factory_unittest.cc
index 75dab6a4..cb88436 100644
--- a/components/autofill/content/browser/content_autofill_driver_factory_unittest.cc
+++ b/components/autofill/content/browser/content_autofill_driver_factory_unittest.cc
@@ -49,7 +49,7 @@
   MOCK_METHOD(void, TriggerReparse, (), (override));
   MOCK_METHOD(void,
               FillOrPreviewForm,
-              (int32_t id,
+              (int32_t query_id,
                const FormData& form,
                mojom::RendererFormDataAction action),
               (override));
diff --git a/components/autofill/content/browser/content_autofill_driver_unittest.cc b/components/autofill/content/browser/content_autofill_driver_unittest.cc
index 3bee7721..4beff3e 100644
--- a/components/autofill/content/browser/content_autofill_driver_unittest.cc
+++ b/components/autofill/content/browser/content_autofill_driver_unittest.cc
@@ -166,14 +166,14 @@
   // mojom::AutofillAgent:
   void TriggerReparse() override {}
 
-  void FillOrPreviewForm(int32_t id,
+  void FillOrPreviewForm(int32_t query_id,
                          const FormData& form,
                          mojom::RendererFormDataAction action) override {
     if (action == mojom::RendererFormDataAction::kPreview) {
-      preview_form_id_ = id;
+      preview_form_id_ = query_id;
       preview_form_form_ = form;
     } else {
-      fill_form_id_ = id;
+      fill_form_id_ = query_id;
       fill_form_form_ = form;
     }
     CallDone();
diff --git a/components/autofill/content/browser/content_autofill_router.cc b/components/autofill/content/browser/content_autofill_router.cc
index 229be2e..4f366501 100644
--- a/components/autofill/content/browser/content_autofill_router.cc
+++ b/components/autofill/content/browser/content_autofill_router.cc
@@ -349,14 +349,16 @@
 
 void ContentAutofillRouter::AskForValuesToFill(
     ContentAutofillDriver* source,
-    int32_t id,
+    int32_t query_id,
     const FormData& form,
     const FormFieldData& field,
     const gfx::RectF& bounding_box,
-    bool autoselect_first_suggestion) {
+    bool autoselect_first_suggestion,
+    TouchToFillEligible touch_to_fill_eligible) {
   if (!base::FeatureList::IsEnabled(features::kAutofillAcrossIframes)) {
-    source->AskForValuesToFillImpl(id, form, field, bounding_box,
-                                   autoselect_first_suggestion);
+    source->AskForValuesToFillImpl(query_id, form, field, bounding_box,
+                                   autoselect_first_suggestion,
+                                   touch_to_fill_eligible);
     return;
   }
 
@@ -372,8 +374,9 @@
   AFCHECK(target, return );
   SetLastQueriedSource(source);
   SetLastQueriedTarget(target);
-  target->AskForValuesToFillImpl(id, browser_form, field, bounding_box,
-                                 autoselect_first_suggestion);
+  target->AskForValuesToFillImpl(query_id, browser_form, field, bounding_box,
+                                 autoselect_first_suggestion,
+                                 touch_to_fill_eligible);
 }
 
 void ContentAutofillRouter::HidePopup(ContentAutofillDriver* source) {
diff --git a/components/autofill/content/browser/content_autofill_router.h b/components/autofill/content/browser/content_autofill_router.h
index ddeb5dbd..b4ce114 100644
--- a/components/autofill/content/browser/content_autofill_router.h
+++ b/components/autofill/content/browser/content_autofill_router.h
@@ -189,11 +189,12 @@
                               const FormFieldData& field,
                               const gfx::RectF& bounding_box);
   void AskForValuesToFill(ContentAutofillDriver* source_driver,
-                          int32_t id,
+                          int32_t query_id,
                           const FormData& form,
                           const FormFieldData& field,
                           const gfx::RectF& bounding_box,
-                          bool autoselect_first_suggestion);
+                          bool autoselect_first_suggestion,
+                          TouchToFillEligible touch_to_fill_eligible);
   void HidePopup(ContentAutofillDriver* source_driver);
   void FocusNoLongerOnForm(ContentAutofillDriver* source_driver,
                            bool had_interacted_form);
diff --git a/components/autofill/content/common/mojom/autofill_agent.mojom b/components/autofill/content/common/mojom/autofill_agent.mojom
index 0e35c55b..65a019d 100644
--- a/components/autofill/content/common/mojom/autofill_agent.mojom
+++ b/components/autofill/content/common/mojom/autofill_agent.mojom
@@ -16,8 +16,10 @@
 
   // Instructs the renderer to fill or preview the active form with the given
   // form data. Refer to AutofillDriver.AskForValuesToFill for comments
-  // about the |id|.
-  FillOrPreviewForm(int32 id, FormData form, RendererFormDataAction action);
+  // about the |query_id|.
+  FillOrPreviewForm(int32 query_id,
+                    FormData form,
+                    RendererFormDataAction action);
 
   // Sends the heuristic and server field type predictions to the renderer.
   FieldTypePredictionsAvailable(array<FormDataPredictions> forms);
diff --git a/components/autofill/content/common/mojom/autofill_driver.mojom b/components/autofill/content/common/mojom/autofill_driver.mojom
index d92cc1b..5fa1c41 100644
--- a/components/autofill/content/common/mojom/autofill_driver.mojom
+++ b/components/autofill/content/common/mojom/autofill_driver.mojom
@@ -52,12 +52,16 @@
 
   // Queries the browser for Autofill suggestions for a form input field.
   // For autofill this means asking the user which values to fill.
-  // |id| is the request ID which is used to map responses correctly.
-  AskForValuesToFill(int32 id,
-                         FormData form,
-                         FormFieldData field,
-                         gfx.mojom.RectF bounding_box,
-                         bool autoselect_first_suggestion);
+  // |query_id| is the request ID which is used to map responses correctly.
+  // |touch_to_fill_eligible| indicates if the Touch To Fill surface could
+  // be used for showing suggestions (e.g. when the user taps an input element
+  // but not on text change).
+  AskForValuesToFill(int32 query_id,
+                     FormData form,
+                     FormFieldData field,
+                     gfx.mojom.RectF bounding_box,
+                     bool autoselect_first_suggestion,
+                     TouchToFillEligible touch_to_fill_eligible);
 
   // Instructs the browser to hide the Autofill popup if it is open.
   HidePopup();
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc
index abbaee56..f8448c6 100644
--- a/components/autofill/content/renderer/autofill_agent.cc
+++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -176,13 +176,14 @@
   void SelectFieldOptionsDidChange(const FormData& form) override {
     DeferMsg(&mojom::AutofillDriver::SelectFieldOptionsDidChange, form);
   }
-  void AskForValuesToFill(int32_t id,
+  void AskForValuesToFill(int32_t query_id,
                           const FormData& form,
                           const FormFieldData& field,
                           const gfx::RectF& bounding_box,
-                          bool autoselect_first_suggestion) override {
-    DeferMsg(&mojom::AutofillDriver::AskForValuesToFill, id, form, field,
-             bounding_box, autoselect_first_suggestion);
+                          bool autoselect_first_suggestion,
+                          TouchToFillEligible touch_to_fill_eligible) override {
+    DeferMsg(&mojom::AutofillDriver::AskForValuesToFill, query_id, form, field,
+             bounding_box, autoselect_first_suggestion, touch_to_fill_eligible);
   }
   void HidePopup() override { DeferMsg(&mojom::AutofillDriver::HidePopup); }
   void FocusNoLongerOnForm(bool had_interacted_form) override {
@@ -209,12 +210,6 @@
   base::WeakPtrFactory<DeferringAutofillDriver> weak_ptr_factory_{this};
 };
 
-AutofillAgent::ShowSuggestionsOptions::ShowSuggestionsOptions()
-    : autofill_on_empty_values(false),
-      requires_caret_at_end(false),
-      show_full_suggestion_list(false),
-      autoselect_first_suggestion(false) {}
-
 AutofillAgent::AutofillAgent(content::RenderFrame* render_frame,
                              PasswordAutofillAgent* password_autofill_agent,
                              PasswordGenerationAgent* password_generation_agent,
@@ -443,9 +438,7 @@
     return;
   }
 
-  ShowSuggestionsOptions options;
-  options.requires_caret_at_end = true;
-  ShowSuggestions(element, options);
+  ShowSuggestions(element, {.requires_caret_at_end = true});
 
   FormData form;
   FormFieldData field;
@@ -465,21 +458,17 @@
 
   if (event.windows_key_code == ui::VKEY_DOWN ||
       event.windows_key_code == ui::VKEY_UP) {
-    ShowSuggestionsOptions options;
-    options.autofill_on_empty_values = true;
-    options.requires_caret_at_end = true;
-    options.autoselect_first_suggestion =
-        ShouldAutoselectFirstSuggestionOnArrowDown();
-    ShowSuggestions(element, options);
+    ShowSuggestions(element,
+                    {.autofill_on_empty_values = true,
+                     .requires_caret_at_end = true,
+                     .autoselect_first_suggestion =
+                         ShouldAutoselectFirstSuggestionOnArrowDown()});
   }
 }
 
 void AutofillAgent::OpenTextDataListChooser(const WebInputElement& element) {
   DCHECK(IsOwnedByFrame(element, render_frame()));
-
-  ShowSuggestionsOptions options;
-  options.autofill_on_empty_values = true;
-  ShowSuggestions(element, options);
+  ShowSuggestions(element, {.autofill_on_empty_values = true});
 }
 
 // Notifies the AutofillDriver about changes in the <datalist> options in
@@ -538,14 +527,14 @@
 }
 
 // mojom::AutofillAgent:
-void AutofillAgent::FillOrPreviewForm(int32_t id,
+void AutofillAgent::FillOrPreviewForm(int32_t query_id,
                                       const FormData& form,
                                       mojom::RendererFormDataAction action) {
   // If |element_| is null or not focused, a Autofill was triggered from another
   // frame. In this case, set |element_| to some form field as if Autofill had
   // been triggered from that field. This is necessary because currently
   // AutofillAgent's relies on |elemet_| in many places.
-  if (id == kCrossFrameFill && !form.fields.empty() &&
+  if (query_id == kCrossFrameFill && !form.fields.empty() &&
       (element_.IsNull() || !element_.Focused())) {
     WebDocument document = render_frame()->GetWebFrame()->GetDocument();
     element_ = form_util::FindFormControlElementByUniqueRendererId(
@@ -555,8 +544,9 @@
   if (element_.IsNull())
     return;
 
-  if (id != autofill_query_id_ && id != kCrossFrameFill &&
-      (action == mojom::RendererFormDataAction::kPreview || id != kNoQueryId)) {
+  if (query_id != autofill_query_id_ && query_id != kCrossFrameFill &&
+      (action == mojom::RendererFormDataAction::kPreview ||
+       query_id != kNoQueryId)) {
     return;
   }
 
@@ -571,7 +561,7 @@
     was_last_action_fill_ = true;
 
     // If this is a re-fill, replace the triggering element if it's invalid.
-    if (id == kNoQueryId)
+    if (query_id == kNoQueryId)
       ReplaceElementIfNowInvalid(form);
 
     query_node_autofill_state_ = element_.GetAutofillState();
@@ -835,7 +825,8 @@
     return;
   }
 
-  QueryAutofillSuggestions(element, options.autoselect_first_suggestion);
+  QueryAutofillSuggestions(element, options.autoselect_first_suggestion,
+                           options.touch_to_fill_eligible);
 }
 
 void AutofillAgent::SetQueryPasswordSuggestion(bool query) {
@@ -902,7 +893,8 @@
 
 void AutofillAgent::QueryAutofillSuggestions(
     const WebFormControlElement& element,
-    bool autoselect_first_suggestion) {
+    bool autoselect_first_suggestion,
+    TouchToFillEligible touch_to_fill_eligible) {
   blink::WebLocalFrame* frame = element.GetDocument().GetFrame();
   if (!frame)
     return;
@@ -947,9 +939,9 @@
   }
 
   is_popup_possibly_visible_ = true;
-  GetAutofillDriver().AskForValuesToFill(autofill_query_id_, form, field,
-                                         field.bounds,
-                                         autoselect_first_suggestion);
+  GetAutofillDriver().AskForValuesToFill(
+      autofill_query_id_, form, field, field.bounds,
+      autoselect_first_suggestion, touch_to_fill_eligible);
 }
 
 void AutofillAgent::DoFillFieldWithValue(const std::u16string& value,
@@ -1137,16 +1129,15 @@
   password_autofill_agent_->TryToShowTouchToFill(element);
 #endif
 
-  ShowSuggestionsOptions options;
-  options.autofill_on_empty_values = true;
-  // Even if the user has not edited an input element, it may still contain a
-  // value: A default value filled by the website. In that case, we don't want
-  // to elide suggestions that don't have a common prefix with the default
-  // value.
-  options.show_full_suggestion_list =
-      element.IsAutofilled() || !element.UserHasEditedTheField();
-
-  ShowSuggestions(element, options);
+  ShowSuggestions(
+      element, {.autofill_on_empty_values = true,
+                // Even if the user has not edited an input element, it may
+                // still contain a value: A default value filled by the website.
+                // In that case, we don't want to elide suggestions that don't
+                // have a common prefix with the default value.
+                .show_full_suggestion_list =
+                    element.IsAutofilled() || !element.UserHasEditedTheField(),
+                .touch_to_fill_eligible = TouchToFillEligible(true)});
 
   SendPotentiallySubmittedFormToBrowser();
 }
@@ -1176,6 +1167,12 @@
   SendPotentiallySubmittedFormToBrowser();
 }
 
+void AutofillAgent::JavaScriptChangedAutofilledValue(
+    const blink::WebFormControlElement& element,
+    const blink::WebString& old_value) {
+  // TODO(crbug.com/1314360): Send event to browser.
+}
+
 void AutofillAgent::OnProvisionallySaveForm(
     const WebFormElement& form,
     const WebFormControlElement& element,
diff --git a/components/autofill/content/renderer/autofill_agent.h b/components/autofill/content/renderer/autofill_agent.h
index 5fb4867b..33ffacbf 100644
--- a/components/autofill/content/renderer/autofill_agent.h
+++ b/components/autofill/content/renderer/autofill_agent.h
@@ -92,7 +92,7 @@
 
   // mojom::AutofillAgent:
   void TriggerReparse() override;
-  void FillOrPreviewForm(int32_t id,
+  void FillOrPreviewForm(int32_t query_id,
                          const FormData& form,
                          mojom::RendererFormDataAction action) override;
   void FieldTypePredictionsAvailable(
@@ -162,25 +162,26 @@
 
   // Flags passed to ShowSuggestions.
   struct ShowSuggestionsOptions {
-    // All fields are default initialized to false.
-    ShowSuggestionsOptions();
-
     // Specifies that suggestions should be shown when |element| contains no
     // text.
-    bool autofill_on_empty_values;
+    bool autofill_on_empty_values{false};
 
     // Specifies that suggestions should be shown when the caret is not
     // after the last character in the element.
-    bool requires_caret_at_end;
+    bool requires_caret_at_end{false};
 
     // Specifies that all autofill suggestions should be shown and none should
     // be elided because of the current value of |element| (relevant for inline
     // autocomplete).
-    bool show_full_suggestion_list;
+    bool show_full_suggestion_list{false};
 
     // Specifies that the first suggestion must be auto-selected when the
     // dropdown is shown. Enabled when the user presses ARROW_DOWN on a field.
-    bool autoselect_first_suggestion;
+    bool autoselect_first_suggestion{false};
+
+    // Specifies that suggestions are triggered in a way it makes sense to
+    // prompt the Touch To Fill surface first (e.g. on click).
+    TouchToFillEligible touch_to_fill_eligible{false};
   };
 
   // content::RenderFrameObserver:
@@ -213,6 +214,9 @@
   void DataListOptionsChanged(const blink::WebInputElement& element) override;
   void UserGestureObserved() override;
   void AjaxSucceeded() override;
+  void JavaScriptChangedAutofilledValue(
+      const blink::WebFormControlElement& element,
+      const blink::WebString& old_value) override;
   void DidCompleteFocusChangeInFrame() override;
   void DidReceiveLeftMouseDownOrGestureTapInNode(
       const blink::WebNode& node) override;
@@ -245,7 +249,8 @@
   // Queries the browser for Autocomplete and Autofill suggestions for the given
   // |element|.
   void QueryAutofillSuggestions(const blink::WebFormControlElement& element,
-                                bool autoselect_first_suggestion);
+                                bool autoselect_first_suggestion,
+                                TouchToFillEligible touch_to_fill_eligible);
 
   // Sets the selected value of the the field identified by |field_id| to
   // |suggested_value|.
diff --git a/components/autofill/content/renderer/autofill_agent_browsertest.cc b/components/autofill/content/renderer/autofill_agent_browsertest.cc
index ed4149a..0ce0d307 100644
--- a/components/autofill/content/renderer/autofill_agent_browsertest.cc
+++ b/components/autofill/content/renderer/autofill_agent_browsertest.cc
@@ -86,11 +86,12 @@
               (override));
   MOCK_METHOD(void,
               AskForValuesToFill,
-              (int32_t id,
+              (int32_t query_id,
                const FormData& form,
                const FormFieldData& field,
                const gfx::RectF& bounding_box,
-               bool autoselect_first_suggestion),
+               bool autoselect_first_suggestion,
+               TouchToFillEligible touch_to_fill_eligible),
               (override));
   MOCK_METHOD(void, HidePopup, (), (override));
   MOCK_METHOD(void,
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index 3c934b2..96330f1 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -309,16 +309,18 @@
     observer.OnSelectControlDidChange();
 }
 
-void AutofillManager::OnAskForValuesToFill(int query_id,
-                                           const FormData& form,
-                                           const FormFieldData& field,
-                                           const gfx::RectF& bounding_box,
-                                           bool autoselect_first_suggestion) {
+void AutofillManager::OnAskForValuesToFill(
+    int query_id,
+    const FormData& form,
+    const FormFieldData& field,
+    const gfx::RectF& bounding_box,
+    bool autoselect_first_suggestion,
+    TouchToFillEligible touch_to_fill_eligible) {
   if (!IsValidFormData(form) || !IsValidFormFieldData(field))
     return;
 
   OnAskForValuesToFillImpl(query_id, form, field, bounding_box,
-                           autoselect_first_suggestion);
+                           autoselect_first_suggestion, touch_to_fill_eligible);
 }
 
 void AutofillManager::OnFocusOnFormField(const FormData& form,
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h
index 15b4146..64b4d0c0 100644
--- a/components/autofill/core/browser/autofill_manager.h
+++ b/components/autofill/core/browser/autofill_manager.h
@@ -135,11 +135,15 @@
   // Invoked when the |form| needs to be autofilled, the |bounding_box| is
   // a window relative value of |field|.
   // |bounding_box| are viewport coordinates.
+  // |touch_to_fill_eligible| indicates if the Touch To Fill surface could be
+  // used for showing suggestion. Note that it doesn't guarantee the given form
+  // input field is eligible for autofilling.
   void OnAskForValuesToFill(int query_id,
                             const FormData& form,
                             const FormFieldData& field,
                             const gfx::RectF& bounding_box,
-                            bool autoselect_first_suggestion);
+                            bool autoselect_first_suggestion,
+                            TouchToFillEligible touch_to_fill_eligible);
 
   // Invoked when |form|'s |field| has focus.
   // |bounding_box| are viewport coordinates.
@@ -313,11 +317,13 @@
                                         const FormFieldData& field,
                                         const gfx::RectF& bounding_box) = 0;
 
-  virtual void OnAskForValuesToFillImpl(int query_id,
-                                        const FormData& form,
-                                        const FormFieldData& field,
-                                        const gfx::RectF& bounding_box,
-                                        bool autoselect_first_suggestion) = 0;
+  virtual void OnAskForValuesToFillImpl(
+      int query_id,
+      const FormData& form,
+      const FormFieldData& field,
+      const gfx::RectF& bounding_box,
+      bool autoselect_first_suggestion,
+      TouchToFillEligible touch_to_fill_eligible) = 0;
 
   virtual void OnFocusOnFormFieldImpl(const FormData& form,
                                       const FormFieldData& field,
diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc
index 12aed8d..32c4f3988 100644
--- a/components/autofill/core/browser/autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -119,7 +119,8 @@
                const FormData& form,
                const FormFieldData& field,
                const gfx::RectF& bounding_box,
-               bool autoselect_first_suggestion),
+               bool autoselect_first_suggestion,
+               TouchToFillEligible touch_to_fill_eligible),
               (override));
   MOCK_METHOD(void,
               OnFocusOnFormFieldImpl,
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc
index ef0f6fa..3dd8b4b 100644
--- a/components/autofill/core/browser/browser_autofill_manager.cc
+++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -949,7 +949,8 @@
     const FormData& form,
     const FormFieldData& field,
     const gfx::RectF& transformed_box,
-    bool autoselect_first_suggestion) {
+    bool autoselect_first_suggestion,
+    TouchToFillEligible touch_to_fill_eligible) {
   if (base::FeatureList::IsEnabled(features::kAutofillDisableFilling)) {
     return;
   }
@@ -1052,7 +1053,7 @@
         field.form_control_type, weak_ptr_factory_.GetWeakPtr(), context);
     return;
   }
-
+  // TODO(crbug.com/1247698): Try to show TTF if |touch_to_fill_eligible|.
   // Send Autofill suggestions (could be an empty list).
   single_field_form_fill_router_->CancelPendingQueries(this);
   external_delegate_->OnSuggestionsReturned(query_id, suggestions,
diff --git a/components/autofill/core/browser/browser_autofill_manager.h b/components/autofill/core/browser/browser_autofill_manager.h
index 980d3bc..bffd1f37 100644
--- a/components/autofill/core/browser/browser_autofill_manager.h
+++ b/components/autofill/core/browser/browser_autofill_manager.h
@@ -362,11 +362,13 @@
   void OnTextFieldDidScrollImpl(const FormData& form,
                                 const FormFieldData& field,
                                 const gfx::RectF& bounding_box) override {}
-  void OnAskForValuesToFillImpl(int query_id,
-                                const FormData& form,
-                                const FormFieldData& field,
-                                const gfx::RectF& transformed_box,
-                                bool autoselect_first_suggestion) override;
+  void OnAskForValuesToFillImpl(
+      int query_id,
+      const FormData& form,
+      const FormFieldData& field,
+      const gfx::RectF& transformed_box,
+      bool autoselect_first_suggestion,
+      TouchToFillEligible touch_to_fill_eligible) override;
   void OnSelectControlDidChangeImpl(const FormData& form,
                                     const FormFieldData& field,
                                     const gfx::RectF& bounding_box) override;
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
index c36cc3dc..ba343e8 100644
--- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -481,7 +481,7 @@
                               const FormFieldData& field) {
     browser_autofill_manager_->OnAskForValuesToFill(
         query_id, form, field, gfx::RectF(),
-        /*autoselect_first_suggestion=*/false);
+        /*autoselect_first_suggestion=*/false, TouchToFillEligible(false));
   }
 
   void GetAutofillSuggestions(const FormData& form,
diff --git a/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc b/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc
index b25b657..5f616e93 100644
--- a/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc
+++ b/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc
@@ -4076,8 +4076,7 @@
   {
     // Simulate activating the autofill popup for the phone field.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     histogram_tester.ExpectUniqueSample("Autofill.AddressSuggestionsCount", 2,
                                         1);
   }
@@ -4087,8 +4086,7 @@
     // No new metric should be logged, since we're still on the same page.
     test::CreateTestFormField("Email", "email", "b", "email", &field);
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     histogram_tester.ExpectTotalCount("Autofill.AddressSuggestionsCount", 0);
   }
 
@@ -4099,8 +4097,7 @@
   {
     // Simulate activating the autofill popup for the email field after typing.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     histogram_tester.ExpectUniqueSample("Autofill.AddressSuggestionsCount", 1,
                                         1);
   }
@@ -4113,8 +4110,7 @@
     // Simulate activating the autofill popup for the email field after a fill.
     form.fields[0].is_autofilled = true;
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     histogram_tester.ExpectTotalCount("Autofill.AddressSuggestionsCount", 1);
   }
 }
@@ -4150,9 +4146,7 @@
   {
     // Simulate activating the autofill popup for the phone field.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
-
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     histogram_tester.ExpectUniqueSample("Autofill.AddressSuggestionsCount", 2,
                                         1);
   }
@@ -4193,8 +4187,7 @@
   // Simulate an Autofill query on a credit card field.
   {
     base::UserActionTester user_action_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     EXPECT_EQ(1, user_action_tester.GetActionCount(
                      "Autofill_PolledCreditCardSuggestions"));
   }
@@ -4291,8 +4284,7 @@
   // Simulate submitting the credit card form.
   {
     base::UserActionTester user_action_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                        SubmissionSource::FORM_SUBMISSION);
     EXPECT_EQ(1,
@@ -4419,8 +4411,7 @@
   // Simulate an Autofill query on a profile field.
   {
     base::UserActionTester user_action_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     EXPECT_EQ(1, user_action_tester.GetActionCount(
                      "Autofill_PolledProfileSuggestions"));
   }
@@ -4472,8 +4463,7 @@
   // Simulate submitting the profile form.
   {
     base::UserActionTester user_action_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                        SubmissionSource::FORM_SUBMISSION);
     EXPECT_EQ(1,
@@ -4563,32 +4553,24 @@
 
   // Simulate an Autofill query on a credit card field. A poll should be logged.
   base::UserActionTester user_action_tester;
-  autofill_manager().OnAskForValuesToFill(
-      0, form, form.fields[0], gfx::RectF(),
-      /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form, form.fields[0]);
   EXPECT_EQ(1, user_action_tester.GetActionCount(
                    "Autofill_PolledCreditCardSuggestions"));
 
   // Simulate a second query on the same field. There should still only be one
   // logged poll.
-  autofill_manager().OnAskForValuesToFill(
-      0, form, form.fields[0], gfx::RectF(),
-      /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form, form.fields[0]);
   EXPECT_EQ(1, user_action_tester.GetActionCount(
                    "Autofill_PolledCreditCardSuggestions"));
 
   // Simulate a query to another field. There should be a second poll logged.
-  autofill_manager().OnAskForValuesToFill(
-      0, form, form.fields[1], gfx::RectF(),
-      /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form, form.fields[1]);
   EXPECT_EQ(2, user_action_tester.GetActionCount(
                    "Autofill_PolledCreditCardSuggestions"));
 
   // Simulate a query back to the initial field. There should be a third poll
   // logged.
-  autofill_manager().OnAskForValuesToFill(
-      0, form, form.fields[0], gfx::RectF(),
-      /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form, form.fields[0]);
   EXPECT_EQ(3, user_action_tester.GetActionCount(
                    "Autofill_PolledCreditCardSuggestions"));
 }
@@ -4643,9 +4625,7 @@
     // Simulate an Autofill query on a credit card field (HTTP, non-secure
     // form).
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, form.fields[1], gfx::RectF(),
-        /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, form.fields[1]);
     histogram_tester.ExpectUniqueSample(
         "Autofill.QueriedCreditCardFormIsSecure", false, 1);
     // Reset the main frame origin to secure for other tests
@@ -4665,9 +4645,7 @@
 
     // Simulate an Autofill query on a credit card field (HTTPS form).
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, form.fields[1], gfx::RectF(),
-        /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, form.fields[1]);
     histogram_tester.ExpectUniqueSample(
         "Autofill.QueriedCreditCardFormIsSecure", true, 1);
   }
@@ -4705,32 +4683,24 @@
 
   // Simulate an Autofill query on a profile field. A poll should be logged.
   base::UserActionTester user_action_tester;
-  autofill_manager().OnAskForValuesToFill(
-      0, form, form.fields[0], gfx::RectF(),
-      /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form, form.fields[0]);
   EXPECT_EQ(1, user_action_tester.GetActionCount(
                    "Autofill_PolledProfileSuggestions"));
 
   // Simulate a second query on the same field. There should still only be poll
   // logged.
-  autofill_manager().OnAskForValuesToFill(
-      0, form, form.fields[0], gfx::RectF(),
-      /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form, form.fields[0]);
   EXPECT_EQ(1, user_action_tester.GetActionCount(
                    "Autofill_PolledProfileSuggestions"));
 
   // Simulate a query to another field. There should be a second poll logged.
-  autofill_manager().OnAskForValuesToFill(
-      0, form, form.fields[1], gfx::RectF(),
-      /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form, form.fields[1]);
   EXPECT_EQ(2, user_action_tester.GetActionCount(
                    "Autofill_PolledProfileSuggestions"));
 
   // Simulate a query back to the initial field. There should be a third poll
   // logged.
-  autofill_manager().OnAskForValuesToFill(
-      0, form, form.fields[0], gfx::RectF(),
-      /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form, form.fields[0]);
   EXPECT_EQ(3, user_action_tester.GetActionCount(
                    "Autofill_PolledProfileSuggestions"));
 }
@@ -4800,8 +4770,7 @@
   {
     // Simulate activating the autofill popup for the credit card field.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     histogram_tester.ExpectUniqueSample("Autofill.FormEvents.CreditCard",
                                         FORM_EVENT_INTERACTED_ONCE, 1);
     histogram_tester.ExpectUniqueSample(
@@ -4816,10 +4785,8 @@
   {
     // Simulate activating the autofill popup for the credit card field twice.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
-    autofill_manager().OnAskForValuesToFill(
-        1, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field, /*query_id=*/0);
+    autofill_manager().OnAskForValuesToFillTest(form, field, /*query_id=*/1);
     histogram_tester.ExpectUniqueSample("Autofill.FormEvents.CreditCard",
                                         FORM_EVENT_INTERACTED_ONCE, 1);
     histogram_tester.ExpectUniqueSample(
@@ -5009,8 +4976,7 @@
   {
     // Simulate new popup being shown.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
     histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
                                        FORM_EVENT_SUGGESTIONS_SHOWN, 1);
@@ -5041,8 +5007,7 @@
   {
     // Simulating two popups in the same page load.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
     autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
     histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
@@ -5074,8 +5039,7 @@
   {
     // Simulating same popup being refreshed.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().DidShowSuggestions(false /* is_new_popup */, form,
                                           field);
     histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
@@ -5114,8 +5078,7 @@
     // Simulating two popups in the same page load. Suggestions shown should be
     // logged, but suggestions shown with virtual card should not.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
     autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
     histogram_tester.ExpectBucketCount("Autofill.FormEvents.CreditCard",
@@ -5822,8 +5785,7 @@
   // Simulating submission with suggestion shown, but not selected.
   base::HistogramTester histogram_tester;
   autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
-  autofill_manager().OnAskForValuesToFill(
-      0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form, field);
   autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                      SubmissionSource::FORM_SUBMISSION);
   histogram_tester.ExpectBucketCount(
@@ -5866,8 +5828,7 @@
   // Simulating submission with suggestion shown, but not selected.
   base::HistogramTester histogram_tester;
   autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
-  autofill_manager().OnAskForValuesToFill(
-      0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form, field);
   autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                      SubmissionSource::FORM_SUBMISSION);
   histogram_tester.ExpectBucketCount(
@@ -5914,8 +5875,7 @@
   // Simulating submission with suggestion shown, but not selected.
   base::HistogramTester histogram_tester;
   autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
-  autofill_manager().OnAskForValuesToFill(
-      0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form, field);
   autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                      SubmissionSource::FORM_SUBMISSION);
   histogram_tester.ExpectBucketCount(
@@ -5963,8 +5923,7 @@
   // Simulating submission with suggestion shown, but not selected.
   base::HistogramTester histogram_tester;
   autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
-  autofill_manager().OnAskForValuesToFill(
-      0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form, field);
   autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                      SubmissionSource::FORM_SUBMISSION);
   histogram_tester.ExpectBucketCount(
@@ -6012,8 +5971,7 @@
   // Simulating submission with suggestion shown, but not selected.
   base::HistogramTester histogram_tester;
   autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
-  autofill_manager().OnAskForValuesToFill(
-      0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form, field);
   autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                      SubmissionSource::FORM_SUBMISSION);
   histogram_tester.ExpectBucketCount(
@@ -6061,8 +6019,7 @@
   // Simulating submission with suggestion shown and selected.
   base::HistogramTester histogram_tester;
   autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
-  autofill_manager().OnAskForValuesToFill(
-      0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form, field);
   std::string guid("10000000-0000-0000-0000-000000000001");
   autofill_manager().FillOrPreviewForm(
       mojom::RendererFormDataAction::kFill, 0, form, form.fields.back(),
@@ -6122,8 +6079,7 @@
   // Simulating submission with no filled data.
   base::HistogramTester histogram_tester;
   autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
-  autofill_manager().OnAskForValuesToFill(
-      0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form, field);
   autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                      SubmissionSource::FORM_SUBMISSION);
   histogram_tester.ExpectBucketCount(
@@ -6166,8 +6122,7 @@
   {
     // Simulating submission with no filled data.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                        SubmissionSource::FORM_SUBMISSION);
 
@@ -6200,8 +6155,7 @@
     // Simulating submission with suggestion shown.
     base::HistogramTester histogram_tester;
     autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                        SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
@@ -6246,8 +6200,7 @@
     // triggered.
     base::HistogramTester histogram_tester;
     autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                        SubmissionSource::FORM_SUBMISSION);
     // Trigger UploadFormDataAsyncCallback.
@@ -6291,8 +6244,7 @@
   {
     // Simulating submission with filled local data.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     std::string guid("10000000-0000-0000-0000-000000000001");  // local card
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, 0, form, form.fields.front(),
@@ -6339,8 +6291,7 @@
     // Simulating submission with filled virtual card data by selecting the
     // option based on the enrolled masked card.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     std::string guid("10000000-0000-0000-0000-000000000002");  // masked card
     autofill_manager().FillOrPreviewVirtualCardInformation(
         mojom::RendererFormDataAction::kFill, guid, kDefaultPageID, form,
@@ -6387,8 +6338,7 @@
   {
     // Simulating submission with filled server data.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     std::string guid(
         "10000000-0000-0000-0000-000000000003");  // full server card
     autofill_manager().FillOrPreviewForm(
@@ -6491,8 +6441,7 @@
   {
     // Simulating multiple submissions.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                        SubmissionSource::FORM_SUBMISSION);
 
@@ -6722,8 +6671,7 @@
   {
     // Simulating submission with no filled data.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                        SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
@@ -6748,8 +6696,7 @@
     // Simulating submission with suggestion shown.
     base::HistogramTester histogram_tester;
     autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                        SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
@@ -6773,8 +6720,7 @@
   {
     // Simulating submission with filled local data.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     std::string guid("10000000-0000-0000-0000-000000000001");  // local card
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, 0, form, form.fields.front(),
@@ -6804,8 +6750,7 @@
     // Simulating submission with filled virtual card data by selecting the
     // option based on the enrolled masked card.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     std::string guid("10000000-0000-0000-0000-000000000002");  // masked card
     autofill_manager().FillOrPreviewVirtualCardInformation(
         mojom::RendererFormDataAction::kFill, guid, kDefaultPageID, form,
@@ -6835,8 +6780,7 @@
   {
     // Simulating submission with filled server data.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     // Full server card.
     std::string guid("10000000-0000-0000-0000-000000000003");
     autofill_manager().FillOrPreviewForm(
@@ -6901,8 +6845,7 @@
   {
     // Simulating multiple submissions.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                        SubmissionSource::FORM_SUBMISSION);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
@@ -7077,8 +7020,7 @@
     // Simulating activating the autofill popup for the credit card field, new
     // popup being shown and filling a local card suggestion.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
     std::string guid("10000000-0000-0000-0000-000000000001");  // local card
     autofill_manager().FillOrPreviewForm(
@@ -7127,8 +7069,7 @@
     // submitting the form. Verify that all related form events are correctly
     // logged to offer sub-histogram.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
     // Select the masked server card with the linked offer.
     autofill_manager().FillOrPreviewForm(
@@ -7175,8 +7116,7 @@
     // submitting the form. Verify that all related form events are correctly
     // logged to offer sub-histogram.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
     // Select another card, and still log to offer
     // sub-histogram because user has another masked server card with offer.
@@ -7241,8 +7181,7 @@
     // Simulating activating the autofill popup for the credit card field,
     // new popup being shown and filling a local card suggestion.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
     // Select the card with linked offer, though metrics should not record it
     // since the offer is expired.
@@ -7318,8 +7257,7 @@
     // sub-histogram. Making suggestions reappear tests confirmation of a fix
     // for crbug/1198751.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
     // Select the masked server card with the linked offer.
     autofill_manager().FillOrPreviewForm(
@@ -7331,8 +7269,7 @@
 
     // Simulate user showing suggestions but then submitting form with
     // previously filled card info.
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                        SubmissionSource::FORM_SUBMISSION);
@@ -7381,8 +7318,7 @@
     // failing the CVC check and submitting the form anyways. Verify that all
     // related form events are correctly logged to offer sub-histogram.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
     // Select the masked server card with the linked offer, but fail the CVC
     // check.
@@ -7443,8 +7379,7 @@
     base::HistogramTester histogram_tester;
 
     // Show suggestions and select the card with offer.
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, 0, form, form.fields.back(),
@@ -7454,8 +7389,7 @@
                     "6011000990139424");
 
     // Show suggestions again, and select a local card instead.
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
     guid = "10000000-0000-0000-0000-000000000001";
     autofill_manager().FillOrPreviewForm(
@@ -7612,8 +7546,7 @@
   {
     // Simulate activating the autofill popup for the street field.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     histogram_tester.ExpectUniqueSample("Autofill.FormEvents.Address",
                                         FORM_EVENT_INTERACTED_ONCE, 1);
 
@@ -7638,10 +7571,8 @@
   {
     // Simulate activating the autofill popup for the street field twice.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
-    autofill_manager().OnAskForValuesToFill(
-        1, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field, /*query_id=*/0);
+    autofill_manager().OnAskForValuesToFillTest(form, field, /*query_id=*/1);
     histogram_tester.ExpectUniqueSample("Autofill.FormEvents.Address",
                                         FORM_EVENT_INTERACTED_ONCE, 1);
     // Check if FormEvent UKM is logged properly
@@ -8025,8 +7956,7 @@
   {
     // Simulating submission with no filled data.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                        SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
@@ -8052,8 +7982,7 @@
     // autofill manager is reset before UploadFormDataAsyncCallback is
     // triggered.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                        SubmissionSource::FORM_SUBMISSION);
     // Trigger UploadFormDataAsyncCallback.
@@ -8080,8 +8009,7 @@
     // Simulating submission with suggestion shown.
     base::HistogramTester histogram_tester;
     autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                        SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
@@ -8100,8 +8028,7 @@
   {
     // Simulating submission with filled local data.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     std::string guid(kTestGuid);  // local profile
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, 0, form, form.fields.front(),
@@ -8124,8 +8051,7 @@
   {
     // Simulating multiple submissions.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                        SubmissionSource::FORM_SUBMISSION);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
@@ -8211,8 +8137,7 @@
   {
     // Simulating submission with no filled data.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                        SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
@@ -8232,8 +8157,7 @@
     // Simulating submission with suggestion shown.
     base::HistogramTester histogram_tester;
     autofill_manager().DidShowSuggestions(true /* is_new_popup */, form, field);
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                        SubmissionSource::FORM_SUBMISSION);
     histogram_tester.ExpectBucketCount(
@@ -8252,8 +8176,7 @@
   {
     // Simulating submission with filled local data.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     std::string guid(kTestGuid);  // local profile
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, 0, form, form.fields.front(),
@@ -8277,8 +8200,7 @@
   {
     // Simulating multiple submissions.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
                                        SubmissionSource::FORM_SUBMISSION);
     autofill_manager().OnFormSubmitted(form, /*known_success=*/false,
@@ -8357,8 +8279,7 @@
   autofill_manager().AddSeenForm(form, field_types, field_types);
 
   base::HistogramTester histogram_tester;
-  autofill_manager().OnAskForValuesToFill(
-      0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form, field);
   histogram_tester.ExpectBucketCount("Autofill.FormEvents.Address.PhoneOnly",
                                      FORM_EVENT_INTERACTED_ONCE, 1);
 }
@@ -8397,8 +8318,7 @@
   {
     // Simulate activating the autofill popup for the credit card field.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     histogram_tester.ExpectUniqueSample(
         "Autofill.FormEvents.CreditCard.WithNoData", FORM_EVENT_INTERACTED_ONCE,
         1);
@@ -8416,8 +8336,7 @@
   {
     // Simulate activating the autofill popup for the credit card field.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     histogram_tester.ExpectUniqueSample(
         "Autofill.FormEvents.CreditCard.WithOnlyLocalData",
         FORM_EVENT_INTERACTED_ONCE, 1);
@@ -8435,8 +8354,7 @@
   {
     // Simulate activating the autofill popup for the credit card field.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     histogram_tester.ExpectUniqueSample(
         "Autofill.FormEvents.CreditCard.WithOnlyServerData",
         FORM_EVENT_INTERACTED_ONCE, 1);
@@ -8454,8 +8372,7 @@
   {
     // Simulate activating the autofill popup for the credit card field.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     histogram_tester.ExpectUniqueSample(
         "Autofill.FormEvents.CreditCard.WithOnlyServerData",
         FORM_EVENT_INTERACTED_ONCE, 1);
@@ -8473,8 +8390,7 @@
   {
     // Simulate activating the autofill popup for the credit card field.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     histogram_tester.ExpectUniqueSample(
         "Autofill.FormEvents.CreditCard.WithBothServerAndLocalData",
         FORM_EVENT_INTERACTED_ONCE, 1);
@@ -8512,8 +8428,7 @@
   {
     // Simulate activating the autofill popup for the street field.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     histogram_tester.ExpectUniqueSample(
         "Autofill.FormEvents.Address.WithNoData", FORM_EVENT_INTERACTED_ONCE,
         1);
@@ -8527,8 +8442,7 @@
   {
     // Simulate activating the autofill popup for the street field.
     base::HistogramTester histogram_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     histogram_tester.ExpectUniqueSample(
         "Autofill.FormEvents.Address.WithOnlyLocalData",
         FORM_EVENT_INTERACTED_ONCE, 1);
@@ -10331,8 +10245,7 @@
   // Simulate an Autofill query on a credit card field.
   {
     base::UserActionTester user_action_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     EXPECT_EQ(1, user_action_tester.GetActionCount(
                      "Autofill_PolledCreditCardSuggestions"));
   }
@@ -10393,8 +10306,7 @@
   // Simulate an Autofill query on a credit card field.
   {
     base::UserActionTester user_action_tester;
-    autofill_manager().OnAskForValuesToFill(
-        0, form, field, gfx::RectF(), /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, field);
     EXPECT_EQ(1, user_action_tester.GetActionCount(
                      "Autofill_PolledCreditCardSuggestions"));
   }
@@ -11607,9 +11519,7 @@
 
   // Simulate interacting with the form.
   if (user_interacted_with_form) {
-    autofill_manager().OnAskForValuesToFill(
-        /*query_id=*/0, form, form.fields[0], gfx::RectF(),
-        /*autoselect_first_suggestion=*/false);
+    autofill_manager().OnAskForValuesToFillTest(form, form.fields[0]);
   }
 
   // Simulate seeing a suggestion.
@@ -11750,9 +11660,7 @@
                                  /*removed_forms=*/{});
 
   // Simulate interacting with the form.
-  autofill_manager().OnAskForValuesToFill(
-      /*query_id=*/0, form, form.fields[0], gfx::RectF(),
-      /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form, form.fields[0]);
 
   // Don't simulate a suggestion but simulate the user typing.
   autofill_manager().OnTextFieldDidChange(form, form.fields[0], gfx::RectF(),
@@ -11835,9 +11743,7 @@
   // Simulate page load.
   autofill_manager().OnFormsSeen(/*updated_forms=*/{form_},
                                  /*removed_forms=*/{});
-  autofill_manager().OnAskForValuesToFill(
-      0, form_, form_.fields[0], gfx::RectF(),
-      /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form_, form_.fields[0]);
 
   // Simulate form submission.
   autofill_manager().OnFormSubmitted(form_, false,
@@ -11866,9 +11772,7 @@
   personal_data().ClearProfiles();
   autofill_manager().OnFormsSeen(/*updated_forms=*/{form_},
                                  /*removed_forms=*/{});
-  autofill_manager().OnAskForValuesToFill(
-      0, form_, form_.fields[0], gfx::RectF(),
-      /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form_, form_.fields[0]);
 
   // Simulate user typing the address.
   autofill_manager().OnTextFieldDidChange(form_, form_.fields[0], gfx::RectF(),
@@ -11901,9 +11805,7 @@
   // Simulate that suggestion is shown but user does not accept it.
   autofill_manager().OnFormsSeen(/*updated_forms=*/{form_},
                                  /*removed_forms=*/{});
-  autofill_manager().OnAskForValuesToFill(
-      0, form_, form_.fields[0], gfx::RectF(),
-      /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form_, form_.fields[0]);
   autofill_manager().DidShowSuggestions(
       /*has_autofill_suggestions=*/true, form_, form_.fields[0]);
 
@@ -11938,9 +11840,7 @@
   // Simulate that suggestion is shown and user accepts it.
   autofill_manager().OnFormsSeen(/*updated_forms=*/{form_},
                                  /*removed_forms=*/{});
-  autofill_manager().OnAskForValuesToFill(
-      0, form_, form_.fields[0], gfx::RectF(),
-      /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form_, form_.fields[0]);
   autofill_manager().DidShowSuggestions(
       /*has_autofill_suggestions=*/true, form_, form_.fields[0]);
   autofill_manager().FillOrPreviewForm(
@@ -11978,9 +11878,7 @@
   // Simulate that suggestion is shown and user accepts it.
   autofill_manager().OnFormsSeen(/*updated_forms=*/{form_},
                                  /*removed_forms=*/{});
-  autofill_manager().OnAskForValuesToFill(
-      0, form_, form_.fields[0], gfx::RectF(),
-      /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form_, form_.fields[0]);
   autofill_manager().DidShowSuggestions(
       /*has_autofill_suggestions=*/true, form_, form_.fields[0]);
   autofill_manager().FillOrPreviewForm(
@@ -12168,9 +12066,7 @@
   // Simulate having seen this form on page load.
   autofill_manager().AddSeenForm(form, heuristic_types, server_types);
 
-  autofill_manager().OnAskForValuesToFill(
-      0, form, form.fields[0], gfx::RectF(),
-      /*autoselect_first_suggestion=*/false);
+  autofill_manager().OnAskForValuesToFillTest(form, form.fields[0]);
   autofill_manager().DidShowSuggestions(
       /*has_autofill_suggestions=*/true, form, form.fields[0]);
 
diff --git a/components/autofill/core/browser/test_browser_autofill_manager.cc b/components/autofill/core/browser/test_browser_autofill_manager.cc
index ce32b148..73d1b9f 100644
--- a/components/autofill/core/browser/test_browser_autofill_manager.cc
+++ b/components/autofill/core/browser/test_browser_autofill_manager.cc
@@ -150,6 +150,18 @@
   return submitted_form_signature_;
 }
 
+void TestBrowserAutofillManager::OnAskForValuesToFillTest(
+    const FormData& form,
+    const FormFieldData& field,
+    int query_id,
+    const gfx::RectF& bounding_box,
+    bool autoselect_first_suggestion,
+    TouchToFillEligible touch_to_fill_eligible) {
+  BrowserAutofillManager::OnAskForValuesToFill(
+      query_id, form, field, bounding_box, autoselect_first_suggestion,
+      touch_to_fill_eligible);
+}
+
 void TestBrowserAutofillManager::SetAutofillProfileEnabled(
     bool autofill_profile_enabled) {
   autofill_profile_enabled_ = autofill_profile_enabled;
diff --git a/components/autofill/core/browser/test_browser_autofill_manager.h b/components/autofill/core/browser/test_browser_autofill_manager.h
index 4612f7a..e60192e6 100644
--- a/components/autofill/core/browser/test_browser_autofill_manager.h
+++ b/components/autofill/core/browser/test_browser_autofill_manager.h
@@ -70,6 +70,15 @@
 
   const std::string GetSubmittedFormSignature();
 
+  // Helper to skip irrelevant params.
+  void OnAskForValuesToFillTest(
+      const FormData& form,
+      const FormFieldData& field,
+      int query_id = 0,
+      const gfx::RectF& bounding_box = {},
+      bool autoselect_first_suggestion = false,
+      TouchToFillEligible touch_to_fill_eligible = TouchToFillEligible(false));
+
   void SetAutofillProfileEnabled(bool profile_enabled);
 
   void SetAutofillCreditCardEnabled(bool credit_card_enabled);
diff --git a/components/autofill/core/common/BUILD.gn b/components/autofill/core/common/BUILD.gn
index 1df8b62..0660e3a 100644
--- a/components/autofill/core/common/BUILD.gn
+++ b/components/autofill/core/common/BUILD.gn
@@ -4,6 +4,7 @@
 
 static_library("common") {
   sources = [
+    "aliases.h",
     "autofill_clock.cc",
     "autofill_clock.h",
     "autofill_constants.cc",
diff --git a/components/autofill/core/common/aliases.h b/components/autofill/core/common/aliases.h
new file mode 100644
index 0000000..dfd1a0c6
--- /dev/null
+++ b/components/autofill/core/common/aliases.h
@@ -0,0 +1,20 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_COMMON_ALIASES_H_
+#define COMPONENTS_AUTOFILL_CORE_COMMON_ALIASES_H_
+
+#include "base/types/strong_alias.h"
+
+namespace autofill {
+
+// TODO(crbug.com/1326518): Use strong aliases for other primitives in mojom
+// files.
+
+using TouchToFillEligible =
+    base::StrongAlias<struct TouchToFillEligibleTag, bool>;
+
+}  // namespace autofill
+
+#endif  // COMPONENTS_AUTOFILL_CORE_COMMON_ALIASES_H_
diff --git a/components/autofill/core/common/mojom/BUILD.gn b/components/autofill/core/common/mojom/BUILD.gn
index 7a7eaa7b..f076b75e 100644
--- a/components/autofill/core/common/mojom/BUILD.gn
+++ b/components/autofill/core/common/mojom/BUILD.gn
@@ -72,6 +72,11 @@
           mojom = "autofill.mojom.PasswordGenerationUIData"
           cpp = "::autofill::password_generation::PasswordGenerationUIData"
         },
+        {
+          mojom = "autofill.mojom.TouchToFillEligible"
+          cpp = "::autofill::TouchToFillEligible"
+          copyable_pass_by_value = true
+        },
       ]
       traits_headers = [ "autofill_types_mojom_traits.h" ]
       traits_sources = [ "autofill_types_mojom_traits.cc" ]
diff --git a/components/autofill/core/common/mojom/autofill_types.mojom b/components/autofill/core/common/mojom/autofill_types.mojom
index d135727..5cb2482 100644
--- a/components/autofill/core/common/mojom/autofill_types.mojom
+++ b/components/autofill/core/common/mojom/autofill_types.mojom
@@ -309,3 +309,8 @@
   kFill,     // The renderer should fill the form data.
   kPreview,  // The renderer should preview the form data.
 };
+
+// autofill::TouchToFillEligible
+struct TouchToFillEligible {
+  bool eligible;
+};
diff --git a/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc b/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc
index 8c64af0..808cf396 100644
--- a/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc
+++ b/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc
@@ -311,4 +311,12 @@
          data.ReadConfirmPasswordRendererId(&out->confirm_password_renderer_id);
 }
 
+bool StructTraits<autofill::mojom::TouchToFillEligibleDataView,
+                  autofill::TouchToFillEligible>::
+    Read(autofill::mojom::TouchToFillEligibleDataView data,
+         autofill::TouchToFillEligible* out) {
+  *out = autofill::TouchToFillEligible(data.eligible());
+  return true;
+}
+
 }  // namespace mojo
diff --git a/components/autofill/core/common/mojom/autofill_types_mojom_traits.h b/components/autofill/core/common/mojom/autofill_types_mojom_traits.h
index ec8fa9db..c551782 100644
--- a/components/autofill/core/common/mojom/autofill_types_mojom_traits.h
+++ b/components/autofill/core/common/mojom/autofill_types_mojom_traits.h
@@ -11,6 +11,7 @@
 #include <vector>
 
 #include "base/i18n/rtl.h"
+#include "components/autofill/core/common/aliases.h"
 #include "components/autofill/core/common/form_data.h"
 #include "components/autofill/core/common/form_data_predictions.h"
 #include "components/autofill/core/common/form_field_data.h"
@@ -539,6 +540,15 @@
                    autofill::ParsingResult* out);
 };
 
+template <>
+struct StructTraits<autofill::mojom::TouchToFillEligibleDataView,
+                    autofill::TouchToFillEligible> {
+  static bool eligible(autofill::TouchToFillEligible r) { return r.value(); }
+
+  static bool Read(autofill::mojom::TouchToFillEligibleDataView data,
+                   autofill::TouchToFillEligible* out);
+};
+
 }  // namespace mojo
 
 #endif  // COMPONENTS_AUTOFILL_CORE_COMMON_MOJOM_AUTOFILL_TYPES_MOJOM_TRAITS_H_
diff --git a/components/autofill/ios/browser/autofill_agent.mm b/components/autofill/ios/browser/autofill_agent.mm
index 867fe9f..c195f976 100644
--- a/components/autofill/ios/browser/autofill_agent.mm
+++ b/components/autofill/ios/browser/autofill_agent.mm
@@ -333,7 +333,8 @@
   // -showAutofillPopup:popupDelegate:.
   autofillManager->OnAskForValuesToFill(++_lastQueryID, form, field,
                                         gfx::RectF(),
-                                        /*autoselect_first_suggestion=*/false);
+                                        /*autoselect_first_suggestion=*/false,
+                                        autofill::TouchToFillEligible(false));
 }
 
 - (void)checkIfSuggestionsAvailableForForm:
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn
index 2fb476e..96a5a63f 100644
--- a/components/cronet/android/BUILD.gn
+++ b/components/cronet/android/BUILD.gn
@@ -274,6 +274,7 @@
     "java/src/org/chromium/net/impl/CronetEngineBase.java",
     "java/src/org/chromium/net/impl/CronetEngineBuilderImpl.java",
     "java/src/org/chromium/net/impl/CronetExceptionImpl.java",
+    "java/src/org/chromium/net/impl/CronetLogger.java",
     "java/src/org/chromium/net/impl/NetworkExceptionImpl.java",
     "java/src/org/chromium/net/impl/Preconditions.java",
     "java/src/org/chromium/net/impl/QuicExceptionImpl.java",
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/CronetLogger.java b/components/cronet/android/java/src/org/chromium/net/impl/CronetLogger.java
new file mode 100644
index 0000000..bca44c9f
--- /dev/null
+++ b/components/cronet/android/java/src/org/chromium/net/impl/CronetLogger.java
@@ -0,0 +1,188 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.net.impl;
+
+import org.chromium.net.ExperimentalCronetEngine;
+
+/**
+ * Base class for implementing a CronetLogger.
+ */
+public abstract class CronetLogger {
+    public static enum CronetSource {
+        // Safe default, don't use explicitly.
+        CRONET_SOURCE_UNSPECIFIED,
+        // The library is bundled with the application.
+        CRONET_SOURCE_STATICALLY_LINKED,
+        // The library is loaded from GooglePlayServices
+        CRONET_SOURCE_PLAY_SERVICES,
+        // The application is using the fallback implementation
+        CRONET_SOURCE_FALLBACK,
+    }
+
+    public abstract void logCronetEngineCreation(int cronetEngineId,
+            ExperimentalCronetEngine.Builder builder, CronetVersion version, CronetSource source);
+
+    public abstract void logCronetTrafficInfo(int cronetEngineId, CronetTrafficInfo trafficInfo);
+
+    /**
+     * This aggregates the information about request and response traffic for a
+     * particular CronetEngine
+     */
+    public static class CronetTrafficInfo {
+        private final int mRequestHeaderSizeInBytes;
+        private final int mRequestBodySizeInBytes;
+        private final int mResponseHeaderSizeInBytes;
+        private final int mResponseBodySizeInBytes;
+        private final int mResponseStatusCode;
+        private final int mHeadersLatencyInMillis;
+        private final int mTotalLatencyInMillis;
+        private final String mNegotiatedProtocol;
+        private final boolean mWasConnectionMigrationAttempted;
+        private final boolean mDidConnectionMigrationSucceed;
+
+        public CronetTrafficInfo(int requestHeaderSizeInBytes, int requestBodySizeInBytes,
+                int responseHeaderSizeInBytes, int responseBodySizeInBytes, int responseStatusCode,
+                int headersLatencyInMillis, int totalLatencyInMillis, String negotiatedProtocol,
+                boolean wasConnectionMigrationAttempted, boolean didConnectionMigrationSucceed) {
+            mRequestHeaderSizeInBytes = requestHeaderSizeInBytes;
+            mRequestBodySizeInBytes = requestBodySizeInBytes;
+            mResponseHeaderSizeInBytes = responseHeaderSizeInBytes;
+            mResponseBodySizeInBytes = responseBodySizeInBytes;
+            mResponseStatusCode = responseStatusCode;
+            mHeadersLatencyInMillis = headersLatencyInMillis;
+            mTotalLatencyInMillis = totalLatencyInMillis;
+            mNegotiatedProtocol = negotiatedProtocol;
+            mWasConnectionMigrationAttempted = wasConnectionMigrationAttempted;
+            mDidConnectionMigrationSucceed = didConnectionMigrationSucceed;
+        }
+
+        /**
+         * @return The total size of headers sent in bytes
+         */
+        public int getRequestHeaderSizeInBytes() {
+            return mRequestHeaderSizeInBytes;
+        }
+
+        /**
+         * @return The total size of request body sent, if any, in bytes
+         */
+        public int getRequestBodySizeInBytes() {
+            return mRequestBodySizeInBytes;
+        }
+
+        /**
+         * @return The total size of headers received in bytes
+         */
+        public int getResponseHeaderSizeInBytes() {
+            return mResponseHeaderSizeInBytes;
+        }
+
+        /**
+         * @return The total size of response body, if any, received in bytes
+         */
+        public int getResponseBodySizeInBytes() {
+            return mResponseBodySizeInBytes;
+        }
+
+        /**
+         * @return The response status code of the request
+         */
+        public int getResponseStatusCode() {
+            return mResponseStatusCode;
+        }
+
+        /**
+         * The time it took from starting the request to receiving the full set of
+         * response headers.
+         *
+         * @return The time to get response headers in milliseconds
+         */
+        public int getHeadersLatencyInMillis() {
+            return mHeadersLatencyInMillis;
+        }
+
+        /**
+         * The time it took from starting the request to receiving the entire
+         * response.
+         *
+         * @return The time to get total response in milliseconds
+         */
+        public int getTotalLatencyInMillis() {
+            return mTotalLatencyInMillis;
+        }
+
+        /**
+         * @return The negotiated protocol used for the traffic
+         */
+        public String getNegotiatedProtocol() {
+            return mNegotiatedProtocol;
+        }
+
+        /**
+         * @return True if the connection migration was attempted, else False
+         */
+        public boolean wasConnectionMigrationAttempted() {
+            return mWasConnectionMigrationAttempted;
+        }
+
+        /**
+         * @return True if the connection migration was attempted and succeeded, else False
+         */
+        public boolean didConnectionMigrationSucceed() {
+            return mDidConnectionMigrationSucceed;
+        }
+    }
+
+    /**
+     * Holds information about the cronet version used for a cronetEngine.
+     */
+    public static class CronetVersion {
+        private final int mMajorVersion;
+        private final int mMinorVersion;
+        private final int mBuildVersion;
+        private final int mPatchVersion;
+
+        /**
+         * Pass the cronet version string here and
+         * it would be split. The string comes in the format
+         * MAJOR.MINOR.BUILD.PATCH
+         */
+        public CronetVersion(String version) {
+            String[] splitVersion = version.split("\\.");
+            mMajorVersion = Integer.parseInt(splitVersion[0]);
+            mMinorVersion = Integer.parseInt(splitVersion[1]);
+            mBuildVersion = Integer.parseInt(splitVersion[2]);
+            mPatchVersion = Integer.parseInt(splitVersion[3]);
+        }
+
+        /**
+         * @return the MAJOR version of cronet used for the traffic
+         */
+        public int getMajorVersion() {
+            return mMajorVersion;
+        }
+
+        /**
+         * @return the MINOR version of cronet used for the traffic
+         */
+        public int getMinorVersion() {
+            return mMinorVersion;
+        }
+
+        /**
+         * @return the BUILD version of cronet used for the traffic
+         */
+        public int getBuildVersion() {
+            return mBuildVersion;
+        }
+
+        /**
+         * @return the PATCH version of cronet used for the traffic
+         */
+        public int getPatchVersion() {
+            return mPatchVersion;
+        }
+    }
+}
\ No newline at end of file
diff --git a/components/page_load_metrics/browser/page_load_metrics_forward_observer.cc b/components/page_load_metrics/browser/page_load_metrics_forward_observer.cc
index af20d10..f43eabc 100644
--- a/components/page_load_metrics/browser/page_load_metrics_forward_observer.cc
+++ b/components/page_load_metrics/browser/page_load_metrics_forward_observer.cc
@@ -217,13 +217,11 @@
 void PageLoadMetricsForwardObserver::OnFirstInputInPage(
     const mojom::PageLoadTiming& timing) {}
 
+// OnLoadingBehaviorObserved is called through PageLoadTracker::UpdateMetrics.
+// So, the event is always forwarded at the PageLoadTracker layer.
 void PageLoadMetricsForwardObserver::OnLoadingBehaviorObserved(
     content::RenderFrameHost* rfh,
-    int behavior_flags) {
-  if (!parent_observer_)
-    return;
-  parent_observer_->OnLoadingBehaviorObserved(rfh, behavior_flags);
-}
+    int behavior_flags) {}
 
 void PageLoadMetricsForwardObserver::OnFeaturesUsageObserved(
     content::RenderFrameHost* rfh,
diff --git a/components/password_manager/core/browser/form_parsing/form_parser.cc b/components/password_manager/core/browser/form_parsing/form_parser.cc
index bdddb29..e3d58f3 100644
--- a/components/password_manager/core/browser/form_parsing/form_parser.cc
+++ b/components/password_manager/core/browser/form_parsing/form_parser.cc
@@ -64,16 +64,18 @@
     return AutocompleteFlag::kNone;
 
   const base::StringPiece& field_type = tokens.back();
-  if (base::LowerCaseEqualsASCII(field_type, kAutocompleteUsername))
+  if (base::EqualsCaseInsensitiveASCII(field_type, kAutocompleteUsername))
     return AutocompleteFlag::kUsername;
-  if (base::LowerCaseEqualsASCII(field_type, kAutocompleteCurrentPassword))
+  if (base::EqualsCaseInsensitiveASCII(field_type,
+                                       kAutocompleteCurrentPassword))
     return AutocompleteFlag::kCurrentPassword;
-  if (base::LowerCaseEqualsASCII(field_type, kAutocompleteNewPassword))
+  if (base::EqualsCaseInsensitiveASCII(field_type, kAutocompleteNewPassword))
     return AutocompleteFlag::kNewPassword;
-  if (base::LowerCaseEqualsASCII(field_type, kAutocompleteWebAuthn))
+  if (base::EqualsCaseInsensitiveASCII(field_type, kAutocompleteWebAuthn))
     return AutocompleteFlag::kWebAuthn;
 
-  if (base::LowerCaseEqualsASCII(field_type, kAutocompleteOneTimePassword) ||
+  if (base::EqualsCaseInsensitiveASCII(field_type,
+                                       kAutocompleteOneTimePassword) ||
       base::StartsWith(field_type, kAutocompleteCreditCardPrefix,
                        base::CompareCase::SENSITIVE)) {
     return AutocompleteFlag::kNonPassword;
diff --git a/components/signin/core/browser/signin_internals_util.h b/components/signin/core/browser/signin_internals_util.h
index 09e80e8..9851505 100644
--- a/components/signin/core/browser/signin_internals_util.h
+++ b/components/signin/core/browser/signin_internals_util.h
@@ -18,11 +18,9 @@
 extern const char kSigninPrefPrefix[];
 extern const char kTokenPrefPrefix[];
 
-// Helper enums to access fields from SigninStatus (declared below).
-enum {
-  SIGNIN_FIELDS_BEGIN = 0,
-  UNTIMED_FIELDS_BEGIN_UNTYPED = SIGNIN_FIELDS_BEGIN
-};
+// Helper constants to access fields from SigninStatus (declared below).
+constexpr int SIGNIN_FIELDS_BEGIN = 0;
+constexpr int UNTIMED_FIELDS_BEGIN_UNTYPED = SIGNIN_FIELDS_BEGIN;
 
 enum UntimedSigninStatusField {
   UNTIMED_FIELDS_BEGIN = UNTIMED_FIELDS_BEGIN_UNTYPED,
@@ -32,10 +30,8 @@
   UNTIMED_FIELDS_END
 };
 
-enum {
-  UNTIMED_FIELDS_COUNT = UNTIMED_FIELDS_END - UNTIMED_FIELDS_BEGIN,
-  TIMED_FIELDS_BEGIN_UNTYPED = UNTIMED_FIELDS_END
-};
+constexpr int UNTIMED_FIELDS_COUNT = UNTIMED_FIELDS_END - UNTIMED_FIELDS_BEGIN;
+constexpr int TIMED_FIELDS_BEGIN_UNTYPED = UNTIMED_FIELDS_END;
 
 enum TimedSigninStatusField {
   TIMED_FIELDS_BEGIN = TIMED_FIELDS_BEGIN_UNTYPED,
@@ -44,11 +40,9 @@
   TIMED_FIELDS_END
 };
 
-enum {
-  TIMED_FIELDS_COUNT = TIMED_FIELDS_END - TIMED_FIELDS_BEGIN,
-  SIGNIN_FIELDS_END = TIMED_FIELDS_END,
-  SIGNIN_FIELDS_COUNT = SIGNIN_FIELDS_END - SIGNIN_FIELDS_BEGIN
-};
+constexpr int TIMED_FIELDS_COUNT = TIMED_FIELDS_END - TIMED_FIELDS_BEGIN;
+constexpr int SIGNIN_FIELDS_END = TIMED_FIELDS_END;
+constexpr int SIGNIN_FIELDS_COUNT = SIGNIN_FIELDS_END - SIGNIN_FIELDS_BEGIN;
 
 // Returns the name of a SigninStatus field.
 std::string SigninStatusFieldToString(UntimedSigninStatusField field);
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc
index 2bd35a87..1e2eca9 100644
--- a/content/browser/devtools/protocol/page_handler.cc
+++ b/content/browser/devtools/protocol/page_handler.cc
@@ -1277,9 +1277,18 @@
 }
 
 Response PageHandler::SetWebLifecycleState(const std::string& state) {
-  WebContentsImpl* web_contents = GetWebContents();
-  if (!web_contents)
+  if (!host_)
     return Response::ServerError("Not attached to a page");
+
+  // Inactive pages(e.g., a prerendered or back-forward cached page) should not
+  // affect the state.
+  if (!host_->IsActive())
+    return Response::ServerError("Not attached to an active page");
+
+  if (host_->GetParentOrOuterDocument())
+    return Response::ServerError("This is only supported for top-level frames");
+
+  WebContents* web_contents = WebContents::FromRenderFrameHost(host_);
   if (state == Page::SetWebLifecycleState::StateEnum::Frozen) {
     // TODO(fmeawad): Instead of forcing a visibility change, only allow
     // freezing a page if it was already hidden.
diff --git a/content/browser/loader/file_url_loader_factory.cc b/content/browser/loader/file_url_loader_factory.cc
index 1a5106b..e1894ae6 100644
--- a/content/browser/loader/file_url_loader_factory.cc
+++ b/content/browser/loader/file_url_loader_factory.cc
@@ -518,7 +518,7 @@
 #if BUILDFLAG(IS_WIN)
     base::FilePath shortcut_target;
     if (link_following_policy == LinkFollowingPolicy::kFollow &&
-        base::LowerCaseEqualsASCII(path.Extension(), ".lnk") &&
+        base::EqualsCaseInsensitiveASCII(path.Extension(), ".lnk") &&
         base::win::ResolveShortcut(path, &shortcut_target, nullptr)) {
       // Follow Windows shortcuts
       redirect_data_ = std::make_unique<RedirectData>();
diff --git a/content/browser/renderer_host/pending_beacon_host.cc b/content/browser/renderer_host/pending_beacon_host.cc
index 118132b8..43e6e79 100644
--- a/content/browser/renderer_host/pending_beacon_host.cc
+++ b/content/browser/renderer_host/pending_beacon_host.cc
@@ -4,6 +4,8 @@
 
 #include "content/browser/renderer_host/pending_beacon_host.h"
 
+#include "content/browser/renderer_host/pending_beacon_service.h"
+
 namespace content {
 
 PendingBeaconHost::PendingBeaconHost(RenderFrameHost* rfh,
@@ -31,4 +33,25 @@
 
 DOCUMENT_USER_DATA_KEY_IMPL(PendingBeaconHost);
 
+Beacon::Beacon(const base::UnguessableToken& id,
+               const GURL& url,
+               blink::mojom::BeaconMethod method,
+               base::TimeDelta timeout,
+               mojo::PendingReceiver<blink::mojom::PendingBeacon> receiver)
+    : receiver_(this, std::move(receiver)),
+      id_(id),
+      url_(url),
+      method_(method),
+      timeout_(timeout) {}
+
+Beacon::~Beacon() = default;
+
+void Beacon::Deactivate() {
+  // Beacons are not deleted on deactivation; they'll be cleaned up when the
+  // document that owns the beacon is either hidden or discarded.
+  // TODO(crbug.com/1293679): Clean up beacons when their owning document is
+  // discarded or hidden.
+  active_ = false;
+}
+
 }  // namespace content
diff --git a/content/browser/renderer_host/pending_beacon_host.h b/content/browser/renderer_host/pending_beacon_host.h
index 74c46b1..76a27454 100644
--- a/content/browser/renderer_host/pending_beacon_host.h
+++ b/content/browser/renderer_host/pending_beacon_host.h
@@ -8,7 +8,6 @@
 #include "base/memory/raw_ptr.h"
 #include "base/time/time.h"
 #include "base/unguessable_token.h"
-#include "content/browser/renderer_host/pending_beacon_service.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/document_user_data.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -17,6 +16,8 @@
 
 namespace content {
 
+class PendingBeaconService;
+
 // Holds a set of IDs (i.e. UnguessableTokens) for a document's
 // pending beacons. This class is responsible for triggering the sending
 // of beacons when a document is either discarded or hidden.
@@ -55,6 +56,34 @@
   DOCUMENT_USER_DATA_KEY_DECL();
 };
 
+class Beacon : public blink::mojom::PendingBeacon {
+ public:
+  // Browser-side pending beacon constructor. Parameters correspond to the
+  // renderer-side PendingBeacon class, except for 'id' which is a
+  // browser-side identifier to distinguish which beacons belong to which
+  // documents. This will be used to determine if a beacon should be sent when
+  // a particular document is discarded or hidden (each document has a
+  // `PendingBeaconHost` which keeps a vector of IDs for the beacons it owns).
+  // API explainer can be found at:
+  // https://github.com/darrenw/docs/blob/main/explainers/beacon_api.md
+  explicit Beacon(const base::UnguessableToken& id,
+                  const GURL& url,
+                  blink::mojom::BeaconMethod method,
+                  base::TimeDelta timeout,
+                  mojo::PendingReceiver<blink::mojom::PendingBeacon> receiver);
+  ~Beacon() override;
+  void Deactivate() override;
+
+ private:
+  mojo::Receiver<blink::mojom::PendingBeacon> receiver_;
+
+  const base::UnguessableToken id_;
+  const GURL url_;
+  [[maybe_unused]] const blink::mojom::BeaconMethod method_;
+  [[maybe_unused]] const base::TimeDelta timeout_;
+  bool active_ = true;
+};
+
 }  // namespace content
 
 #endif  // CONTENT_BROWSER_RENDERER_HOST_PENDING_BEACON_HOST_H_
\ No newline at end of file
diff --git a/content/browser/renderer_host/pending_beacon_service.cc b/content/browser/renderer_host/pending_beacon_service.cc
index af9a911..ccd80ef 100644
--- a/content/browser/renderer_host/pending_beacon_service.cc
+++ b/content/browser/renderer_host/pending_beacon_service.cc
@@ -3,7 +3,9 @@
 // found in the LICENSE file.
 
 #include "content/browser/renderer_host/pending_beacon_service.h"
+
 #include "base/time/time.h"
+#include "content/browser/renderer_host/pending_beacon_host.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "third_party/blink/public/mojom/frame/pending_beacon.mojom.h"
 
@@ -27,26 +29,4 @@
   beacons_.emplace_back(std::move(beacon));
 }
 
-void PendingBeaconService::Beacon::Deactivate() {
-  // Beacons are not deleted on deactivation; they'll be cleaned up when the
-  // document that owns the beacon is either hidden or discarded.
-  // TODO(crbug.com/1293679): Clean up beacons when their owning document is
-  // discarded or hidden.
-  active_ = false;
-}
-
-PendingBeaconService::Beacon::Beacon(
-    const base::UnguessableToken& id,
-    const GURL& url,
-    blink::mojom::BeaconMethod method,
-    base::TimeDelta timeout,
-    mojo::PendingReceiver<blink::mojom::PendingBeacon> receiver)
-    : receiver_(this, std::move(receiver)),
-      id_(id),
-      url_(url),
-      method_(method),
-      timeout_(timeout) {}
-
-PendingBeaconService::Beacon::~Beacon() = default;
-
 }  // namespace content
diff --git a/content/browser/renderer_host/pending_beacon_service.h b/content/browser/renderer_host/pending_beacon_service.h
index 652771fd..5e3c681 100644
--- a/content/browser/renderer_host/pending_beacon_service.h
+++ b/content/browser/renderer_host/pending_beacon_service.h
@@ -8,6 +8,7 @@
 #include "base/memory/singleton.h"
 #include "base/time/time.h"
 #include "base/unguessable_token.h"
+#include "content/browser/renderer_host/pending_beacon_host.h"
 #include "content/common/content_export.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver.h"
@@ -34,37 +35,6 @@
   ~PendingBeaconService();
 
  private:
-  class Beacon : public blink::mojom::PendingBeacon {
-   public:
-    // Browser-side pending beacon constructor. Parameters correspond to the
-    // renderer-side PendingBeacon class, except for 'id' which is a
-    // browser-side identifier to distinguish which beacons belong to which
-    // documents. This will be used to determine if a beacon should be sent when
-    // a particular document is discarded or hidden (each document has a
-    // `PendingBeaconHost` which keeps a vector of IDs for the beacons it owns).
-    // API explainer can be found at:
-    // https://github.com/darrenw/docs/blob/main/explainers/beacon_api.md
-    explicit Beacon(
-        const base::UnguessableToken& id,
-        const GURL& url,
-        blink::mojom::BeaconMethod method,
-        base::TimeDelta timeout,
-        mojo::PendingReceiver<blink::mojom::PendingBeacon> receiver);
-    ~Beacon() override;
-    void Deactivate() override;
-
-   private:
-    mojo::Receiver<blink::mojom::PendingBeacon> receiver_;
-
-    const base::UnguessableToken id_;
-    const GURL url_;
-    [[maybe_unused]] const blink::mojom::BeaconMethod method_;
-    [[maybe_unused]] const base::TimeDelta timeout_;
-    bool active_ = true;
-
-    friend class PendingBeaconService;
-  };
-
   PendingBeaconService();
 
   std::vector<std::unique_ptr<Beacon>> beacons_;
diff --git a/docs/clang_format.md b/docs/clang_format.md
index 13dfe1de..2c55bf1 100644
--- a/docs/clang_format.md
+++ b/docs/clang_format.md
@@ -44,6 +44,7 @@
 
 *   [Sublime Text](https://www.chromium.org/developers/sublime-text#TOC-Format-selection-or-area-around-cursor-using-clang-format)
 *   [llvm's guidelines for vim, emacs, and bbedit](http://clang.llvm.org/docs/ClangFormat.html)
+*   [Visual Studio Code](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/vscode.md#useful-extensions)
 *   For vim, `:so tools/vim/clang-format.vim` and then hit cmd-shift-i (mac)
     ctrl-shift-i (elsewhere) to indent the current line or current selection.
 
diff --git a/extensions/renderer/api/automation/automation_internal_custom_bindings.cc b/extensions/renderer/api/automation/automation_internal_custom_bindings.cc
index 654086a..ea44b0bf 100644
--- a/extensions/renderer/api/automation/automation_internal_custom_bindings.cc
+++ b/extensions/renderer/api/automation/automation_internal_custom_bindings.cc
@@ -1867,12 +1867,7 @@
   if (tree_id == accessibility_focused_tree_id_)
     accessibility_focused_tree_id_ = ui::AXTreeIDUnknown();
 
-  auto it = tree_id_to_tree_wrapper_map_.find(tree_id);
-  if (it == tree_id_to_tree_wrapper_map_.end())
-    return;
-
-  TreeEventListenersChanged(it->second.get(), /* is_deleting=*/true);
-  tree_id_to_tree_wrapper_map_.erase(it);
+  tree_id_to_tree_wrapper_map_.erase(tree_id);
 }
 
 void AutomationInternalCustomBindings::AddTreeChangeObserver(
@@ -2973,9 +2968,8 @@
 }
 
 void AutomationInternalCustomBindings::TreeEventListenersChanged(
-    AutomationAXTreeWrapper* tree_wrapper,
-    bool is_deleting) {
-  if (!is_deleting && tree_wrapper->EventListenerCount() != 0) {
+    AutomationAXTreeWrapper* tree_wrapper) {
+  if (tree_wrapper->EventListenerCount() != 0) {
     trees_with_event_listeners_.insert(tree_wrapper->GetTreeID());
     return;
   }
diff --git a/extensions/renderer/api/automation/automation_internal_custom_bindings.h b/extensions/renderer/api/automation/automation_internal_custom_bindings.h
index 979fb89..e0231a20 100644
--- a/extensions/renderer/api/automation/automation_internal_custom_bindings.h
+++ b/extensions/renderer/api/automation/automation_internal_custom_bindings.h
@@ -271,8 +271,7 @@
                                     bool* offscreen = nullptr,
                                     bool clip_bounds = true) const;
 
-  void TreeEventListenersChanged(AutomationAXTreeWrapper* tree_wrapper,
-                                 bool is_deleting = false);
+  void TreeEventListenersChanged(AutomationAXTreeWrapper* tree_wrapper);
 
   std::map<ui::AXTreeID, std::unique_ptr<AutomationAXTreeWrapper>>
       tree_id_to_tree_wrapper_map_;
diff --git a/ios/chrome/browser/chrome_url_util.mm b/ios/chrome/browser/chrome_url_util.mm
index 3a87262..ec79b99 100644
--- a/ios/chrome/browser/chrome_url_util.mm
+++ b/ios/chrome/browser/chrome_url_util.mm
@@ -22,7 +22,8 @@
 
 bool UrlIsExternalFileReference(const GURL& url) {
   return url.SchemeIs(kChromeUIScheme) &&
-         base::LowerCaseEqualsASCII(url.host(), kChromeUIExternalFileHost);
+         base::EqualsCaseInsensitiveASCII(url.host(),
+                                          kChromeUIExternalFileHost);
 }
 
 bool UrlHasChromeScheme(const GURL& url) {
diff --git a/media/audio/alsa/alsa_wrapper.cc b/media/audio/alsa/alsa_wrapper.cc
index b24630d..a5ac06a 100644
--- a/media/audio/alsa/alsa_wrapper.cc
+++ b/media/audio/alsa/alsa_wrapper.cc
@@ -350,6 +350,10 @@
   return snd_mixer_selem_has_playback_switch(elem);
 }
 
+int AlsaWrapper::MixerSelemHasPlaybackVolume(snd_mixer_elem_t* elem) {
+  return snd_mixer_selem_has_playback_volume(elem);
+}
+
 void AlsaWrapper::MixerSelemIdSetIndex(snd_mixer_selem_id_t* obj,
                                        unsigned int val) {
   snd_mixer_selem_id_set_index(obj, val);
@@ -367,6 +371,12 @@
   return snd_mixer_selem_set_playback_switch(elem, channel, value);
 }
 
+int AlsaWrapper::MixerSelemSetPlaybackSwitchAll(
+    snd_mixer_elem_t* elem,
+    int value) {
+  return snd_mixer_selem_set_playback_switch_all(elem, value);
+}
+
 int AlsaWrapper::MixerSelemSetPlaybackVolumeAll(snd_mixer_elem_t* elem,
                                                 long value) {
   return snd_mixer_selem_set_playback_volume_all(elem, value);
diff --git a/media/audio/alsa/alsa_wrapper.h b/media/audio/alsa/alsa_wrapper.h
index 970327f..11e0f20 100644
--- a/media/audio/alsa/alsa_wrapper.h
+++ b/media/audio/alsa/alsa_wrapper.h
@@ -143,12 +143,15 @@
                                                long* min,
                                                long* max);
   virtual int MixerSelemHasPlaybackSwitch(snd_mixer_elem_t* elem);
+  virtual int MixerSelemHasPlaybackVolume(snd_mixer_elem_t* elem);
   virtual void MixerSelemIdSetIndex(snd_mixer_selem_id_t* obj,
                                     unsigned int val);
   virtual void MixerSelemIdSetName(snd_mixer_selem_id_t* obj, const char* val);
   virtual int MixerSelemSetPlaybackSwitch(snd_mixer_elem_t* elem,
                                           snd_mixer_selem_channel_id_t channel,
                                           int value);
+  virtual int MixerSelemSetPlaybackSwitchAll(snd_mixer_elem_t* elem,
+                                          int value);
   virtual int MixerSelemSetPlaybackVolumeAll(snd_mixer_elem_t* elem,
                                              long value);
   virtual int MixerSelemIdMalloc(snd_mixer_selem_id_t** ptr);
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index 56379bb..2007ceb0 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -90,6 +90,12 @@
   EXTERNALLY_CONDITIONALIZED_MAX
 };
 
+void RecordPervasivePayloadIndex(const char* histogram_name, int index) {
+  if (index != -1) {
+    base::UmaHistogramExactLinear(histogram_name, index, 101);
+  }
+}
+
 }  // namespace
 
 #define CACHE_STATUS_HISTOGRAMS(type)                                      \
@@ -668,8 +674,13 @@
   if (hex_result != request_->checksum) {
     DVLOG(2) << "Pervasive payload checksum mismatch for \"" << request_->url
              << "\": got " << hex_result << ", expected " << request_->checksum;
+    RecordPervasivePayloadIndex("Network.CacheTransparency.MismatchedChecksums",
+                                request_->pervasive_payloads_index_for_logging);
     return false;
   }
+  RecordPervasivePayloadIndex(
+      "Network.CacheTransparency.SingleKeyedCacheIsUsed",
+      request_->pervasive_payloads_index_for_logging);
   return true;
 }
 
@@ -1528,6 +1539,9 @@
   }
 
   if (response_.single_keyed_cache_entry_unusable) {
+    RecordPervasivePayloadIndex("Network.CacheTransparency.MarkedUnusable",
+                                request_->pervasive_payloads_index_for_logging);
+
     // We've read the single keyed entry and it turned out to be unusable. Let's
     // retry reading from the split cache.
     if (effective_load_flags_ & LOAD_USE_SINGLE_KEYED_CACHE) {
diff --git a/net/http/http_request_info.cc b/net/http/http_request_info.cc
index faf3191..dba2c9b6 100644
--- a/net/http/http_request_info.cc
+++ b/net/http/http_request_info.cc
@@ -15,7 +15,8 @@
       privacy_mode(PRIVACY_MODE_DISABLED),
       secure_dns_policy(SecureDnsPolicy::kAllow),
       reporting_upload_depth(0),
-      idempotency(net::DEFAULT_IDEMPOTENCY) {}
+      idempotency(net::DEFAULT_IDEMPOTENCY),
+      pervasive_payloads_index_for_logging(-1) {}
 
 HttpRequestInfo::HttpRequestInfo(const HttpRequestInfo& other) = default;
 
diff --git a/net/http/http_request_info.h b/net/http/http_request_info.h
index 444a9b83..e10fcd4 100644
--- a/net/http/http_request_info.h
+++ b/net/http/http_request_info.h
@@ -89,6 +89,10 @@
   // that the request is idempotent.
   net::Idempotency idempotency;
 
+  // Index of the requested URL in Cache Transparency's pervasive payload list.
+  // Only used for logging purposes.
+  int pervasive_payloads_index_for_logging;
+
   // Checksum of the request body and selected headers, in upper-case
   // hexadecimal. Only non-empty if the USE_SINGLE_KEYED_CACHE load flag is set.
   std::string checksum;
diff --git a/net/url_request/url_request.h b/net/url_request/url_request.h
index ce6d47e7..0aeb701 100644
--- a/net/url_request/url_request.h
+++ b/net/url_request/url_request.h
@@ -792,6 +792,14 @@
   void SetIdempotency(Idempotency idempotency) { idempotency_ = idempotency; }
   Idempotency GetIdempotency() const { return idempotency_; }
 
+  int pervasive_payloads_index_for_logging() const {
+    return pervasive_payloads_index_for_logging_;
+  }
+
+  void set_pervasive_payloads_index_for_logging(int index) {
+    pervasive_payloads_index_for_logging_ = index;
+  }
+
   const std::string& expected_response_checksum() const {
     return expected_response_checksum_;
   }
@@ -1041,6 +1049,11 @@
   ResponseHeadersCallback early_response_headers_callback_;
   ResponseHeadersCallback response_headers_callback_;
 
+  // The index of the request URL in Cache Transparency's Pervasive Payloads
+  // List. This is only used for logging purposes. It is initialized as -1 to
+  // signify that the index has not been set.
+  int pervasive_payloads_index_for_logging_ = -1;
+
   // A SHA-256 checksum of the response and selected headers, stored as
   // upper-case hexadecimal. This is only used if the
   // LOAD_USE_SINGLE_KEYED_CACHE flag is set. On failure to match the cache
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index 33d77d31..e889bb0 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -278,6 +278,8 @@
       net::MutableNetworkTrafficAnnotationTag(request_->traffic_annotation());
   request_info_.socket_tag = request_->socket_tag();
   request_info_.idempotency = request_->GetIdempotency();
+  request_info_.pervasive_payloads_index_for_logging =
+      request_->pervasive_payloads_index_for_logging();
   request_info_.checksum = request_->expected_response_checksum();
 #if BUILDFLAG(ENABLE_REPORTING)
   request_info_.reporting_upload_depth = request_->reporting_upload_depth();
diff --git a/services/network/public/cpp/content_security_policy/content_security_policy.cc b/services/network/public/cpp/content_security_policy/content_security_policy.cc
index d5f266c..9b57873 100644
--- a/services/network/public/cpp/content_security_policy/content_security_policy.cc
+++ b/services/network/public/cpp/content_security_policy/content_security_policy.cc
@@ -1399,65 +1399,65 @@
 }
 
 CSPDirectiveName ToCSPDirectiveName(const std::string& name) {
-  if (base::LowerCaseEqualsASCII(name, "base-uri"))
+  if (base::EqualsCaseInsensitiveASCII(name, "base-uri"))
     return CSPDirectiveName::BaseURI;
-  if (base::LowerCaseEqualsASCII(name, "block-all-mixed-content"))
+  if (base::EqualsCaseInsensitiveASCII(name, "block-all-mixed-content"))
     return CSPDirectiveName::BlockAllMixedContent;
-  if (base::LowerCaseEqualsASCII(name, "child-src"))
+  if (base::EqualsCaseInsensitiveASCII(name, "child-src"))
     return CSPDirectiveName::ChildSrc;
-  if (base::LowerCaseEqualsASCII(name, "connect-src"))
+  if (base::EqualsCaseInsensitiveASCII(name, "connect-src"))
     return CSPDirectiveName::ConnectSrc;
-  if (base::LowerCaseEqualsASCII(name, "default-src"))
+  if (base::EqualsCaseInsensitiveASCII(name, "default-src"))
     return CSPDirectiveName::DefaultSrc;
-  if (base::LowerCaseEqualsASCII(name, "fenced-frame-src"))
+  if (base::EqualsCaseInsensitiveASCII(name, "fenced-frame-src"))
     return CSPDirectiveName::FencedFrameSrc;
-  if (base::LowerCaseEqualsASCII(name, "frame-ancestors"))
+  if (base::EqualsCaseInsensitiveASCII(name, "frame-ancestors"))
     return CSPDirectiveName::FrameAncestors;
-  if (base::LowerCaseEqualsASCII(name, "frame-src"))
+  if (base::EqualsCaseInsensitiveASCII(name, "frame-src"))
     return CSPDirectiveName::FrameSrc;
-  if (base::LowerCaseEqualsASCII(name, "font-src"))
+  if (base::EqualsCaseInsensitiveASCII(name, "font-src"))
     return CSPDirectiveName::FontSrc;
-  if (base::LowerCaseEqualsASCII(name, "form-action"))
+  if (base::EqualsCaseInsensitiveASCII(name, "form-action"))
     return CSPDirectiveName::FormAction;
-  if (base::LowerCaseEqualsASCII(name, "img-src"))
+  if (base::EqualsCaseInsensitiveASCII(name, "img-src"))
     return CSPDirectiveName::ImgSrc;
-  if (base::LowerCaseEqualsASCII(name, "manifest-src"))
+  if (base::EqualsCaseInsensitiveASCII(name, "manifest-src"))
     return CSPDirectiveName::ManifestSrc;
-  if (base::LowerCaseEqualsASCII(name, "media-src"))
+  if (base::EqualsCaseInsensitiveASCII(name, "media-src"))
     return CSPDirectiveName::MediaSrc;
-  if (base::LowerCaseEqualsASCII(name, "object-src"))
+  if (base::EqualsCaseInsensitiveASCII(name, "object-src"))
     return CSPDirectiveName::ObjectSrc;
-  if (base::LowerCaseEqualsASCII(name, "prefetch-src"))
+  if (base::EqualsCaseInsensitiveASCII(name, "prefetch-src"))
     return CSPDirectiveName::PrefetchSrc;
-  if (base::LowerCaseEqualsASCII(name, "report-uri"))
+  if (base::EqualsCaseInsensitiveASCII(name, "report-uri"))
     return CSPDirectiveName::ReportURI;
-  if (base::LowerCaseEqualsASCII(name, "require-trusted-types-for"))
+  if (base::EqualsCaseInsensitiveASCII(name, "require-trusted-types-for"))
     return CSPDirectiveName::RequireTrustedTypesFor;
-  if (base::LowerCaseEqualsASCII(name, "sandbox"))
+  if (base::EqualsCaseInsensitiveASCII(name, "sandbox"))
     return CSPDirectiveName::Sandbox;
-  if (base::LowerCaseEqualsASCII(name, "script-src"))
+  if (base::EqualsCaseInsensitiveASCII(name, "script-src"))
     return CSPDirectiveName::ScriptSrc;
-  if (base::LowerCaseEqualsASCII(name, "script-src-attr"))
+  if (base::EqualsCaseInsensitiveASCII(name, "script-src-attr"))
     return CSPDirectiveName::ScriptSrcAttr;
-  if (base::LowerCaseEqualsASCII(name, "script-src-elem"))
+  if (base::EqualsCaseInsensitiveASCII(name, "script-src-elem"))
     return CSPDirectiveName::ScriptSrcElem;
-  if (base::LowerCaseEqualsASCII(name, "style-src"))
+  if (base::EqualsCaseInsensitiveASCII(name, "style-src"))
     return CSPDirectiveName::StyleSrc;
-  if (base::LowerCaseEqualsASCII(name, "style-src-attr"))
+  if (base::EqualsCaseInsensitiveASCII(name, "style-src-attr"))
     return CSPDirectiveName::StyleSrcAttr;
-  if (base::LowerCaseEqualsASCII(name, "style-src-elem"))
+  if (base::EqualsCaseInsensitiveASCII(name, "style-src-elem"))
     return CSPDirectiveName::StyleSrcElem;
-  if (base::LowerCaseEqualsASCII(name, "treat-as-public-address"))
+  if (base::EqualsCaseInsensitiveASCII(name, "treat-as-public-address"))
     return CSPDirectiveName::TreatAsPublicAddress;
-  if (base::LowerCaseEqualsASCII(name, "trusted-types"))
+  if (base::EqualsCaseInsensitiveASCII(name, "trusted-types"))
     return CSPDirectiveName::TrustedTypes;
-  if (base::LowerCaseEqualsASCII(name, "upgrade-insecure-requests"))
+  if (base::EqualsCaseInsensitiveASCII(name, "upgrade-insecure-requests"))
     return CSPDirectiveName::UpgradeInsecureRequests;
-  if (base::LowerCaseEqualsASCII(name, "worker-src"))
+  if (base::EqualsCaseInsensitiveASCII(name, "worker-src"))
     return CSPDirectiveName::WorkerSrc;
-  if (base::LowerCaseEqualsASCII(name, "report-to"))
+  if (base::EqualsCaseInsensitiveASCII(name, "report-to"))
     return CSPDirectiveName::ReportTo;
-  if (base::LowerCaseEqualsASCII(name, "navigate-to"))
+  if (base::EqualsCaseInsensitiveASCII(name, "navigate-to"))
     return CSPDirectiveName::NavigateTo;
 
   return CSPDirectiveName::Unknown;
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc
index e4b8796a..00b86bc9 100644
--- a/services/network/public/cpp/features.cc
+++ b/services/network/public/cpp/features.cc
@@ -268,13 +268,17 @@
 const base::Feature kCacheTransparency{"CacheTransparency",
                                        base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Load Pervasive Payloads List for Cache Transparency.
+const base::Feature kPervasivePayloadsList{"PervasivePayloadsList",
+                                           base::FEATURE_DISABLED_BY_DEFAULT};
+
 // The list of pervasive payloads. A comma separated list starting with a
 // version number, followed one or more pairs of URL and checksum. The version
 // number is an integer. The URL is the canonical URL as returned by
 // GURL::spec(). The checksum is the SHA-256 of the payload and selected headers
 // converted to uppercase hexadecimal.
 constexpr base::FeatureParam<std::string> kCacheTransparencyPervasivePayloads{
-    &kCacheTransparency, "pervasive-payloads", ""};
+    &kPervasivePayloadsList, "pervasive-payloads", ""};
 
 // Read as much of the net::URLRequest as there is space in the Mojo data pipe.
 const base::Feature kOptimizeNetworkBuffers{"OptimizeNetworkBuffers",
diff --git a/services/network/public/cpp/features.h b/services/network/public/cpp/features.h
index a39b128..10bbcd0 100644
--- a/services/network/public/cpp/features.h
+++ b/services/network/public/cpp/features.h
@@ -113,6 +113,9 @@
 extern const base::Feature kCacheTransparency;
 
 COMPONENT_EXPORT(NETWORK_CPP)
+extern const base::Feature kPervasivePayloadsList;
+
+COMPONENT_EXPORT(NETWORK_CPP)
 extern const base::FeatureParam<std::string>
     kCacheTransparencyPervasivePayloads;
 
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
index 559ed70..c2d3f893 100644
--- a/services/network/url_loader.cc
+++ b/services/network/url_loader.cc
@@ -432,10 +432,28 @@
     return enabled_;
   }
 
+  bool PervasivePayloadsEnabled() const {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    return pervasive_payloads_enabled_;
+  }
+
+  absl::optional<int> GetIndexForURL(const GURL& url) const {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+    if (!pervasive_payloads_enabled_ || !url.is_valid())
+      return absl::nullopt;
+
+    auto it = map_.find(url.spec());
+    if (it == map_.end()) {
+      return absl::nullopt;
+    }
+    return std::distance(map_.begin(), it);
+  }
+
   absl::optional<std::string> GetChecksumForURL(const GURL& url) const {
     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-    if (!url.is_valid())
+    if (!enabled_ || !url.is_valid())
       return absl::nullopt;
 
     auto it = map_.find(url.spec());
@@ -449,7 +467,11 @@
   using PervasivePayloadsMap = base::flat_map<std::string, std::string>;
 
   CacheTransparencySettings()
-      : enabled_(base::FeatureList::IsEnabled(features::kCacheTransparency)),
+      : enabled_(
+            base::FeatureList::IsEnabled(features::kCacheTransparency) &&
+            base::FeatureList::IsEnabled(features::kPervasivePayloadsList)),
+        pervasive_payloads_enabled_(
+            base::FeatureList::IsEnabled(features::kPervasivePayloadsList)),
         map_(CreateMap()) {
     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   }
@@ -458,7 +480,7 @@
 
   PervasivePayloadsMap CreateMap() {
     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    if (!enabled_)
+    if (!pervasive_payloads_enabled_)
       return PervasivePayloadsMap();
 
     const std::string comma_separated =
@@ -497,7 +519,8 @@
   }
 
   SEQUENCE_CHECKER(sequence_checker_);
-  const bool enabled_ GUARDED_BY_CONTEXT(sequence_checker_) = false;
+  const bool enabled_ GUARDED_BY_CONTEXT(sequence_checker_);
+  const bool pervasive_payloads_enabled_ GUARDED_BY_CONTEXT(sequence_checker_);
   const PervasivePayloadsMap map_ GUARDED_BY_CONTEXT(sequence_checker_);
 
   // This is normally leaked to avoid running a destructor. It's only
@@ -544,6 +567,16 @@
   return false;
 }
 
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum class CacheTransparencyCacheNotUsedReason {
+  kTryingSingleKeyedCache = 0,
+  kIncompatibleRequestType = 1,
+  kIncompatibleRequestLoadFlags = 2,
+  kIncompatibleRequestHeaders = 3,
+  kMaxValue = kIncompatibleRequestHeaders,
+};
+
 }  // namespace
 
 URLLoader::MaybeSyncURLLoaderClient::MaybeSyncURLLoaderClient(
@@ -764,27 +797,46 @@
 
   int request_load_flags = request.load_flags;
 
+  if (CacheTransparencySettings::Get().PervasivePayloadsEnabled()) {
+    auto index = CacheTransparencySettings::Get().GetIndexForURL(request.url);
+    if (index.has_value()) {
+      url_request_->set_pervasive_payloads_index_for_logging(index.value());
+      base::UmaHistogramExactLinear("Network.CacheTransparency.URLMatched",
+                                    index.value(), 101);
+    }
+  }
+
   if (CacheTransparencySettings::Get().enabled() &&
       ThirdPartyCookiesEnabled()) {
     auto checksum =
         CacheTransparencySettings::Get().GetChecksumForURL(request.url);
     if (checksum.has_value()) {
+      CacheTransparencyCacheNotUsedReason cache_not_used_reason =
+          CacheTransparencyCacheNotUsedReason::kTryingSingleKeyedCache;
       DVLOG(2) << "Found pervasive payload: " << request.url.spec();
       if (request.method != net::HttpRequestHeaders::kGetMethod) {
         DVLOG(2) << "Not using single-keyed-cache; method is "
                  << request.method;
+        cache_not_used_reason =
+            CacheTransparencyCacheNotUsedReason::kIncompatibleRequestType;
       } else if (HasFlagsIncompatibleWithSingleKeyedCache(request_load_flags)) {
         DVLOG(2) << "Not using single-keyed-cache; flags are "
                  << request_load_flags;
+        cache_not_used_reason =
+            CacheTransparencyCacheNotUsedReason::kIncompatibleRequestLoadFlags;
       } else if (HasHeadersIncompatibleWithSingleKeyedCache(request.headers)) {
         DVLOG(2) << "Not using single-keyed-cache; headers are\n"
                  << request.headers.ToString();
+        cache_not_used_reason =
+            CacheTransparencyCacheNotUsedReason::kIncompatibleRequestHeaders;
       } else {
         DVLOG(2) << "Trying single-keyed cache";
         request_load_flags |= net::LOAD_USE_SINGLE_KEYED_CACHE;
 
         url_request_->set_expected_response_checksum(checksum.value());
       }
+      base::UmaHistogramEnumeration("Network.CacheTransparency.CacheNotUsed",
+                                    cache_not_used_reason);
     }
   }
 
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc
index 3966a4f..1b59124d 100644
--- a/services/network/url_loader_unittest.cc
+++ b/services/network/url_loader_unittest.cc
@@ -7313,8 +7313,10 @@
     params["pervasive-payloads"] = base::StrCat(
         {"1,", pervasive_payload_url_.spec(),
          ",87F6EE26BD9CFC440B4C805AAE79E0A5671F61C00B5E0AF54B8199EAF64AAAC3"});
-    cache_transparency_feature_.InitAndEnableFeatureWithParameters(
-        features::kCacheTransparency, params);
+    pervasive_payloads_feature_.InitAndEnableFeatureWithParameters(
+        features::kPervasivePayloadsList, params);
+    cache_transparency_feature_.InitAndEnableFeature(
+        features::kCacheTransparency);
     split_cache_feature_.InitAndEnableFeature(
         net::features::kSplitCacheByNetworkIsolationKey);
 
@@ -7398,6 +7400,7 @@
  private:
   static constexpr char kPervasivePayload[] = "/pervasive.js";
 
+  base::test::ScopedFeatureList pervasive_payloads_feature_;
   base::test::ScopedFeatureList cache_transparency_feature_;
   base::test::ScopedFeatureList split_cache_feature_;
   GURL pervasive_payload_url_;
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 72dbc147..5461117 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -5865,21 +5865,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5078.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5079.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5078.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5079.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5078.0",
-              "revision": "version:104.0.5078.0"
+              "location": "lacros_version_skew_tests_v104.0.5079.0",
+              "revision": "version:104.0.5079.0"
             }
           ],
           "dimension_sets": [
@@ -5892,7 +5892,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5078.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5079.0"
       },
       {
         "isolate_profile_data": true,
@@ -6030,21 +6030,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5078.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5079.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5078.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5079.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5078.0",
-              "revision": "version:104.0.5078.0"
+              "location": "lacros_version_skew_tests_v104.0.5079.0",
+              "revision": "version:104.0.5079.0"
             }
           ],
           "dimension_sets": [
@@ -6056,7 +6056,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5078.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5079.0"
       },
       {
         "args": [
@@ -6176,21 +6176,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5078.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5079.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5078.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5079.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5078.0",
-              "revision": "version:104.0.5078.0"
+              "location": "lacros_version_skew_tests_v104.0.5079.0",
+              "revision": "version:104.0.5079.0"
             }
           ],
           "dimension_sets": [
@@ -6202,7 +6202,7 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 104.0.5078.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5079.0"
       },
       {
         "isolate_profile_data": true,
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 413263c..54538c8 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -87946,21 +87946,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5078.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5079.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5078.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5079.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5078.0",
-              "revision": "version:104.0.5078.0"
+              "location": "lacros_version_skew_tests_v104.0.5079.0",
+              "revision": "version:104.0.5079.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -87968,7 +87968,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5078.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5079.0"
       },
       {
         "isolate_profile_data": true,
@@ -88081,28 +88081,28 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5078.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5079.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5078.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5079.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5078.0",
-              "revision": "version:104.0.5078.0"
+              "location": "lacros_version_skew_tests_v104.0.5079.0",
+              "revision": "version:104.0.5079.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5078.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5079.0"
       },
       {
         "args": [
@@ -88202,28 +88202,28 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5078.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5079.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5078.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5079.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5078.0",
-              "revision": "version:104.0.5078.0"
+              "location": "lacros_version_skew_tests_v104.0.5079.0",
+              "revision": "version:104.0.5079.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 104.0.5078.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5079.0"
       },
       {
         "isolate_profile_data": true,
@@ -89561,20 +89561,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5078.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5079.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5078.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5079.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5078.0",
-              "revision": "version:104.0.5078.0"
+              "location": "lacros_version_skew_tests_v104.0.5079.0",
+              "revision": "version:104.0.5079.0"
             }
           ],
           "dimension_sets": [
@@ -89588,7 +89588,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5078.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5079.0"
       },
       {
         "merge": {
@@ -89726,20 +89726,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5078.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5079.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5078.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5079.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5078.0",
-              "revision": "version:104.0.5078.0"
+              "location": "lacros_version_skew_tests_v104.0.5079.0",
+              "revision": "version:104.0.5079.0"
             }
           ],
           "dimension_sets": [
@@ -89752,7 +89752,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5078.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5079.0"
       },
       {
         "args": [
@@ -89872,20 +89872,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5078.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5079.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5078.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5079.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5078.0",
-              "revision": "version:104.0.5078.0"
+              "location": "lacros_version_skew_tests_v104.0.5079.0",
+              "revision": "version:104.0.5079.0"
             }
           ],
           "dimension_sets": [
@@ -89898,7 +89898,7 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 104.0.5078.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5079.0"
       },
       {
         "merge": {
@@ -91394,20 +91394,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5078.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5079.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5078.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5079.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5078.0",
-              "revision": "version:104.0.5078.0"
+              "location": "lacros_version_skew_tests_v104.0.5079.0",
+              "revision": "version:104.0.5079.0"
             }
           ],
           "dimension_sets": [
@@ -91421,7 +91421,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5078.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5079.0"
       },
       {
         "merge": {
@@ -91559,20 +91559,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5078.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5079.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5078.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 104.0.5079.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5078.0",
-              "revision": "version:104.0.5078.0"
+              "location": "lacros_version_skew_tests_v104.0.5079.0",
+              "revision": "version:104.0.5079.0"
             }
           ],
           "dimension_sets": [
@@ -91585,7 +91585,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5078.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5079.0"
       },
       {
         "args": [
@@ -91705,20 +91705,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5078.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5079.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5078.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 104.0.5079.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5078.0",
-              "revision": "version:104.0.5078.0"
+              "location": "lacros_version_skew_tests_v104.0.5079.0",
+              "revision": "version:104.0.5079.0"
             }
           ],
           "dimension_sets": [
@@ -91731,7 +91731,7 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 104.0.5078.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5079.0"
       },
       {
         "merge": {
@@ -92466,20 +92466,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5078.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5079.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5078.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 104.0.5079.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v104.0.5078.0",
-              "revision": "version:104.0.5078.0"
+              "location": "lacros_version_skew_tests_v104.0.5079.0",
+              "revision": "version:104.0.5079.0"
             }
           ],
           "dimension_sets": [
@@ -92492,7 +92492,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 104.0.5078.0"
+        "variant_id": "Lacros version skew testing ash 104.0.5079.0"
       }
     ]
   },
diff --git a/testing/buildbot/filters/pixel_tests.filter b/testing/buildbot/filters/pixel_tests.filter
index 9d1fdc48..660f425 100644
--- a/testing/buildbot/filters/pixel_tests.filter
+++ b/testing/buildbot/filters/pixel_tests.filter
@@ -53,7 +53,7 @@
 PermissionRequestChipDialogBrowserTest.*
 *PermissionPromptBubbleViewBrowserTest.*
 PrivacySandboxDialogViewBrowserTest.*
-PrivacySandboxNoticeBubbleViewBrowserTest.*
+PrivacySandboxNoticeBubbleBrowserTest.*
 PromptForScanningModalDialogTest.*
 QRCodeGeneratorBubbleBrowserTest.*
 RelaunchRecommendedBubbleViewDialogTest.*
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index ec5839c5..8b52509 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -22,15 +22,15 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5078.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v104.0.5079.0/test_ash_chrome',
     ],
-    'identifier': 'Lacros version skew testing ash 104.0.5078.0',
+    'identifier': 'Lacros version skew testing ash 104.0.5079.0',
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v104.0.5078.0',
-          'revision': 'version:104.0.5078.0',
+          'location': 'lacros_version_skew_tests_v104.0.5079.0',
+          'revision': 'version:104.0.5079.0',
         },
       ],
     },
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 746ac78..81b7058 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -8777,7 +8777,7 @@
             ],
             "experiments": [
                 {
-                    "name": "Enabled,max_queue_time:75ms,_V2"
+                    "name": "Enabled,max_queue_time:75ms,_V4"
                 }
             ]
         }
diff --git a/third_party/blink/public/web/web_autofill_client.h b/third_party/blink/public/web/web_autofill_client.h
index 5a7c10a8..c57df434 100644
--- a/third_party/blink/public/web/web_autofill_client.h
+++ b/third_party/blink/public/web/web_autofill_client.h
@@ -38,6 +38,7 @@
 class WebInputElement;
 class WebKeyboardEvent;
 class WebNode;
+class WebString;
 
 class WebAutofillClient {
  public:
@@ -62,6 +63,11 @@
 
   virtual void DidAssociateFormControlsDynamically() {}
   virtual void AjaxSucceeded() {}
+  // Called when |element| is in autofilled state and the value has been changed
+  // by JavaScript. |old_value| contains the value before being changed.
+  virtual void JavaScriptChangedAutofilledValue(
+      const WebFormControlElement& element,
+      const WebString& old_value) {}
 
   virtual void DidCompleteFocusChangeInFrame() {}
   virtual void DidReceiveLeftMouseDownOrGestureTapInNode(const WebNode&) {}
diff --git a/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc
index 7072b6b..7fa18338 100644
--- a/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_length_interpolation_type.cc
@@ -137,8 +137,8 @@
     StyleResolverState& state) const {
   ComputedStyle& style = *state.Style();
   float zoom = EffectiveZoom(style);
-  CSSToLengthConversionData conversion_data = state.CssToLengthConversionData();
-  conversion_data.SetZoom(zoom);
+  CSSToLengthConversionData conversion_data =
+      state.CssToLengthConversionData().CopyWithAdjustedZoom(zoom);
   Length length = To<InterpolableLength>(interpolable_value)
                       .CreateLength(conversion_data, value_range_);
   if (LengthPropertyFunctions::SetLength(CssProperty(), style, length)) {
diff --git a/third_party/blink/renderer/core/css/build.gni b/third_party/blink/renderer/core/css/build.gni
index ea4f7d2..a4a8f4f 100644
--- a/third_party/blink/renderer/core/css/build.gni
+++ b/third_party/blink/renderer/core/css/build.gni
@@ -707,6 +707,7 @@
   "css_style_declaration_test.cc",
   "css_style_sheet_test.cc",
   "css_syntax_string_parser_test.cc",
+  "css_to_length_conversion_data_test.cc",
   "css_value_clamping_utils_test.cc",
   "cssom/computed_style_property_map_test.cc",
   "cssom/cross_thread_style_value_test.cc",
diff --git a/third_party/blink/renderer/core/css/css_container_values.cc b/third_party/blink/renderer/core/css/css_container_values.cc
index 1f352d5d..6128db22 100644
--- a/third_party/blink/renderer/core/css/css_container_values.cc
+++ b/third_party/blink/renderer/core/css/css_container_values.cc
@@ -18,7 +18,10 @@
       width_(width),
       height_(height),
       writing_mode_(style.GetWritingMode()),
-      font_sizes_(&style, document.documentElement()->GetComputedStyle()) {}
+      font_sizes_(CSSToLengthConversionData::FontSizes(
+                      &style,
+                      document.documentElement()->GetComputedStyle())
+                      .Unzoomed()) {}
 
 float CSSContainerValues::EmSize() const {
   return font_sizes_.Em();
@@ -29,11 +32,11 @@
 }
 
 float CSSContainerValues::ExSize() const {
-  return font_sizes_.Ex() / font_sizes_.Zoom();
+  return font_sizes_.Ex();
 }
 
 float CSSContainerValues::ChSize() const {
-  return font_sizes_.Ch() / font_sizes_.Zoom();
+  return font_sizes_.Ch();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_to_length_conversion_data.cc b/third_party/blink/renderer/core/css/css_to_length_conversion_data.cc
index ab6fd70..d2fcee6 100644
--- a/third_party/blink/renderer/core/css/css_to_length_conversion_data.cc
+++ b/third_party/blink/renderer/core/css/css_to_length_conversion_data.cc
@@ -102,18 +102,31 @@
   DCHECK(font_data);
   if (!font_data || !font_data->GetFontMetrics().HasXHeight())
     return em_ / 2.0f;
-  return font_data->GetFontMetrics().XHeight();
+  // Font-metrics-based units already account for `zoom`. Therefore we need
+  // to unzoom using `zoom` first, if the zoom is adjusted.
+  float unzoom = (zoom_adjust_.has_value() ? zoom_ : 1.0f);
+  return font_data->GetFontMetrics().XHeight() / unzoom *
+         zoom_adjust_.value_or(1.0f);
 }
 
 float CSSToLengthConversionData::FontSizes::Ch() const {
   DCHECK(font_);
   const SimpleFontData* font_data = font_->PrimaryFont();
   DCHECK(font_data);
-  return font_data ? font_data->GetFontMetrics().ZeroWidth() : 0;
+  // Font-metrics-based units already account for `zoom`. Therefore we need
+  // to unzoom using `zoom` first, if the zoom is adjusted.
+  float unzoom = (zoom_adjust_.has_value() ? zoom_ : 1.0f);
+  return font_data ? (font_data->GetFontMetrics().ZeroWidth() / unzoom *
+                      zoom_adjust_.value_or(1.0f))
+                   : 0;
 }
 
-float CSSToLengthConversionData::FontSizes::Zoom() const {
-  return zoom_ ? zoom_ : 1;
+CSSToLengthConversionData::FontSizes
+CSSToLengthConversionData::FontSizes::CopyWithAdjustedZoom(
+    float new_zoom) const {
+  FontSizes font_sizes = *this;
+  font_sizes.zoom_adjust_ = new_zoom;
+  return font_sizes;
 }
 
 CSSToLengthConversionData::ViewportSize::ViewportSize(
@@ -188,7 +201,10 @@
       font_sizes_(font_sizes),
       viewport_size_(viewport_size),
       container_sizes_(container_sizes),
-      zoom_(ClampTo<float>(zoom, std::numeric_limits<float>::denorm_min())) {}
+      zoom_(ClampTo<float>(zoom, std::numeric_limits<float>::denorm_min())) {
+  if (zoom_ != font_sizes_.zoom_)
+    font_sizes_ = font_sizes.CopyWithAdjustedZoom(zoom_);
+}
 
 CSSToLengthConversionData::CSSToLengthConversionData(
     const ComputedStyle* style,
@@ -553,19 +569,17 @@
     case CSSPrimitiveValue::UnitType::kContainerMax:
       return value * ContainerMaxPercent() * Zoom();
 
-    // We do not apply the zoom factor when we are computing the value of the
-    // font-size property. The zooming for font sizes is much more complicated,
-    // since we have to worry about enforcing the minimum font size preference
-    // as well as enforcing the implicit "smart minimum."
+    // Note that functions for font-relative units already account for the
+    // zoom factor.
     case CSSPrimitiveValue::UnitType::kEms:
     case CSSPrimitiveValue::UnitType::kQuirkyEms:
-      return value * EmFontSize() * Zoom();
+      return value * EmFontSize();
 
     case CSSPrimitiveValue::UnitType::kExs:
       return value * ExFontSize();
 
     case CSSPrimitiveValue::UnitType::kRems:
-      return value * RemFontSize() * Zoom();
+      return value * RemFontSize();
 
     case CSSPrimitiveValue::UnitType::kChs:
       return value * ChFontSize();
diff --git a/third_party/blink/renderer/core/css/css_to_length_conversion_data.h b/third_party/blink/renderer/core/css/css_to_length_conversion_data.h
index ca8ce3b..eb106aa2 100644
--- a/third_party/blink/renderer/core/css/css_to_length_conversion_data.h
+++ b/third_party/blink/renderer/core/css/css_to_length_conversion_data.h
@@ -55,21 +55,27 @@
     DISALLOW_NEW();
 
    public:
-    FontSizes() : em_(0), rem_(0), font_(nullptr), zoom_(1) {}
+    FontSizes() = default;
     FontSizes(float em, float rem, const Font*, float zoom);
     FontSizes(const ComputedStyle*, const ComputedStyle* root_style);
 
-    float Em() const { return em_; }
-    float Rem() const { return rem_; }
-    float Zoom() const;
+    FontSizes Unzoomed() const { return CopyWithAdjustedZoom(1.0f); }
+
+    float Em() const { return em_ * zoom_adjust_.value_or(zoom_); }
+    float Rem() const { return rem_ * zoom_adjust_.value_or(zoom_); }
     float Ex() const;
     float Ch() const;
 
    private:
-    float em_;
-    float rem_;
-    const Font* font_;
-    float zoom_;
+    friend class CSSToLengthConversionData;
+
+    FontSizes CopyWithAdjustedZoom(float new_zoom) const;
+
+    float em_ = 0;
+    float rem_ = 0;
+    const Font* font_ = nullptr;
+    float zoom_ = 1;
+    absl::optional<float> zoom_adjust_;
   };
 
   class CORE_EXPORT ViewportSize {
@@ -172,7 +178,6 @@
   float RemFontSize() const;
   float ExFontSize() const;
   float ChFontSize() const;
-  float FontSizeZoom() const { return font_sizes_.Zoom(); }
 
   // Accessing these marks the style as having viewport units
   double ViewportWidthPercent() const;
@@ -226,6 +231,9 @@
                                      viewport_size_, container_sizes_,
                                      new_zoom);
   }
+  CSSToLengthConversionData Unzoomed() const {
+    return CopyWithAdjustedZoom(1.0f);
+  }
 
   double ZoomedComputedPixels(double value, CSSPrimitiveValue::UnitType) const;
 
diff --git a/third_party/blink/renderer/core/css/css_to_length_conversion_data_test.cc b/third_party/blink/renderer/core/css/css_to_length_conversion_data_test.cc
new file mode 100644
index 0000000..1f42c87
--- /dev/null
+++ b/third_party/blink/renderer/core/css/css_to_length_conversion_data_test.cc
@@ -0,0 +1,114 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/blink/renderer/core/css/css_primitive_value.h"
+#include "third_party/blink/renderer/core/css/css_test_helpers.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/dom/element.h"
+#include "third_party/blink/renderer/core/dom/node_computed_style.h"
+#include "third_party/blink/renderer/core/html/html_div_element.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
+#include "third_party/blink/renderer/core/testing/page_test_base.h"
+#include "third_party/blink/renderer/platform/geometry/length.h"
+
+namespace blink {
+
+class CSSToLengthConversionDataTest : public PageTestBase {
+ public:
+  void SetUp() override {
+    PageTestBase::SetUp();
+    LoadAhem();
+  }
+
+  // Set up a page with "Ahem 10px" as :root, and "Ahem 20px" at some <div>,
+  // then return a CSSToLengthConversionData constructed from that.
+  //
+  // css_zoom - The zoom to apply to :root.
+  // data_zoom - The zoom to pass to the CSSToLengthConversionData constructor.
+  CSSToLengthConversionData ConversionData(
+      absl::optional<float> css_zoom = absl::nullopt,
+      absl::optional<float> data_zoom = absl::nullopt) {
+    Element* root = GetDocument().documentElement();
+    DCHECK(root);
+    if (css_zoom.has_value()) {
+      root->SetInlineStyleProperty(CSSPropertyID::kZoom,
+                                   String::Format("%f", *css_zoom));
+    }
+    root->SetInlineStyleProperty(CSSPropertyID::kFontSize, "10px");
+    root->SetInlineStyleProperty(CSSPropertyID::kFontFamily, "Ahem");
+    auto* div = MakeGarbageCollected<HTMLDivElement>(GetDocument());
+    div->SetInlineStyleProperty(CSSPropertyID::kFontSize, "20px");
+    GetDocument().body()->AppendChild(div);
+    UpdateAllLifecyclePhasesForTest();
+    return CSSToLengthConversionData(
+        div->GetComputedStyle(), root->GetComputedStyle(),
+        GetDocument().GetLayoutView(),
+        CSSToLengthConversionData::ContainerSizes(),
+        data_zoom.value_or(div->GetComputedStyle()->EffectiveZoom()));
+  }
+
+  float Convert(const CSSToLengthConversionData& data, String value) {
+    auto* primitive_value = DynamicTo<CSSPrimitiveValue>(
+        css_test_helpers::ParseValue(GetDocument(), "<length>", value));
+    DCHECK(primitive_value);
+    return primitive_value->ConvertToLength(data).Pixels();
+  }
+};
+
+TEST_F(CSSToLengthConversionDataTest, Normal) {
+  CSSToLengthConversionData data = ConversionData();
+  EXPECT_FLOAT_EQ(1.0f, Convert(data, "1px"));
+  EXPECT_FLOAT_EQ(20.0f, Convert(data, "1em"));
+  EXPECT_FLOAT_EQ(16.0f, Convert(data, "1ex"));
+  EXPECT_FLOAT_EQ(20.0f, Convert(data, "1ch"));
+  EXPECT_FLOAT_EQ(10.0f, Convert(data, "1rem"));
+  EXPECT_FLOAT_EQ(20.0f, Convert(data, "1em"));
+  EXPECT_FLOAT_EQ(36.0f, Convert(data, "calc(1em + 1ex)"));
+}
+
+TEST_F(CSSToLengthConversionDataTest, Zoomed) {
+  CSSToLengthConversionData data = ConversionData(2.0f);
+  EXPECT_FLOAT_EQ(2.0f, Convert(data, "1px"));
+  EXPECT_FLOAT_EQ(40.0f, Convert(data, "1em"));
+  EXPECT_FLOAT_EQ(32.0f, Convert(data, "1ex"));
+  EXPECT_FLOAT_EQ(40.0f, Convert(data, "1ch"));
+  EXPECT_FLOAT_EQ(20.0f, Convert(data, "1rem"));
+  EXPECT_FLOAT_EQ(72.0f, Convert(data, "calc(1em + 1ex)"));
+}
+
+TEST_F(CSSToLengthConversionDataTest, AdjustedZoom) {
+  CSSToLengthConversionData data = ConversionData().CopyWithAdjustedZoom(2.0f);
+  EXPECT_FLOAT_EQ(2.0f, Convert(data, "1px"));
+  EXPECT_FLOAT_EQ(40.0f, Convert(data, "1em"));
+  EXPECT_FLOAT_EQ(32.0f, Convert(data, "1ex"));
+  EXPECT_FLOAT_EQ(40.0f, Convert(data, "1ch"));
+  EXPECT_FLOAT_EQ(20.0f, Convert(data, "1rem"));
+  EXPECT_FLOAT_EQ(72.0f, Convert(data, "calc(1em + 1ex)"));
+}
+
+TEST_F(CSSToLengthConversionDataTest, DifferentZoom) {
+  // The zoom used to calculate fonts is different from the requested
+  // zoom in the CSSToLengthConversionData constructor.
+  CSSToLengthConversionData data = ConversionData(1.0f, 2.0f);
+  EXPECT_FLOAT_EQ(2.0f, Convert(data, "1px"));
+  EXPECT_FLOAT_EQ(40.0f, Convert(data, "1em"));
+  EXPECT_FLOAT_EQ(32.0f, Convert(data, "1ex"));
+  EXPECT_FLOAT_EQ(40.0f, Convert(data, "1ch"));
+  EXPECT_FLOAT_EQ(20.0f, Convert(data, "1rem"));
+  EXPECT_FLOAT_EQ(72.0f, Convert(data, "calc(1em + 1ex)"));
+}
+
+TEST_F(CSSToLengthConversionDataTest, Unzoomed) {
+  CSSToLengthConversionData data = ConversionData(2.0f).Unzoomed();
+  EXPECT_FLOAT_EQ(1.0f, Convert(data, "1px"));
+  EXPECT_FLOAT_EQ(20.0f, Convert(data, "1em"));
+  EXPECT_FLOAT_EQ(16.0f, Convert(data, "1ex"));
+  EXPECT_FLOAT_EQ(20.0f, Convert(data, "1ch"));
+  EXPECT_FLOAT_EQ(10.0f, Convert(data, "1rem"));
+  EXPECT_FLOAT_EQ(36.0f, Convert(data, "calc(1em + 1ex)"));
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/css/media_values.cc b/third_party/blink/renderer/core/css/media_values.cc
index e860739..f0325a5 100644
--- a/third_party/blink/renderer/core/css/media_values.cc
+++ b/third_party/blink/renderer/core/css/media_values.cc
@@ -261,10 +261,9 @@
   DCHECK(frame->GetDocument());
   const ComputedStyle* style = frame->GetDocument()->GetComputedStyle();
   DCHECK(style);
-  CSSToLengthConversionData::FontSizes font_sizes(style, style);
   // Font metrics are based on the used font which is scaled to match the size
   // of CSS pixels. Need to scale back to CSS pixels.
-  return font_sizes.Ex() / font_sizes.Zoom();
+  return CSSToLengthConversionData::FontSizes(style, style).Unzoomed().Ex();
 }
 
 float MediaValues::CalculateChSize(LocalFrame* frame) {
@@ -272,10 +271,9 @@
   DCHECK(frame->GetDocument());
   const ComputedStyle* style = frame->GetDocument()->GetComputedStyle();
   DCHECK(style);
-  CSSToLengthConversionData::FontSizes font_sizes(style, style);
   // Font metrics are based on the used font which is scaled to match the size
   // of CSS pixels. Need to scale back to CSS pixels.
-  return font_sizes.Ch() / font_sizes.Zoom();
+  return CSSToLengthConversionData::FontSizes(style, style).Unzoomed().Ch();
 }
 
 const String MediaValues::CalculateMediaType(LocalFrame* frame) {
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 374e818..c17170da 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
@@ -6620,12 +6620,13 @@
     const CSSValue& second = list.Item(1);
     auto* first_primitive_value = DynamicTo<CSSPrimitiveValue>(first);
     if (first_primitive_value && first_primitive_value->IsLength()) {
+      CSSToLengthConversionData unzoomed_conversion_data =
+          state.CssToLengthConversionData().Unzoomed();
       // <length>{2}
       size = gfx::SizeF(
-          first_primitive_value->ComputeLength<float>(
-              state.CssToLengthConversionData().CopyWithAdjustedZoom(1.0)),
+          first_primitive_value->ComputeLength<float>(unzoomed_conversion_data),
           To<CSSPrimitiveValue>(second).ComputeLength<float>(
-              state.CssToLengthConversionData().CopyWithAdjustedZoom(1.0)));
+              unzoomed_conversion_data));
     } else {
       // <page-size> <orientation>
       size = GetPageSizeFromName(To<CSSIdentifierValue>(first));
@@ -6647,7 +6648,7 @@
       // <length>
       page_size_type = PageSizeType::kFixed;
       float width = first_primitive_value->ComputeLength<float>(
-          state.CssToLengthConversionData().CopyWithAdjustedZoom(1.0));
+          state.CssToLengthConversionData().Unzoomed());
       size = gfx::SizeF(width, width);
     } else {
       const auto& ident = To<CSSIdentifierValue>(first);
diff --git a/third_party/blink/renderer/core/css/resolver/cascade_map.cc b/third_party/blink/renderer/core/css/resolver/cascade_map.cc
index 033f19d..12457bd7 100644
--- a/third_party/blink/renderer/core/css/resolver/cascade_map.cc
+++ b/third_party/blink/renderer/core/css/resolver/cascade_map.cc
@@ -65,6 +65,10 @@
   return find_origin(native_properties_.Buffer()[index], origin);
 }
 
+CascadePriority& CascadeMap::Top(CascadePriorityList& list) {
+  return list.Top(backing_vector_);
+}
+
 const CascadePriority* CascadeMap::FindRevertLayer(
     const CSSPropertyName& name,
     CascadePriority revert_from) const {
diff --git a/third_party/blink/renderer/core/css/resolver/cascade_map.h b/third_party/blink/renderer/core/css/resolver/cascade_map.h
index 962fee4..8ffce0d 100644
--- a/third_party/blink/renderer/core/css/resolver/cascade_map.h
+++ b/third_party/blink/renderer/core/css/resolver/cascade_map.h
@@ -23,6 +23,8 @@
   STACK_ALLOCATED();
 
  public:
+  class CascadePriorityList;
+
   // Get the CascadePriority for the given CSSPropertyName. If there is no
   // entry for the given name, CascadePriority() is returned.
   CascadePriority At(const CSSPropertyName&) const;
@@ -50,6 +52,8 @@
   // layers below the given priority.
   const CascadePriority* FindRevertLayer(const CSSPropertyName&,
                                          CascadePriority) const;
+  // Similar to Find(), if you already have the right CascadePriorityList.
+  CascadePriority& Top(CascadePriorityList&);
   // Adds an entry to the map if the incoming priority is greater than or equal
   // to the current priority for the same name. Entries must be added in non-
   // decreasing lexicographical order of (origin, tree scope, layer).
@@ -168,6 +172,7 @@
   using CustomMap = HashMap<CSSPropertyName, CascadePriorityList>;
 
   const CustomMap& GetCustomMap() const { return custom_properties_; }
+  CustomMap& GetCustomMap() { return custom_properties_; }
 
  private:
   uint64_t high_priority_ = 0;
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
index efaeda2..87c44bf5 100644
--- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -437,24 +437,11 @@
 static float ComputeFontSize(const CSSToLengthConversionData& conversion_data,
                              const CSSPrimitiveValue& primitive_value,
                              const FontDescription::Size& parent_size) {
-  if (primitive_value.IsLength()) {
-    float result = primitive_value.ComputeLength<float>(conversion_data);
-    float font_size_zoom = conversion_data.FontSizeZoom();
-    // TODO(crbug.com/408777): Only accounting for numeric literal value here
-    // will leave calc() without zoom correction.
-    if (primitive_value.IsNumericLiteralValue() && font_size_zoom != 1) {
-      CSSPrimitiveValue::UnitType type =
-          To<CSSNumericLiteralValue>(&primitive_value)->GetType();
-      if (type == CSSPrimitiveValue::UnitType::kChs ||
-          type == CSSPrimitiveValue::UnitType::kExs) {
-        return result / font_size_zoom;
-      }
-    }
-    return result;
-  }
+  if (primitive_value.IsLength())
+    return primitive_value.ComputeLength<float>(conversion_data);
   if (primitive_value.IsCalculated()) {
     return To<CSSMathFunctionValue>(primitive_value)
-        .ToCalcValue(conversion_data)
+        .ToCalcValue(conversion_data.Unzoomed())
         ->Evaluate(parent_size.value);
   }
   NOTREACHED();
@@ -2090,7 +2077,7 @@
         primitive_value->IsCalculatedPercentageWithLength()) {
       // Instead of the actual zoom, use 1 to avoid potential rounding errors
       Length length = primitive_value->ConvertToLength(
-          css_to_length_conversion_data.CopyWithAdjustedZoom(1));
+          css_to_length_conversion_data.Unzoomed());
       return *CSSPrimitiveValue::CreateFromLength(length, 1);
     }
 
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade.cc b/third_party/blink/renderer/core/css/resolver/style_cascade.cc
index 3463360..c97d6e4c 100644
--- a/third_party/blink/renderer/core/css/resolver/style_cascade.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_cascade.cc
@@ -479,10 +479,6 @@
 // (e.g. in AnalyzeMatchResult()) and actually apply them. We need to do this
 // in a second phase so that we know which ones actually won the cascade
 // before we start applying, as some properties can affect others.
-//
-// TODO(sesse): See if we can make this more efficient by iterating
-// directly over the BackingVector instead. In particular, that would
-// remove the Find() calls into map_.
 void StyleCascade::ApplyMatchResult(CascadeResolver& resolver) {
   // We only need to apply the resolver part of the filter here;
   // the rest have been applied in the previous pass.
@@ -507,8 +503,8 @@
     LookupAndApplyDeclaration(property, p, resolver);
   }
 
-  for (const auto& [name, priority_list] : map_.GetCustomMap()) {
-    CascadePriority* p = map_.Find(name);
+  for (auto& [name, priority_list] : map_.GetCustomMap()) {
+    CascadePriority* p = &map_.Top(priority_list);
     CascadePriority priority = *p;
     if (priority.GetGeneration() >= resolver.generation_) {
       continue;
diff --git a/third_party/blink/renderer/core/css/rule_set.cc b/third_party/blink/renderer/core/css/rule_set.cc
index 3951516f..2d8ccd1 100644
--- a/third_party/blink/renderer/core/css/rule_set.cc
+++ b/third_party/blink/renderer/core/css/rule_set.cc
@@ -148,13 +148,13 @@
 }
 
 void RuleSet::AddToRuleSet(const AtomicString& key,
-                           PendingRuleMap& map,
+                           RuleMap& map,
                            const RuleData* rule_data) {
-  Member<HeapLinkedStack<Member<const RuleData>>>& rules =
+  Member<HeapVector<Member<const RuleData>>>& rules =
       map.insert(key, nullptr).stored_value->value;
   if (!rules)
-    rules = MakeGarbageCollected<HeapLinkedStack<Member<const RuleData>>>();
-  rules->Push(rule_data);
+    rules = MakeGarbageCollected<HeapVector<Member<const RuleData>>>();
+  rules->push_back(rule_data);
 }
 
 static void ExtractSelectorValues(const CSSSelector* selector,
@@ -288,17 +288,20 @@
 
   // Prefer rule sets in order of most likely to apply infrequently.
   if (!id.IsEmpty()) {
-    AddToRuleSet(id, EnsurePendingRules()->id_rules, rule_data);
+    need_compaction_ = true;
+    AddToRuleSet(id, id_rules_, rule_data);
     return true;
   }
 
   if (!class_name.IsEmpty()) {
-    AddToRuleSet(class_name, EnsurePendingRules()->class_rules, rule_data);
+    need_compaction_ = true;
+    AddToRuleSet(class_name, class_rules_, rule_data);
     return true;
   }
 
   if (!attr_name.IsEmpty()) {
-    AddToRuleSet(attr_name, EnsurePendingRules()->attr_rules, rule_data);
+    need_compaction_ = true;
+    AddToRuleSet(attr_name, attr_rules_, rule_data);
     if (attr_name == html_names::kStyleAttr) {
       has_bucket_for_style_attr_ = true;
     }
@@ -310,10 +313,10 @@
     // and have a relation of ShadowPseudo between them. Therefore we should
     // never be a situation where ExtractSelectorValues finds id and
     // className in addition to custom pseudo.
+    need_compaction_ = true;
     DCHECK(id.IsEmpty());
     DCHECK(class_name.IsEmpty());
-    AddToRuleSet(custom_pseudo_element_name,
-                 EnsurePendingRules()->ua_shadow_pseudo_element_rules,
+    AddToRuleSet(custom_pseudo_element_name, ua_shadow_pseudo_element_rules_,
                  rule_data);
     return true;
   }
@@ -348,6 +351,7 @@
     case CSSSelector::kPseudoPlaceholder:
     case CSSSelector::kPseudoFileSelectorButton:
       if (it->FollowsPart()) {
+        need_compaction_ = true;
         part_pseudo_rules_.push_back(rule_data);
       } else if (it->FollowsSlotted()) {
         slotted_pseudo_element_rules_.push_back(rule_data);
@@ -355,8 +359,8 @@
         const auto& name = pseudo_type == CSSSelector::kPseudoFileSelectorButton
                                ? shadow_element_names::kPseudoFileUploadButton
                                : shadow_element_names::kPseudoInputPlaceholder;
-        AddToRuleSet(name, EnsurePendingRules()->ua_shadow_pseudo_element_rules,
-                     rule_data);
+        need_compaction_ = true;
+        AddToRuleSet(name, ua_shadow_pseudo_element_rules_, rule_data);
       }
       return true;
     case CSSSelector::kPseudoHost:
@@ -371,7 +375,8 @@
   }
 
   if (!tag_name.IsEmpty()) {
-    AddToRuleSet(tag_name, EnsurePendingRules()->tag_rules, rule_data);
+    need_compaction_ = true;
+    AddToRuleSet(tag_name, tag_rules_, rule_data);
     return true;
   }
 
@@ -437,38 +442,37 @@
 }
 
 void RuleSet::AddPageRule(StyleRulePage* rule) {
-  EnsurePendingRules();  // So that page_rules_.ShrinkToFit() gets called.
+  need_compaction_ = true;
   page_rules_.push_back(rule);
 }
 
 void RuleSet::AddFontFaceRule(StyleRuleFontFace* rule) {
-  EnsurePendingRules();  // So that font_face_rules_.ShrinkToFit() gets called.
+  need_compaction_ = true;
   font_face_rules_.push_back(rule);
 }
 
 void RuleSet::AddKeyframesRule(StyleRuleKeyframes* rule) {
-  EnsurePendingRules();  // So that keyframes_rules_.ShrinkToFit() gets called.
+  need_compaction_ = true;
   keyframes_rules_.push_back(rule);
 }
 
 void RuleSet::AddPropertyRule(StyleRuleProperty* rule) {
-  EnsurePendingRules();  // So that property_rules_.ShrinkToFit() gets called.
+  need_compaction_ = true;
   property_rules_.push_back(rule);
 }
 
 void RuleSet::AddCounterStyleRule(StyleRuleCounterStyle* rule) {
-  EnsurePendingRules();  // So that counter_style_rules_.ShrinkToFit() gets
-                         // called.
+  need_compaction_ = true;
   counter_style_rules_.push_back(rule);
 }
 
 void RuleSet::AddFontPaletteValuesRule(StyleRuleFontPaletteValues* rule) {
-  EnsurePendingRules();
+  need_compaction_ = true;
   font_palette_values_rules_.push_back(rule);
 }
 
 void RuleSet::AddScrollTimelineRule(StyleRuleScrollTimeline* rule) {
-  EnsurePendingRules();  // So that property_rules_.ShrinkToFit() gets called.
+  need_compaction_ = true;
   scroll_timeline_rules_.push_back(rule);
 }
 
@@ -618,28 +622,9 @@
   return cascade_layer->GetOrAddSubLayer(name);
 }
 
-void RuleSet::CompactPendingRules(PendingRuleMap& pending_map,
-                                  CompactRuleMap& compact_map) {
-  for (auto& item : pending_map) {
-    HeapLinkedStack<Member<const RuleData>>* pending_rules =
-        item.value.Release();
-    Member<HeapVector<Member<const RuleData>>>& rules =
-        compact_map.insert(item.key, nullptr).stored_value->value;
-    if (!rules) {
-      rules = MakeGarbageCollected<HeapVector<Member<const RuleData>>>();
-      rules->ReserveInitialCapacity(pending_rules->size());
-    } else {
-      rules->ReserveCapacity(pending_rules->size());
-    }
-    // Since pending_rules is a stack, we need to insert in the reversed
-    // ordering so that the resulting vector is sorted by rule position
-    wtf_size_t num_pending_rules = pending_rules->size();
-    rules->Grow(rules->size() + num_pending_rules);
-    for (auto iter = rules->rbegin(); !pending_rules->IsEmpty(); ++iter) {
-      DCHECK(iter != rules->rend());
-      *iter = pending_rules->Peek();
-      pending_rules->Pop();
-    }
+void RuleSet::CompactRuleMap(RuleMap& map) {
+  for (auto& [key, value] : map) {
+    value->ShrinkToFit();
   }
 }
 
@@ -665,7 +650,6 @@
     const HeapVector<Member<const RuleData>>* list,
     const AtomicString& key,
     const AtomicString& value) const {
-  DCHECK(!pending_rules_);
   DCHECK_EQ(attr_rules_.find(key)->value, list);
   if (list->size() < GetMinimumRulesetSizeForSubstringMatcher()) {
     // Too small to build up a tree, so always check.
@@ -688,7 +672,7 @@
 }
 
 void RuleSet::CreateSubstringMatchers(
-    CompactRuleMap& attr_map,
+    RuleMap& attr_map,
     RuleSet::SubstringMatcherMap& substring_matcher_map) {
   for (const auto& [/*AtomicString*/ attr, /*Member<RuleSet>*/ ruleset] :
        attr_map) {
@@ -744,15 +728,13 @@
 }
 
 void RuleSet::CompactRules() {
-  DCHECK(pending_rules_);
-  PendingRuleMaps* pending_rules = pending_rules_.Release();
-  CompactPendingRules(pending_rules->id_rules, id_rules_);
-  CompactPendingRules(pending_rules->class_rules, class_rules_);
-  CompactPendingRules(pending_rules->attr_rules, attr_rules_);
+  DCHECK(need_compaction_);
+  CompactRuleMap(id_rules_);
+  CompactRuleMap(class_rules_);
+  CompactRuleMap(attr_rules_);
   CreateSubstringMatchers(attr_rules_, attr_substring_matchers_);
-  CompactPendingRules(pending_rules->tag_rules, tag_rules_);
-  CompactPendingRules(pending_rules->ua_shadow_pseudo_element_rules,
-                      ua_shadow_pseudo_element_rules_);
+  CompactRuleMap(tag_rules_);
+  CompactRuleMap(ua_shadow_pseudo_element_rules_);
   link_pseudo_class_rules_.ShrinkToFit();
   cue_pseudo_rules_.ShrinkToFit();
   focus_pseudo_class_rules_.ShrinkToFit();
@@ -776,6 +758,7 @@
 #if EXPENSIVE_DCHECKS_ARE_ON()
   AssertRuleListsSorted();
 #endif
+  need_compaction_ = false;
 }
 
 #if EXPENSIVE_DCHECKS_ARE_ON()
@@ -885,14 +868,6 @@
   visitor->Trace(style_scope_);
 }
 
-void RuleSet::PendingRuleMaps::Trace(Visitor* visitor) const {
-  visitor->Trace(id_rules);
-  visitor->Trace(class_rules);
-  visitor->Trace(attr_rules);
-  visitor->Trace(tag_rules);
-  visitor->Trace(ua_shadow_pseudo_element_rules);
-}
-
 void RuleSet::LayerInterval::Trace(Visitor* visitor) const {
   visitor->Trace(layer);
 }
@@ -921,7 +896,6 @@
   visitor->Trace(property_rules_);
   visitor->Trace(counter_style_rules_);
   visitor->Trace(scroll_timeline_rules_);
-  visitor->Trace(pending_rules_);
   visitor->Trace(implicit_outer_layer_);
   visitor->Trace(layer_intervals_);
 #ifndef NDEBUG
diff --git a/third_party/blink/renderer/core/css/rule_set.h b/third_party/blink/renderer/core/css/rule_set.h
index 05b5e501..c4103d6c 100644
--- a/third_party/blink/renderer/core/css/rule_set.h
+++ b/third_party/blink/renderer/core/css/rule_set.h
@@ -244,20 +244,17 @@
 
   const HeapVector<Member<const RuleData>>* IdRules(
       const AtomicString& key) const {
-    DCHECK(!pending_rules_);
     auto it = id_rules_.find(key);
     return it != id_rules_.end() ? it->value : nullptr;
   }
   const HeapVector<Member<const RuleData>>* ClassRules(
       const AtomicString& key) const {
-    DCHECK(!pending_rules_);
     auto it = class_rules_.find(key);
     return it != class_rules_.end() ? it->value : nullptr;
   }
   bool HasAnyAttrRules() const { return !attr_rules_.IsEmpty(); }
   const HeapVector<Member<const RuleData>>* AttrRules(
       const AtomicString& key) const {
-    DCHECK(!pending_rules_);
     auto it = attr_rules_.find(key);
     return it != attr_rules_.end() ? it->value : nullptr;
   }
@@ -266,61 +263,48 @@
                            const AtomicString& value) const;
   const HeapVector<Member<const RuleData>>* TagRules(
       const AtomicString& key) const {
-    DCHECK(!pending_rules_);
     auto it = tag_rules_.find(key);
     return it != tag_rules_.end() ? it->value : nullptr;
   }
   const HeapVector<Member<const RuleData>>* UAShadowPseudoElementRules(
       const AtomicString& key) const {
-    DCHECK(!pending_rules_);
     auto it = ua_shadow_pseudo_element_rules_.find(key);
     return it != ua_shadow_pseudo_element_rules_.end() ? it->value : nullptr;
   }
   const HeapVector<Member<const RuleData>>* LinkPseudoClassRules() const {
-    DCHECK(!pending_rules_);
     return &link_pseudo_class_rules_;
   }
   const HeapVector<Member<const RuleData>>* CuePseudoRules() const {
-    DCHECK(!pending_rules_);
     return &cue_pseudo_rules_;
   }
   const HeapVector<Member<const RuleData>>* FocusPseudoClassRules() const {
-    DCHECK(!pending_rules_);
     return &focus_pseudo_class_rules_;
   }
   const HeapVector<Member<const RuleData>>* FocusVisiblePseudoClassRules()
       const {
-    DCHECK(!pending_rules_);
     return &focus_visible_pseudo_class_rules_;
   }
   const HeapVector<Member<const RuleData>>*
   SpatialNavigationInterestPseudoClassRules() const {
-    DCHECK(!pending_rules_);
     return &spatial_navigation_interest_class_rules_;
   }
   const HeapVector<Member<const RuleData>>* UniversalRules() const {
-    DCHECK(!pending_rules_);
     return &universal_rules_;
   }
   const HeapVector<Member<const RuleData>>* ShadowHostRules() const {
-    DCHECK(!pending_rules_);
     return &shadow_host_rules_;
   }
   const HeapVector<Member<const RuleData>>* PartPseudoRules() const {
-    DCHECK(!pending_rules_);
     return &part_pseudo_rules_;
   }
   const HeapVector<Member<const RuleData>>* VisitedDependentRules() const {
-    DCHECK(!pending_rules_);
     return &visited_dependent_rules_;
   }
   const HeapVector<Member<const RuleData>>* SelectorFragmentAnchorRules()
       const {
-    DCHECK(!pending_rules_);
     return &selector_fragment_anchor_rules_;
   }
   const HeapVector<Member<StyleRulePage>>& PageRules() const {
-    DCHECK(!pending_rules_);
     return page_rules_;
   }
   const HeapVector<Member<StyleRuleFontFace>>& FontFaceRules() const {
@@ -344,7 +328,6 @@
     return scroll_timeline_rules_;
   }
   const HeapVector<Member<const RuleData>>* SlottedPseudoElementRules() const {
-    DCHECK(!pending_rules_);
     return &slotted_pseudo_element_rules_;
   }
 
@@ -357,9 +340,8 @@
   unsigned RuleCount() const { return rule_count_; }
 
   void CompactRulesIfNeeded() {
-    if (!pending_rules_)
-      return;
-    CompactRules();
+    if (need_compaction_)
+      CompactRules();
   }
 
   bool HasSlottedRules() const {
@@ -403,15 +385,12 @@
   FRIEND_TEST_ALL_PREFIXES(RuleSetTest, RuleCountNotIncreasedByInvalidRuleData);
   friend class RuleSetCascadeLayerTest;
 
-  using PendingRuleMap =
-      HeapHashMap<AtomicString,
-                  Member<HeapLinkedStack<Member<const RuleData>>>>;
-  using CompactRuleMap =
+  using RuleMap =
       HeapHashMap<AtomicString, Member<HeapVector<Member<const RuleData>>>>;
   using SubstringMatcherMap =
       HashMap<AtomicString, std::unique_ptr<base::SubstringSetMatcher>>;
 
-  void AddToRuleSet(const AtomicString& key, PendingRuleMap&, const RuleData*);
+  void AddToRuleSet(const AtomicString& key, RuleMap&, const RuleData*);
   void AddPageRule(StyleRulePage*);
   void AddViewportRule(StyleRuleViewport*);
   void AddFontFaceRule(StyleRuleFontFace*);
@@ -440,30 +419,11 @@
   void SortKeyframesRulesIfNeeded();
 
   void CompactRules();
-  static void CompactPendingRules(PendingRuleMap&, CompactRuleMap&);
+  static void CompactRuleMap(RuleMap&);
   static void CreateSubstringMatchers(
-      CompactRuleMap& attr_map,
+      RuleMap& attr_map,
       SubstringMatcherMap& substring_matcher_map);
 
-  class PendingRuleMaps : public GarbageCollected<PendingRuleMaps> {
-   public:
-    PendingRuleMaps() = default;
-
-    PendingRuleMap id_rules;
-    PendingRuleMap class_rules;
-    PendingRuleMap attr_rules;
-    PendingRuleMap tag_rules;
-    PendingRuleMap ua_shadow_pseudo_element_rules;
-
-    void Trace(Visitor*) const;
-  };
-
-  PendingRuleMaps* EnsurePendingRules() {
-    if (!pending_rules_)
-      pending_rules_ = MakeGarbageCollected<PendingRuleMaps>();
-    return pending_rules_.Get();
-  }
-
 #if DCHECK_IS_ON()
   void AssertRuleListsSorted() const;
 #endif
@@ -481,9 +441,9 @@
   // May return nullptr for the implicit outer layer.
   const CascadeLayer* GetLayerForTest(const RuleData&) const;
 
-  CompactRuleMap id_rules_;
-  CompactRuleMap class_rules_;
-  CompactRuleMap attr_rules_;
+  RuleMap id_rules_;
+  RuleMap class_rules_;
+  RuleMap attr_rules_;
   // A structure for quickly rejecting an entire attribute rule set
   // (from attr_rules_). If we have many rules in the same bucket,
   // we build up a case-insensitive substring-matching structure of all
@@ -506,8 +466,8 @@
   // doing a simple match.) Check GetMinimumRulesetSizeForSubstringMatcher()
   // before looking up for a cheaper test.
   SubstringMatcherMap attr_substring_matchers_;
-  CompactRuleMap tag_rules_;
-  CompactRuleMap ua_shadow_pseudo_element_rules_;
+  RuleMap tag_rules_;
+  RuleMap ua_shadow_pseudo_element_rules_;
   HeapVector<Member<const RuleData>> link_pseudo_class_rules_;
   HeapVector<Member<const RuleData>> cue_pseudo_rules_;
   HeapVector<Member<const RuleData>> focus_pseudo_class_rules_;
@@ -536,7 +496,7 @@
   bool has_bucket_for_style_attr_ = false;
 
   unsigned rule_count_ = 0;
-  Member<PendingRuleMaps> pending_rules_;
+  bool need_compaction_ = false;
 
   // nullptr if the stylesheet doesn't explicitly declare any layer.
   Member<CascadeLayer> implicit_outer_layer_;
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.cc b/third_party/blink/renderer/core/html/forms/html_input_element.cc
index e0f40b15..bb76480b 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.cc
@@ -1181,9 +1181,8 @@
   needs_to_update_view_value_ = false;
 }
 
-void HTMLInputElement::setValue(const String& value,
-                                ExceptionState& exception_state,
-                                TextFieldEventBehavior event_behavior) {
+void HTMLInputElement::setValueForBinding(const String& value,
+                                          ExceptionState& exception_state) {
   // FIXME: Remove type check.
   if (type() == input_type_names::kFile && !value.IsEmpty()) {
     exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
@@ -1192,7 +1191,17 @@
                                       "to the empty string.");
     return;
   }
-  setValue(value, event_behavior);
+
+  if (GetAutofillState() != WebAutofillState::kAutofilled) {
+    setValue(value);
+  } else {
+    String old_value = this->value();
+    setValue(value);
+    if (Page* page = GetDocument().GetPage()) {
+      page->GetChromeClient().JavaScriptChangedAutofilledValue(*this,
+                                                               old_value);
+    }
+  }
 }
 
 void HTMLInputElement::setValue(const String& value,
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.h b/third_party/blink/renderer/core/html/forms/html_input_element.h
index d662e8c..3f41dadd 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.h
@@ -141,13 +141,11 @@
   String value() const override;
   void setValue(
       const String&,
-      ExceptionState&,
-      TextFieldEventBehavior = TextFieldEventBehavior::kDispatchNoEvent);
-  void setValue(
-      const String&,
       TextFieldEventBehavior = TextFieldEventBehavior::kDispatchNoEvent,
       TextControlSetValueSelection =
           TextControlSetValueSelection::kSetSelectionToEnd) override;
+  String valueForBinding() const { return value(); }
+  void setValueForBinding(const String&, ExceptionState&);
   void SetValueForUser(const String&);
   // Update the value, and clear hasDirtyValue() flag.
   void SetNonDirtyValue(const String&);
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.idl b/third_party/blink/renderer/core/html/forms/html_input_element.idl
index 36b3b91..ef1ddd0 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.idl
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.idl
@@ -62,7 +62,7 @@
     [CEReactions, Reflect] attribute DOMString step;
     [CEReactions] attribute DOMString type;
     [CEReactions, Reflect=value] attribute DOMString defaultValue;
-    [CEReactions, RaisesException=Setter] attribute [TreatNullAs=EmptyString] DOMString value;
+    [CEReactions, ImplementedAs=valueForBinding, RaisesException=Setter] attribute [TreatNullAs=EmptyString] DOMString value;
     [CEReactions, RaisesException=Setter, CallWith=ScriptState] attribute object? valueAsDate;
     [RaisesException=Setter] attribute unrestricted double valueAsNumber;
     // Note: The spec has valueLow and valueHigh for two-valued range controls.
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.cc b/third_party/blink/renderer/core/html/forms/html_select_element.cc
index 38c1170..5f87c64 100644
--- a/third_party/blink/renderer/core/html/forms/html_select_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -283,6 +283,19 @@
   return "";
 }
 
+void HTMLSelectElement::setValueForBinding(const String& value) {
+  if (GetAutofillState() != WebAutofillState::kAutofilled) {
+    setValue(value);
+  } else {
+    String old_value = this->value();
+    setValue(value);
+    if (Page* page = GetDocument().GetPage()) {
+      page->GetChromeClient().JavaScriptChangedAutofilledValue(*this,
+                                                               old_value);
+    }
+  }
+}
+
 void HTMLSelectElement::setValue(const String& value, bool send_events) {
   HTMLOptionElement* option = nullptr;
   // Find the option with value() matching the given parameter and make it the
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.h b/third_party/blink/renderer/core/html/forms/html_select_element.h
index d31cc92..a480111 100644
--- a/third_party/blink/renderer/core/html/forms/html_select_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_select_element.h
@@ -94,6 +94,8 @@
 
   String value() const;
   void setValue(const String&, bool send_events = false);
+  String valueForBinding() const { return value(); }
+  void setValueForBinding(const String&);
   String SuggestedValue() const;
   void SetSuggestedValue(const String&);
 
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.idl b/third_party/blink/renderer/core/html/forms/html_select_element.idl
index d5fde8e..8a920f9 100644
--- a/third_party/blink/renderer/core/html/forms/html_select_element.idl
+++ b/third_party/blink/renderer/core/html/forms/html_select_element.idl
@@ -47,7 +47,7 @@
 
     readonly attribute HTMLCollection selectedOptions;
     attribute long selectedIndex;
-    attribute DOMString value;
+    [ImplementedAs=valueForBinding] attribute DOMString value;
 
     readonly attribute boolean willValidate;
     readonly attribute ValidityState validity;
diff --git a/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc b/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc
index c9aa532..0dea95f 100644
--- a/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc
@@ -22,6 +22,8 @@
 #include "third_party/blink/renderer/core/html/html_slot_element.h"
 #include "third_party/blink/renderer/core/html_names.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
+#include "third_party/blink/renderer/core/page/chrome_client.h"
+#include "third_party/blink/renderer/core/page/page.h"
 #include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
 #include "third_party/blink/renderer/platform/keyboard_codes.h"
 #include "third_party/blink/renderer/platform/text/platform_locale.h"
@@ -302,6 +304,19 @@
   return "";
 }
 
+void HTMLSelectMenuElement::setValueForBinding(const String& value) {
+  if (GetAutofillState() != WebAutofillState::kAutofilled) {
+    setValue(value);
+  } else {
+    String old_value = this->value();
+    setValue(value);
+    if (Page* page = GetDocument().GetPage()) {
+      page->GetChromeClient().JavaScriptChangedAutofilledValue(*this,
+                                                               old_value);
+    }
+  }
+}
+
 void HTMLSelectMenuElement::setValue(const String& value, bool send_events) {
   // Find the option with innerText matching the given parameter and make it the
   // current selection.
diff --git a/third_party/blink/renderer/core/html/forms/html_select_menu_element.h b/third_party/blink/renderer/core/html/forms/html_select_menu_element.h
index 69563df..6fab653e 100644
--- a/third_party/blink/renderer/core/html/forms/html_select_menu_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_select_menu_element.h
@@ -36,6 +36,8 @@
   HTMLOptionElement* selectedOption() const;
   String value() const;
   void setValue(const String&, bool send_events = false);
+  String valueForBinding() const { return value(); }
+  void setValueForBinding(const String&);
   bool open() const;
 
   // For ValidityState
diff --git a/third_party/blink/renderer/core/html/forms/html_select_menu_element.idl b/third_party/blink/renderer/core/html/forms/html_select_menu_element.idl
index 5286ed1d..2225e39 100644
--- a/third_party/blink/renderer/core/html/forms/html_select_menu_element.idl
+++ b/third_party/blink/renderer/core/html/forms/html_select_menu_element.idl
@@ -7,7 +7,7 @@
   readonly attribute boolean open;
 
   [SameObject] readonly attribute HTMLOptionElement? selectedOption;
-  attribute DOMString value;
+  [ImplementedAs=valueForBinding] attribute DOMString value;
   // TODO(crbug.com/1121840) Fill this out.
   // Open question: do we want to replicate the interface of
   // <select> as closely as possible?
diff --git a/third_party/blink/renderer/core/html/forms/html_text_area_element.cc b/third_party/blink/renderer/core/html/forms/html_text_area_element.cc
index 779fc2a..e03f4843 100644
--- a/third_party/blink/renderer/core/html/forms/html_text_area_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_text_area_element.cc
@@ -439,6 +439,19 @@
   return value_;
 }
 
+void HTMLTextAreaElement::setValueForBinding(const String& value) {
+  if (GetAutofillState() != WebAutofillState::kAutofilled) {
+    setValue(value);
+  } else {
+    String old_value = this->value();
+    setValue(value);
+    if (Page* page = GetDocument().GetPage()) {
+      page->GetChromeClient().JavaScriptChangedAutofilledValue(*this,
+                                                               old_value);
+    }
+  }
+}
+
 void HTMLTextAreaElement::setValue(const String& value,
                                    TextFieldEventBehavior event_behavior,
                                    TextControlSetValueSelection selection) {
diff --git a/third_party/blink/renderer/core/html/forms/html_text_area_element.h b/third_party/blink/renderer/core/html/forms/html_text_area_element.h
index 2aa3e15..7767b9e 100644
--- a/third_party/blink/renderer/core/html/forms/html_text_area_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_text_area_element.h
@@ -50,6 +50,8 @@
       TextFieldEventBehavior = TextFieldEventBehavior::kDispatchNoEvent,
       TextControlSetValueSelection =
           TextControlSetValueSelection::kSetSelectionToEnd) override;
+  String valueForBinding() const { return value(); }
+  void setValueForBinding(const String&);
   String defaultValue() const;
   void setDefaultValue(const String&);
   int textLength() const { return value().length(); }
diff --git a/third_party/blink/renderer/core/html/forms/html_text_area_element.idl b/third_party/blink/renderer/core/html/forms/html_text_area_element.idl
index 591be34..ef4c28ff 100644
--- a/third_party/blink/renderer/core/html/forms/html_text_area_element.idl
+++ b/third_party/blink/renderer/core/html/forms/html_text_area_element.idl
@@ -40,7 +40,7 @@
 
     readonly attribute DOMString type;
     [CEReactions] attribute DOMString defaultValue;
-    [CEReactions] attribute [TreatNullAs=EmptyString] DOMString value;
+    [CEReactions, ImplementedAs=valueForBinding] attribute [TreatNullAs=EmptyString] DOMString value;
     readonly attribute unsigned long textLength;
 
     readonly attribute boolean willValidate;
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 b1de07f9..0294527 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
@@ -536,8 +536,7 @@
   ResetRewindLoopDetector();
 }
 
-void NGLineBreaker::NextLine(
-    NGLineInfo* line_info) {
+void NGLineBreaker::NextLine(NGLineInfo* line_info) {
   PrepareNextLine(line_info);
   BreakLine(line_info);
   if (UNLIKELY(HasHyphen()))
@@ -578,8 +577,7 @@
   ComputeLineLocation(line_info);
 }
 
-void NGLineBreaker::BreakLine(
-    NGLineInfo* line_info) {
+void NGLineBreaker::BreakLine(NGLineInfo* line_info) {
   DCHECK(!line_info->IsLastLine());
   const HeapVector<NGInlineItem>& items = Items();
   state_ = LineBreakState::kContinue;
@@ -1469,6 +1467,7 @@
 
   unsigned last_safe = source_result->PreviousSafeToBreakOffset(end_offset);
   DCHECK_LE(last_safe, end_offset);
+  // TODO(abotella): Shouldn't last_safe <= start_offset trigger a reshaping?
   if (last_safe == end_offset || last_safe <= start_offset) {
     return ShapeResultView::Create(source_result, start_offset, end_offset);
   }
@@ -1909,9 +1908,8 @@
   MoveToNextOf(item);
 }
 
-void NGLineBreaker::HandleAtomicInline(
-    const NGInlineItem& item,
-    NGLineInfo* line_info) {
+void NGLineBreaker::HandleAtomicInline(const NGInlineItem& item,
+                                       NGLineInfo* line_info) {
   DCHECK_EQ(item.Type(), NGInlineItem::kAtomicInline);
   DCHECK(item.Style());
   const ComputedStyle& style = *item.Style();
diff --git a/third_party/blink/renderer/core/page/chrome_client.h b/third_party/blink/renderer/core/page/chrome_client.h
index 547ebe57..1f0c79f2 100644
--- a/third_party/blink/renderer/core/page/chrome_client.h
+++ b/third_party/blink/renderer/core/page/chrome_client.h
@@ -480,6 +480,10 @@
   virtual void DidChangeSelectionInSelectControl(HTMLFormControlElement&) {}
   virtual void SelectFieldOptionsChanged(HTMLFormControlElement&) {}
   virtual void AjaxSucceeded(LocalFrame*) {}
+  // Called when |element| is in autofilled state and the value has been changed
+  // by JavaScript. |old_value| contains the value before being changed.
+  virtual void JavaScriptChangedAutofilledValue(HTMLFormControlElement&,
+                                                const String& old_value) {}
 
   // Input method editor related functions.
   virtual void ShowVirtualKeyboardOnElementFocus(LocalFrame&) {}
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.cc b/third_party/blink/renderer/core/page/chrome_client_impl.cc
index 8d9c6f4c..b05a0d8 100644
--- a/third_party/blink/renderer/core/page/chrome_client_impl.cc
+++ b/third_party/blink/renderer/core/page/chrome_client_impl.cc
@@ -1213,6 +1213,16 @@
     fill_client->AjaxSucceeded();
 }
 
+void ChromeClientImpl::JavaScriptChangedAutofilledValue(
+    HTMLFormControlElement& element,
+    const String& old_value) {
+  Document& doc = element.GetDocument();
+  if (auto* fill_client = AutofillClientFromFrame(doc.GetFrame())) {
+    fill_client->JavaScriptChangedAutofilledValue(
+        WebFormControlElement(&element), old_value);
+  }
+}
+
 TransformationMatrix ChromeClientImpl::GetDeviceEmulationTransform() const {
   DCHECK(web_view_);
   return web_view_->GetDeviceEmulationTransform();
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.h b/third_party/blink/renderer/core/page/chrome_client_impl.h
index 6796e96..6413b206 100644
--- a/third_party/blink/renderer/core/page/chrome_client_impl.h
+++ b/third_party/blink/renderer/core/page/chrome_client_impl.h
@@ -258,6 +258,8 @@
   void DidChangeSelectionInSelectControl(HTMLFormControlElement&) override;
   void SelectFieldOptionsChanged(HTMLFormControlElement&) override;
   void AjaxSucceeded(LocalFrame*) override;
+  void JavaScriptChangedAutofilledValue(HTMLFormControlElement&,
+                                        const String& old_value) override;
 
   void ShowVirtualKeyboardOnElementFocus(LocalFrame&) override;
 
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl_test.cc b/third_party/blink/renderer/core/page/chrome_client_impl_test.cc
index d09b6b17..2b4085db 100644
--- a/third_party/blink/renderer/core/page/chrome_client_impl_test.cc
+++ b/third_party/blink/renderer/core/page/chrome_client_impl_test.cc
@@ -38,6 +38,7 @@
 #include "third_party/blink/public/mojom/choosers/color_chooser.mojom-blink.h"
 #include "third_party/blink/public/web/web_local_frame.h"
 #include "third_party/blink/public/web/web_local_frame_client.h"
+#include "third_party/blink/public/web/web_testing_support.h"
 #include "third_party/blink/public/web/web_view.h"
 #include "third_party/blink/public/web/web_view_client.h"
 #include "third_party/blink/renderer/core/exported/web_view_impl.h"
@@ -57,6 +58,7 @@
 #include "third_party/blink/renderer/core/loader/frame_load_request.h"
 #include "third_party/blink/renderer/core/page/page.h"
 #include "third_party/blink/renderer/core/page/scoped_page_pauser.h"
+#include "third_party/blink/renderer/core/script/classic_script.h"
 #include "third_party/blink/renderer/core/testing/page_test_base.h"
 #include "third_party/blink/renderer/platform/language.h"
 
@@ -65,6 +67,20 @@
 
 namespace blink {
 
+namespace {
+class FakeChromeClientForAutofill : public EmptyChromeClient {
+ public:
+  void JavaScriptChangedAutofilledValue(HTMLFormControlElement&,
+                                        const String& old_value) override {
+    last_old_value_ = old_value;
+  }
+  const String& last_old_value() const { return last_old_value_; }
+
+ private:
+  String last_old_value_;
+};
+}  // namespace
+
 class ViewCreatingClient : public frame_test_helpers::TestWebViewClient {
  public:
   WebView* CreateView(WebLocalFrame* opener,
@@ -371,4 +387,64 @@
   chooser.ResponseOnOpenFileChooser(FileChooserFileInfoList());
 }
 
+class AutofillChromeClientTest : public PageTestBase {
+ public:
+  void SetUp() override {
+    chrome_client_ = MakeGarbageCollected<FakeChromeClientForAutofill>();
+    SetupPageWithClients(chrome_client_);
+    GetFrame().GetSettings()->SetScriptEnabled(true);
+  }
+
+  void ExecuteScript(const char* script) {
+    ClassicScript::CreateUnspecifiedScript(script)->RunScript(
+        GetFrame().DomWindow());
+  }
+
+  Persistent<FakeChromeClientForAutofill> chrome_client_;
+};
+
+TEST_F(AutofillChromeClientTest, NotificationsOfJavaScriptChanges) {
+  SetHtmlInnerHTML(R"HTML(
+    <!DOCTYPE HTML>
+    <form id='form' method='GET' action='https://internal.test/'
+        target='_blank'>
+      <input id='text' value='old_text'>
+      <textarea id='textarea'>old_textarea</textarea>
+      <select id='select'>
+        <option value='select_a'>a</option>
+        <option value='select_b' selected>b</option>
+      </select>
+      <selectmenu id='selectmenu'>
+        <option value='selectmenu_a'>a</option>
+        <option value='selectmenu_b' selected>b</option>
+      </select>
+      <input id='not_autofilled_text' value='old_text'>
+    </form>
+  )HTML");
+
+  for (const char* id : {"text", "textarea", "select", "selectmenu"}) {
+    To<HTMLFormControlElement>(GetElementById(id))
+        ->SetAutofillState(WebAutofillState::kAutofilled);
+  }
+
+  ExecuteScript("document.getElementById('text').value = 'new_text';");
+  EXPECT_EQ(String("old_text"), chrome_client_->last_old_value());
+
+  ExecuteScript("document.getElementById('textarea').value = 'new_text';");
+  EXPECT_EQ(String("old_textarea"), chrome_client_->last_old_value());
+
+  ExecuteScript("document.getElementById('select').value = 'select_a';");
+  EXPECT_EQ(String("select_b"), chrome_client_->last_old_value());
+
+  ExecuteScript(
+      "document.getElementById('selectmenu').value = 'selectmenu_a';");
+  EXPECT_EQ(String("selectmenu_b"), chrome_client_->last_old_value());
+
+  // Because this is not in state "autofilled", the chrome client is not
+  // informed about the change.
+  ExecuteScript(
+      "document.getElementById('not_autofilled_text').value = 'new_text';");
+  EXPECT_EQ(String("selectmenu_b"), chrome_client_->last_old_value());
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/script/script_loader.cc b/third_party/blink/renderer/core/script/script_loader.cc
index 00d86faf..fc55ee10 100644
--- a/third_party/blink/renderer/core/script/script_loader.cc
+++ b/third_party/blink/renderer/core/script/script_loader.cc
@@ -202,10 +202,6 @@
     // attribute.</spec>
     if (MIMETypeRegistry::IsSupportedJavaScriptMIMEType("text/" + language))
       return true;
-
-    // Not spec'ed.
-    if (MIMETypeRegistry::IsLegacySupportedJavaScriptLanguage(language))
-      return true;
   } else if (type.IsEmpty()) {
     // <spec step="8">the script element has a type attribute and its value is
     // the empty string, or</spec>
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.cc b/third_party/blink/renderer/modules/webgpu/gpu_device.cc
index d327e06..c0c7f60 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_device.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_device.cc
@@ -104,6 +104,7 @@
 }
 
 GPUDevice::~GPUDevice() {
+  DestroyAllExternalTextures();
   // Clear the callbacks since we can't handle callbacks after finalization.
   // error_callback_, logging_callback_, and lost_callback_ will be deleted.
   GetProcs().deviceSetUncapturedErrorCallback(GetHandle(), nullptr, nullptr);
@@ -276,6 +277,8 @@
 }
 
 void GPUDevice::destroy() {
+  destroyed_ = true;
+  DestroyAllExternalTextures();
   GetProcs().deviceDestroy(GetHandle());
   FlushNow();
 }
@@ -305,10 +308,18 @@
 GPUExternalTexture* GPUDevice::importExternalTexture(
     const GPUExternalTextureDescriptor* descriptor,
     ExceptionState& exception_state) {
+  // Ensure the GPUExternalTexture created from a destroyed GPUDevice will be
+  // expired immediately.
+  if (destroyed_)
+    return GPUExternalTexture::CreateExpired(this, descriptor, exception_state);
+
   GPUExternalTexture* externalTexture =
       GPUExternalTexture::Create(this, descriptor, exception_state);
-  if (externalTexture)
+
+  // No need to manage expired GPUExternalTexture in GPUDevice.
+  if (externalTexture && !externalTexture->expired()) {
     EnsureExternalTextureDestroyed(externalTexture);
+  }
   return externalTexture;
 }
 
@@ -485,16 +496,20 @@
   DCHECK(externalTexture);
   external_textures_pending_destroy_.push_back(externalTexture);
 
-  if (has_pending_microtask_)
+  if (has_destroy_external_texture_microtask_)
     return;
 
   Microtask::EnqueueMicrotask(WTF::Bind(
       &GPUDevice::DestroyExternalTexturesMicrotask, WrapWeakPersistent(this)));
-  has_pending_microtask_ = true;
+  has_destroy_external_texture_microtask_ = true;
 }
 
 void GPUDevice::DestroyExternalTexturesMicrotask() {
-  has_pending_microtask_ = false;
+  // GPUDevice.destroy() call has destroyed all pending external textures.
+  if (!has_destroy_external_texture_microtask_)
+    return;
+
+  has_destroy_external_texture_microtask_ = false;
 
   auto externalTextures = std::move(external_textures_pending_destroy_);
   for (Member<GPUExternalTexture> externalTexture : externalTextures) {
@@ -502,4 +517,15 @@
   }
 }
 
+void GPUDevice::DestroyAllExternalTextures() {
+  has_destroy_external_texture_microtask_ = false;
+
+  auto externalTexturesPendingDestroy =
+      std::move(external_textures_pending_destroy_);
+  for (Member<GPUExternalTexture> externalTexture :
+       externalTexturesPendingDestroy) {
+    externalTexture->Destroy();
+  }
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.h b/third_party/blink/renderer/modules/webgpu/gpu_device.h
index 89cf0c7..023d48b 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_device.h
+++ b/third_party/blink/renderer/modules/webgpu/gpu_device.h
@@ -137,14 +137,15 @@
   void InjectError(WGPUErrorType type, const char* message);
   void AddConsoleWarning(const char* message);
 
-  void EnsureExternalTextureDestroyed(GPUExternalTexture* externalTexture);
-
  private:
   using LostProperty =
       ScriptPromiseProperty<Member<GPUDeviceLostInfo>, ToV8UndefinedGenerator>;
 
+  void EnsureExternalTextureDestroyed(GPUExternalTexture* externalTexture);
   void DestroyExternalTexturesMicrotask();
 
+  void DestroyAllExternalTextures();
+
   void OnUncapturedError(WGPUErrorType errorType, const char* message);
   void OnLogging(WGPULoggingType loggingType, const char* message);
   void OnDeviceLostError(WGPUDeviceLostReason, const char* message);
@@ -188,8 +189,11 @@
   static constexpr int kMaxAllowedConsoleWarnings = 500;
   int allowed_console_warnings_remaining_ = kMaxAllowedConsoleWarnings;
 
-  bool has_pending_microtask_ = false;
+  bool has_destroy_external_texture_microtask_ = false;
   HeapVector<Member<GPUExternalTexture>> external_textures_pending_destroy_;
+
+  // This attribute records that whether GPUDevice is destroyed (via destroy()).
+  bool destroyed_ = false;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_external_texture.cc b/third_party/blink/renderer/modules/webgpu/gpu_external_texture.cc
index 6af881c3..949cf90 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_external_texture.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_external_texture.cc
@@ -103,6 +103,85 @@
   dstTransferConstants[5] = dst_transfer_fn.e;
   dstTransferConstants[6] = dst_transfer_fn.f;
 }
+
+struct ExternalTextureSource {
+  scoped_refptr<media::VideoFrame> media_video_frame = nullptr;
+  media::PaintCanvasVideoRenderer* video_renderer = nullptr;
+  bool valid = false;
+};
+
+ExternalTextureSource GetExternalTextureSource(
+    GPUDevice* deivce,
+    const GPUExternalTextureDescriptor* webgpu_desc,
+    ExceptionState& exception_state) {
+  ExternalTextureSource source;
+  switch (webgpu_desc->source()->GetContentType()) {
+    case V8UnionHTMLVideoElementOrVideoFrame::ContentType::kHTMLVideoElement: {
+      HTMLVideoElement* video = webgpu_desc->source()->GetAsHTMLVideoElement();
+      if (!video) {
+        exception_state.ThrowDOMException(DOMExceptionCode::kOperationError,
+                                          "Missing video source");
+        return source;
+      }
+
+      if (video->WouldTaintOrigin()) {
+        exception_state.ThrowSecurityError(
+            "Video element is tainted by cross-origin data and may not be "
+            "loaded.");
+        return source;
+      }
+
+      if (auto* wmp = video->GetWebMediaPlayer()) {
+        source.media_video_frame = wmp->GetCurrentFrame();
+        source.video_renderer = wmp->GetPaintCanvasVideoRenderer();
+      }
+
+      if (!source.media_video_frame) {
+        exception_state.ThrowDOMException(DOMExceptionCode::kOperationError,
+                                          "Failed to import texture from video "
+                                          "element that doesn't have back "
+                                          "resource.");
+        return source;
+      }
+
+      break;
+    }
+
+    case V8UnionHTMLVideoElementOrVideoFrame::ContentType::kVideoFrame: {
+      VideoFrame* frame = webgpu_desc->source()->GetAsVideoFrame();
+
+      if (!frame) {
+        exception_state.ThrowDOMException(DOMExceptionCode::kOperationError,
+                                          "Missing video frame");
+        return source;
+      }
+      // Tainted blink::VideoFrames are not supposed to be possible.
+      DCHECK(!frame->WouldTaintOrigin());
+
+      source.media_video_frame = frame->frame();
+      if (!source.media_video_frame) {
+        exception_state.ThrowDOMException(
+            DOMExceptionCode::kOperationError,
+            "Failed to import texture from video "
+            "frame that doesn't have back resource");
+        return source;
+      }
+
+      if (!source.media_video_frame->coded_size().width() ||
+          !source.media_video_frame->coded_size().height()) {
+        exception_state.ThrowDOMException(
+            DOMExceptionCode::kOperationError,
+            "Cannot import from zero sized video frame");
+        return source;
+      }
+      break;
+    }
+  }
+
+  source.valid = true;
+  return source;
+}
+
 }  // namespace
 
 // static
@@ -110,87 +189,34 @@
     GPUDevice* device,
     const GPUExternalTextureDescriptor* webgpu_desc,
     ExceptionState& exception_state) {
-  scoped_refptr<media::VideoFrame> media_video_frame;
-  media::PaintCanvasVideoRenderer* video_renderer = nullptr;
-  switch (webgpu_desc->source()->GetContentType()) {
-    case V8UnionHTMLVideoElementOrVideoFrame::ContentType::kHTMLVideoElement: {
-      HTMLVideoElement* video = webgpu_desc->source()->GetAsHTMLVideoElement();
-
-      if (!video || !video->videoWidth() || !video->videoHeight()) {
-        exception_state.ThrowDOMException(DOMExceptionCode::kOperationError,
-                                          "Missing video source");
-        return nullptr;
-      }
-
-      if (video->WouldTaintOrigin()) {
-        exception_state.ThrowSecurityError(
-            "Video element is tainted by cross-origin data and may not be "
-            "loaded.");
-        return nullptr;
-      }
-
-      if (auto* wmp = video->GetWebMediaPlayer()) {
-        media_video_frame = wmp->GetCurrentFrame();
-        video_renderer = wmp->GetPaintCanvasVideoRenderer();
-      }
-      break;
-    }
-
-    case V8UnionHTMLVideoElementOrVideoFrame::ContentType::kVideoFrame: {
-      VideoFrame* frame = webgpu_desc->source()->GetAsVideoFrame();
-
-      if (!frame || !frame->codedWidth() || !frame->codedHeight()) {
-        exception_state.ThrowDOMException(DOMExceptionCode::kOperationError,
-                                          "Missing video source");
-        return nullptr;
-      }
-
-      if (frame->WouldTaintOrigin()) {
-        exception_state.ThrowSecurityError(
-            "VideoFrame is tainted by cross-origin data and may not be "
-            "loaded.");
-        return nullptr;
-      }
-
-      media_video_frame = frame->frame();
-      break;
-    }
-  }
-
-  if (!media_video_frame) {
-    exception_state.ThrowDOMException(DOMExceptionCode::kOperationError,
-                                      "Failed to import texture from video");
-    if (!media_video_frame) {
-      device->AddConsoleWarning(
-          "Cannot get valid video frame, maybe the"
-          "HTMLVideoElement is not loaded");
-    }
-
+  ExternalTextureSource source =
+      GetExternalTextureSource(device, webgpu_desc, exception_state);
+  if (!source.valid)
     return nullptr;
-  }
 
-  gfx::ColorSpace srcColorSpace = media_video_frame->ColorSpace();
+  gfx::ColorSpace srcColorSpace = source.media_video_frame->ColorSpace();
   gfx::ColorSpace dstColorSpace;
   switch (webgpu_desc->colorSpace().AsEnum()) {
     case V8GPUPredefinedColorSpace::Enum::kSRGB:
       dstColorSpace = gfx::ColorSpace::CreateSRGB();
   }
 
+  DCHECK(source.media_video_frame);
   // TODO(crbug.com/1306753): Use SharedImageProducer and CompositeSharedImage
   // rather than check 'is_webgpu_compatible'.
   bool device_support_zero_copy =
       device->adapter()->features()->FeatureNameSet().Contains(
           "multi-planar-formats");
 
-  if (media_video_frame->HasTextures() &&
-      (media_video_frame->format() == media::PIXEL_FORMAT_NV12) &&
+  if (source.media_video_frame->HasTextures() &&
+      (source.media_video_frame->format() == media::PIXEL_FORMAT_NV12) &&
       device_support_zero_copy &&
-      media_video_frame->metadata().is_webgpu_compatible) {
+      source.media_video_frame->metadata().is_webgpu_compatible) {
     scoped_refptr<WebGPUMailboxTexture> mailbox_texture =
         WebGPUMailboxTexture::FromVideoFrame(
             device->GetDawnControlClient(), device->GetHandle(),
             WGPUTextureUsage::WGPUTextureUsage_TextureBinding,
-            media_video_frame);
+            source.media_video_frame);
 
     WGPUTextureViewDescriptor view_desc = {
         .format = WGPUTextureFormat_R8Unorm,
@@ -210,7 +236,7 @@
     external_texture_desc.colorSpace = AsDawnEnum(webgpu_desc->colorSpace());
 
     float yuvToRgbMatrix[12];
-    GetYUVToRGBMatrix(srcColorSpace, media_video_frame->BitDepth(),
+    GetYUVToRGBMatrix(srcColorSpace, source.media_video_frame->BitDepth(),
                       yuvToRgbMatrix);
     external_texture_desc.yuvToRgbConversionMatrix = yuvToRgbMatrix;
 
@@ -247,7 +273,7 @@
       context_provider_wrapper->ContextProvider()->IsContextLost())
     return nullptr;
 
-  const auto intrinsic_size = media_video_frame->natural_size();
+  const auto intrinsic_size = source.media_video_frame->natural_size();
 
   // Get a recyclable resource for producing WebGPU-compatible shared images.
   std::unique_ptr<RecyclableCanvasResource> recyclable_canvas_resource =
@@ -276,10 +302,10 @@
   // DrawVideoFrameIntoResourceProvider() creates local_video_renderer always.
   // This might affect performance, maybe a cache local_video_renderer could
   // help.
-  const auto dest_rect = gfx::Rect(media_video_frame->natural_size());
+  const auto dest_rect = gfx::Rect(source.media_video_frame->natural_size());
   if (!DrawVideoFrameIntoResourceProvider(
-          std::move(media_video_frame), resource_provider,
-          raster_context_provider, dest_rect, video_renderer)) {
+          std::move(source.media_video_frame), resource_provider,
+          raster_context_provider, dest_rect, source.video_renderer)) {
     exception_state.ThrowDOMException(DOMExceptionCode::kOperationError,
                                       "Failed to import texture from video");
     return nullptr;
@@ -327,6 +353,24 @@
   return external_texture;
 }
 
+// static
+GPUExternalTexture* GPUExternalTexture::CreateExpired(
+    GPUDevice* device,
+    const GPUExternalTextureDescriptor* webgpu_desc,
+    ExceptionState& exception_state) {
+  // Validate GPUExternalTextureDescriptor.
+  ExternalTextureSource source =
+      GetExternalTextureSource(device, webgpu_desc, exception_state);
+  if (!source.valid)
+    return nullptr;
+
+  // Bypass importing video frame into Dawn.
+  GPUExternalTexture* external_texture =
+      MakeGarbageCollected<GPUExternalTexture>(device, nullptr, nullptr);
+  external_texture->Destroy();
+  return external_texture;
+}
+
 GPUExternalTexture::GPUExternalTexture(
     GPUDevice* device,
     WGPUExternalTexture external_texture,
@@ -335,11 +379,12 @@
       mailbox_texture_(mailbox_texture) {}
 
 void GPUExternalTexture::Destroy() {
-  WGPUTexture texture = mailbox_texture_->GetTexture();
-  GetProcs().textureReference(texture);
+  expired_ = true;
+  if (!mailbox_texture_)
+    return;
+
+  GetProcs().textureDestroy(mailbox_texture_->GetTexture());
   mailbox_texture_.reset();
-  GetProcs().textureDestroy(texture);
-  GetProcs().textureRelease(texture);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_external_texture.h b/third_party/blink/renderer/modules/webgpu/gpu_external_texture.h
index e559cd1..a5c31ee0 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_external_texture.h
+++ b/third_party/blink/renderer/modules/webgpu/gpu_external_texture.h
@@ -22,6 +22,10 @@
       GPUDevice* device,
       const GPUExternalTextureDescriptor* webgpu_desc,
       ExceptionState& exception_state);
+  static GPUExternalTexture* CreateExpired(
+      GPUDevice* device,
+      const GPUExternalTextureDescriptor* webgpu_desc,
+      ExceptionState& exception_state);
   explicit GPUExternalTexture(
       GPUDevice* device,
       WGPUExternalTexture external_texture,
@@ -32,6 +36,8 @@
 
   void Destroy();
 
+  bool expired() const { return expired_; }
+
  private:
   void setLabelImpl(const String& value) override {
     std::string utf8_label = value.Utf8();
@@ -39,6 +45,9 @@
   }
 
   scoped_refptr<WebGPUMailboxTexture> mailbox_texture_;
+
+  // This attribute marks whether GPUExternalTexture will be destroyed.
+  bool expired_ = false;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_external_texture.idl b/third_party/blink/renderer/modules/webgpu/gpu_external_texture.idl
index 33262786..ba5570ed 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_external_texture.idl
+++ b/third_party/blink/renderer/modules/webgpu/gpu_external_texture.idl
@@ -8,5 +8,6 @@
     Exposed(Window WebGPU, DedicatedWorker WebGPU),
     SecureContext
 ] interface GPUExternalTexture {
+    readonly attribute boolean expired;
 };
 GPUExternalTexture includes GPUObjectBase;
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc b/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc
index 427bca02..dfca9c1 100644
--- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc
+++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.cc
@@ -472,7 +472,7 @@
 unsigned ShapeResultView::PreviousSafeToBreakOffset(unsigned index) const {
   for (auto it = RunsOrParts().rbegin(); it != RunsOrParts().rend(); ++it) {
     const auto& part = *it;
-    unsigned run_start = part.start_index_;
+    unsigned run_start = part.start_index_ + char_index_offset_;
     if (index >= run_start) {
       unsigned offset = index - run_start;
       if (offset <= part.num_characters_) {
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_result_view_test.cc b/third_party/blink/renderer/platform/fonts/shaping/shape_result_view_test.cc
index 81113f5..04ecc04 100644
--- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_view_test.cc
+++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_view_test.cc
@@ -468,4 +468,24 @@
   EXPECT_EQ(view2->NumGlyphs(), 1u);
 }
 
+// https://crbug.com/1304876
+// In a text containing only Latin characters and without ligatures (or where
+// ligatures are not close to the end of the view), PreviousSafeToBreakOffset in
+// some cases used to return the length of the view, rather than a position into
+// the view.
+TEST_F(ShapeResultViewTest, PreviousSafeOffsetInsideView) {
+  HarfBuzzShaper shaper("Blah bla test something. ");
+  scoped_refptr<const ShapeResult> result =
+      shaper.Shape(&font, TextDirection::kLtr);
+
+  // Used to be 14 - 9 = 5, which is before the start of the view.
+  auto view1 = ShapeResultView::Create(result.get(), 9, 14);
+  EXPECT_EQ(view1->PreviousSafeToBreakOffset(14), 14u);
+
+  // Used to be 25 - 9 = 16, which is inside the view's range, but not the last
+  // safe offset.
+  auto view2 = ShapeResultView::Create(result.get(), 9, 25);
+  EXPECT_EQ(view2->PreviousSafeToBreakOffset(24), 24u);
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource.cc b/third_party/blink/renderer/platform/loader/fetch/resource.cc
index ac88afb8..bd4e64a 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource.cc
@@ -1164,11 +1164,13 @@
   switch (type_) {
     case ResourceType::kImage:
     case ResourceType::kCSSStyleSheet:
-    case ResourceType::kScript:
     case ResourceType::kFont:
     case ResourceType::kSVGDocument:
     case ResourceType::kXSLStyleSheet:
       return true;
+    case ResourceType::kScript:
+      // <script> elements delay the load event in core/script (e.g. in
+      // ScriptRunner) and no longer need the delaying in platform/loader side.
     case ResourceType::kRaw:
     case ResourceType::kLinkPrefetch:
     case ResourceType::kTextTrack:
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 556454f..6f5210d 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -3188,7 +3188,6 @@
 crbug.com/626703 virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https.html [ Failure ]
 crbug.com/626703 external/wpt/preload/preload-resource-match.https.html [ Failure ]
 crbug.com/626703 virtual/prerender/external/wpt/speculation-rules/prerender/workers.html [ Failure ]
-crbug.com/626703 [ Win ] external/wpt/preload/avoid-delaying-onload-link-modulepreload.html [ Failure ]
 crbug.com/626703 [ Win ] virtual/prerender/external/wpt/speculation-rules/prerender/restriction-presentation-request.https.html [ Failure ]
 crbug.com/626703 [ Win ] virtual/prerender/external/wpt/speculation-rules/prerender/storage-foundation.https.html [ Failure ]
 crbug.com/626703 [ Win ] virtual/partitioned-cookies/http/tests/inspector-protocol/network/disabled-cache-navigation.js [ Failure ]
diff --git a/third_party/blink/web_tests/animations/svg/stroke-width-zoom-factor.html b/third_party/blink/web_tests/animations/svg/stroke-width-zoom-factor.html
index aaeb4a3..1168859 100644
--- a/third_party/blink/web_tests/animations/svg/stroke-width-zoom-factor.html
+++ b/third_party/blink/web_tests/animations/svg/stroke-width-zoom-factor.html
@@ -3,12 +3,17 @@
 <title>Make sure stroke-width is zoom agnostic when animating</title>
 <script src="../../resources/testharness.js"></script>
 <script src="../../resources/testharnessreport.js"></script>
+<script src="../../resources/ahem.js"></script>
 
 <div id="target"></div>
 
 <script>
 test(t => {
-  // Setting the zoom factor should not change the value of strokeWidth.
+  t.add_cleanup(() => {
+    if (window.testRunner)
+      testRunner.setPageZoomFactor(1);
+  });
+
   if (window.testRunner)
     testRunner.setPageZoomFactor(5);
 
@@ -21,5 +26,28 @@
 
   anim.currentTime = 500;
   assert_equals(getComputedStyle(target).strokeWidth, '12.5px');
-});
+}, 'Zoom does not affect strokeWidth animation (px)');
+
+promise_test(async t => {
+  t.add_cleanup(() => {
+    target.style = '';
+  });
+  target.style.fontFamily = 'Ahem';
+  target.style.fontSize = '20px';
+
+  await document.fonts.ready;
+
+  if (window.testRunner)
+    testRunner.setPageZoomFactor(5);
+
+  const anim = target.animate([
+    { strokeWidth: '1ex' }, // 16px
+    { strokeWidth: '2ex' }, // 32px
+  ], {
+    duration: 1000,
+  });
+
+  anim.currentTime = 500;
+  assert_equals(getComputedStyle(target).strokeWidth, '24px');
+}, 'Zoom does not affect strokeWidth animation (ex)');
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_lig-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_lig-001-ref.html
new file mode 100644
index 0000000..df71a1d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_lig-001-ref.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: test for Chromium bug 1304876</title>
+<style type="text/css">
+@font-face {
+    font-family: GentiumPlus;
+    src: url('/fonts/GentiumPlus-R.woff') format('woff');
+    font-weight: normal;
+    font-style: normal;
+}
+.test {
+    font-family: GentiumPlus;
+    font-size: 18pt;
+    width: 300px;
+    border: 1px solid black;
+    margin: 1em;
+}
+.line {
+    display: block;
+    white-space: nowrap;
+}
+/* the CSS above is not part of the test */
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the word "office" is rendered without repeated letters.</p>
+<div class="test">
+    <div class="line">Sanitary measures in the</div>
+    <div class="line">office ought be adequately</div>
+    <div class="line"><b>maintained</b>.</div>
+</div>
+<div class="test">
+    <div class="line">Sanitary measures in the</div>
+    <div class="line">office ought be adequately</div>
+    <div class="line"><b>maintained</b>.</div>
+</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_lig-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_lig-001.html
new file mode 100644
index 0000000..059b8df
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_lig-001.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: test for Chromium bug 1304876</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1304876">
+<link rel="match" href="reference/shaping_lig-001-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: GentiumPlus;
+    src: url('/fonts/GentiumPlus-R.woff') format('woff');
+    font-weight: normal;
+    font-style: normal;
+}
+.test {
+    font-family: GentiumPlus;
+    font-size: 18pt;
+    width: 300px;
+    border: 1px solid black;
+    margin: 1em;
+}
+/* the CSS above is not part of the test */
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the word "office" is rendered without repeated letters.</p>
+<div class="test">Sanitary measures in the office ought be adequately <b>maintained</b>.</div>
+<div class="test">Sanitary measures in the<br>office ought be adequately <b>maintained</b>.</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/fast/html/script-allowed-types-languages.html b/third_party/blink/web_tests/fast/html/script-allowed-types-languages.html
deleted file mode 100644
index 3ee958e..0000000
--- a/third_party/blink/web_tests/fast/html/script-allowed-types-languages.html
+++ /dev/null
@@ -1,123 +0,0 @@
-<script>
-function log(msg)
-{
-    document.getElementById('log').appendChild(document.createTextNode(msg + '\n'));
-}
-
-function appendChildText(node, text)
-{
-    if (node.canHaveChildren == null || node.canHaveChildren) {
-        node.appendChild(document.createTextNode(text));
-    } else {
-        // IE doesn't allow script nodes to have children. We must use the
-        // .text property instead.
-        node.text = text;
-    }
-}
-
-function createScriptElement(type, language)
-{
-    var script = document.createElement('script');
-
-    var typeStr;
-    if (type == null) {
-        typeStr = 'unspecified';
-    } else {
-        typeStr = '\\"' + type + '\\"';
-        script.setAttribute('type', type);
-    }
-
-    var languageStr;
-    if (language == null) {
-        languageStr = 'unspecified';
-    } else {
-        languageStr = '\\"' + language + '\\"';
-        script.setAttribute('language', language);
-    }
-
-    var text = 'log("Type: ' + typeStr + ', Language: ' + languageStr + '");';
-    appendChildText(script, text);
-
-    return script;
-}
-
-function test()
-{
-    if (window.testRunner)
-        testRunner.dumpAsText();
-
-    var types = [
-        null,
-        "",
-        "text/javascript",
-        "text/ecmascript",
-        "text/x-javascript",
-        "text/x-ecmascript",
-        "application/javascript",
-        "application/ecmascript",
-        "application/x-javascript",
-        "application/x-ecmascript",
-        "text/javascript1.0",
-        "text/javascript1.1",
-        "text/javascript1.2",
-        "text/javascript1.3",
-        "text/javascript1.4",
-        "text/javascript1.5",
-        "text/javascript1.6",
-        "text/javascript1.7",
-        "text/javascript1.8",
-        "text/javascript1.9",
-        "text/jscript",
-        "text/livescript",
-        "text/x-ebayScript",
-        "  text/javascript",
-        "text/javascript  ",
-        "  text/javascript  ",
-        "    ",
-        "abcdefg"
-    ];
-
-    var languages = [
-        "",
-        "javascript",
-        "javascript1.0",
-        "javascript1.1",
-        "javascript1.2",
-        "javascript1.3",
-        "javascript1.4",
-        "javascript1.5",
-        "javascript1.6",
-        "javascript1.7",
-        "javascript1.8",
-        "javascript1.9",
-        "ecmascript",
-        "livescript",
-        "jscript",
-        "ebayScript",
-        "    ",
-        "  javascript",
-        "javascript  ",
-        "  javascript  ",
-        "abcdefg"
-    ];
-
-    for (var i = 0; i < types.length; ++i)
-        document.body.appendChild(createScriptElement(types[i], null));
-
-    for (var i = 0; i < languages.length; ++i)
-        document.body.appendChild(createScriptElement(null, languages[i]));
-
-    for (var i = 0; i < languages.length; ++i)
-        document.body.appendChild(createScriptElement("", languages[i]));
-
-    log('When a type is specified, the language attribute should be ignored.');
-    for (var i = 0; i < languages.length; ++i)
-        document.body.appendChild(createScriptElement("text/javascript", languages[i]));
-}
-</script>
-<body onload="test();">
-    <p>This page tests the allowed values for the type and language attributes
-    of the &lt;script&gt; tag. Below you will see the allowed values.</p>
-
-    <pre id="log"></pre>
-</body>
diff --git a/third_party/blink/web_tests/fast/tokenizer/004.html b/third_party/blink/web_tests/fast/tokenizer/004.html
deleted file mode 100644
index f405f0f..0000000
--- a/third_party/blink/web_tests/fast/tokenizer/004.html
+++ /dev/null
@@ -1,187 +0,0 @@
-<html>
-<script>
-    if (window.testRunner)
-        testRunner.dumpAsText();
-</script>
-<body>
-<h3>Variations on type attribute of script tag</h3>
-<h4>These scripts should execute</h4>
-<ol>
-    <li>no type attribute <script>document.write("executed");</script></li>
-    <li>empty string <script type="">document.write("executed");</script></li>
-    <li>text/javascript <script type="text/javascript">document.write("executed");</script></li>
-    <li>text/JAVASCRIPT <script type="text/JAVASCRIPT">document.write("executed");</script></li>
-    <li>TEXT/JAVASCRIPT <script type="TEXT/JAVASCRIPT">document.write("executed");</script></li>
-    <li>'text/javascript ' <script type="text/javascript ">document.write("executed");</script></li>
-    <li>' text/javascript ' <script type=" text/javascript ">document.write("executed");</script></li>
-    <li>text/jscript <script type="text/jscript">document.write("executed");</script></li>
-    <li>text/ecmascript <script type="text/ecmascript">document.write("executed");</script></li>
-    <li>text/livescript <script type="text/livescript">document.write("executed");</script></li>
-    <li>text/javascript1.0 <script type="text/javascript1.0">document.write("executed");</script></li>
-    <li>text/javascript1.1 <script type="text/javascript1.1">document.write("executed");</script></li>
-    <li>text/javascript1.2 <script type="text/javascript1.2">document.write("executed");</script></li>
-    <li>text/javascript1.3 <script type="text/javascript1.3">document.write("executed");</script></li>
-    <li>text/javascript1.4 <script type="text/javascript1.4">document.write("executed");</script></li>
-    <li>text/javascript1.5 <script type="text/javascript1.5">document.write("executed");</script></li>
-    <li>text/x-javascript <script type="text/x-javascript">document.write("executed");</script></li>
-    <li>text/x-ecmascript <script type="text/x-ecmascript">document.write("executed");</script></li>
-    <li>application/javascript <script type="application/javascript">document.write("executed");</script></li>
-    <li>application/ecmascript <script type="application/ecmascript">document.write("executed");</script></li>
-    <li>application/x-javascript <script type="application/x-javascript">document.write("executed");</script></li>
-    <li>application/x-ecmascript <script type="application/x-ecmascript">document.write("executed");</script></li>
-</ol>
-<h4>These scripts should not execute</h4>
-<ol>
-    <li>one space <script type=" ">document.write("executed");</script></li>
-    <li>text/ <script type="text/">document.write("executed");</script></li>
-    <li>text/vbscript <script type="text/vbscript">document.write("executed");</script></li>
-    <li>text/vbs <script type="text/vbs">document.write("executed");</script></li>
-    <li>text/xml <script type="text/xml">document.write("executed");</script></li>
-    <li>text/javascript1 <script type="text/javascript1">document.write("executed");</script></li>
-    <li>text/javascript1.6 <script type="text/javascript1.6">document.write("executed");</script></li>
-    <li>application/jscript <script type="application/jscript">document.write("executed");</script></li>
-    <li>application/x-jscript <script type="application/x-jscript">document.write("executed");</script></li>
-    <li>application/livescript <script type="application/livescript">document.write("executed");</script></li>
-    <li>application/x-livescript <script type="application/x-livescript">document.write("executed");</script></li>
-    <li>application/javascript1.2 <script type="application/javascript1.2">document.write("executed");</script></li>
-    <li>application/x-javascript1.2 <script type="application/x-javascript1.2">document.write("executed");</script></li>
-    <li>javascript <script type="javascript">document.write("executed");</script></li>
-    <li>jscript <script type="jscript">document.write("executed");</script></li>
-    <li>ecmascript <script type="ecmascript">document.write("executed");</script></li>
-    <li>livescript <script type="livescript">document.write("executed");</script></li>
-    <li>livescript1.1 <script type="livescript1.1">document.write("executed");</script></li>
-    <li>JAVASCRIPT <script type="JAVASCRIPT">document.write("executed");</script></li>
-    <li>JavaScript <script type="JavaScript">document.write("executed");</script></li>
-    <li>JavaScript 1 <script type="JavaScript 1">document.write("executed");</script></li>
-    <li>JavaScript 1.0 <script type="JavaScript 1.0">document.write("executed");</script></li>
-    <li>JavaScript 1.1 <script type="JavaScript 1.1">document.write("executed");</script></li>
-    <li>JavaScript 1.1.1 <script type="JavaScript 1.1.1">document.write("executed");</script></li>
-    <li>JavaScript 1.2 <script type="JavaScript 1.2">document.write("executed");</script></li>
-    <li>JavaScript 1.3 <script type="JavaScript 1.3">document.write("executed");</script></li>
-    <li>JavaScript 1.4 <script type="JavaScript 1.4">document.write("executed");</script></li>
-    <li>JavaScript 1.5 <script type="JavaScript 1.5">document.write("executed");</script></li>
-    <li>JavaScript 1.6 <script type="JavaScript 1.6">document.write("executed");</script></li>
-    <li>JavaScript 1.7 <script type="JavaScript 1.7">document.write("executed");</script></li>
-    <li>JavaScript 1.8 <script type="JavaScript 1.8">document.write("executed");</script></li>
-    <li>JavaScript 1.9 <script type="JavaScript 1.9">document.write("executed");</script></li>
-    <li>JavaScript 2 <script type="JavaScript 2">document.write("executed");</script></li>
-    <li>JavaScript 2.1 <script type="JavaScript 2.1">document.write("executed");</script></li>
-    <li>JavaScript 10 <script type="JavaScript 10">document.write("executed");</script></li>
-    <li>JavaScript 10.0 <script type="JavaScript 10.0">document.write("executed");</script></li>
-    <li>_javascript <script type="_javascript">document.write("executed");</script></li>
-    <li>javascript_ <script type="javascript_">document.write("executed");</script></li>
-    <li>javascript_1.0 <script type="javascript_1.0">document.write("executed");</script></li>
-    <li>javascript 1.0 x <script type="javascript 1.0 x">document.write("executed");</script></li>
-    <li>JavaScript1 <script type="JavaScript1">document.write("executed");</script></li>
-    <li>JavaScript1.0 <script type="JavaScript1.0">document.write("executed");</script></li>
-    <li>JavaScript1.1 <script type="JavaScript1.1">document.write("executed");</script></li>
-    <li>JavaScript1.2 <script type="JavaScript1.2">document.write("executed");</script></li>
-    <li>JavaScript1.3 <script type="JavaScript1.3">document.write("executed");</script></li>
-    <li>JavaScript1.4 <script type="JavaScript1.4">document.write("executed");</script></li>
-    <li>JavaScript1.4.1 <script type="JavaScript1.4.1">document.write("executed");</script></li>
-    <li>JavaScript1.5 <script type="JavaScript1.5">document.write("executed");</script></li>
-    <li>JavaScript1.6 <script type="JavaScript1.6">document.write("executed");</script></li>
-    <li>JavaScript1.7 <script type="JavaScript1.7">document.write("executed");</script></li>
-    <li>1.0 javascript <script type="1.0 javascript">document.write("executed");</script></li>
-    <li>' javascript ' <script type=" javascript ">document.write("executed");</script></li>
-    <li>' javascript1.1 ' <script type=" javascript1.1 ">document.write("executed");</script></li>
-    <li>'&nbsp;&nbsp;&nbsp;javascript&nbsp;&nbsp;&nbsp;' <script type="   javascript   ">document.write("executed");</script></li>
-    <li>' javascript 1.0 ' <script type=" javascript 1.0 ">document.write("executed");</script></li>
-    <li>' javascript&nbsp;&nbsp;1.0 ' <script type=" javascript  1.0 ">document.write("executed");</script></li>
-    <li>jscript 1 <script type="jscript 1">document.write("executed");</script></li>
-    <li>jscript 1.0 <script type="jscript 1.0">document.write("executed");</script></li>
-    <li>ecmascript 1 <script type="ecmascript 1">document.write("executed");</script></li>
-    <li>ecmascript 1.0 <script type="ecmascript 1.0">document.write("executed");</script></li>
-    <li>livescript 1 <script type="livescript 1">document.write("executed");</script></li>
-    <li>livescript 1.0 <script type="livescript 1.0">document.write("executed");</script></li>
-    <li>' jscript&nbsp;&nbsp;1.0 ' <script type=" jscript  1.0 ">document.write("executed");</script></li>
-    <li>disabled_javascript <script type="disabled_javascript">document.write("executed");</script></li>
-    <li>xxxjavascriptxxx <script type="xxxjavascriptxxx">document.write("executed");</script></li>
-    <li>bogus <script type="bogus">document.write("executed");</script></li>
-</ol>
-
-<h3>Variations on language attribute of script tag</h3>
-<h4>These scripts should execute</h4>
-<ol>
-    <li>no language attribute <script>document.write("executed");</script></li>
-    <li>empty string <script language="">document.write("executed");</script></li>
-    <li>jscript <script language="jscript">document.write("executed");</script></li>
-    <li>ecmascript <script language="ecmascript">document.write("executed");</script></li>
-    <li>livescript <script language="livescript">document.write("executed");</script></li>
-    <li>javascript <script language="javascript">document.write("executed");</script></li>
-    <li>JAVASCRIPT <script language="JAVASCRIPT">document.write("executed");</script></li>
-    <li>JavaScript <script language="JavaScript">document.write("executed");</script></li>
-    <li>JavaScript1.0 <script language="JavaScript1.0">document.write("executed");</script></li>
-    <li>JavaScript1.1 <script language="JavaScript1.1">document.write("executed");</script></li>
-    <li>JavaScript1.2 <script language="JavaScript1.2">document.write("executed");</script></li>
-    <li>JavaScript1.3 <script language="JavaScript1.3">document.write("executed");</script></li>
-    <li>JavaScript1.4 <script language="JavaScript1.4">document.write("executed");</script></li>
-    <li>JavaScript1.5 <script language="JavaScript1.5">document.write("executed");</script></li>
-    <li>JavaScript1.6 <script language="JavaScript1.6">document.write("executed");</script></li>
-    <li>JavaScript1.7 <script language="JavaScript1.7">document.write("executed");</script></li>
-</ol>
-<h4>These scripts should not execute</h4>
-<ol>
-    <li>one space <script language=" ">document.write("executed");</script></li>
-    <li>vbscript <script language="vbscript">document.write("executed");</script></li>
-    <li>livescript1.1 <script language="livescript1.1">document.write("executed");</script></li>
-    <li>JavaScript 1 <script language="JavaScript 1">document.write("executed");</script></li>
-    <li>JavaScript 1.0 <script language="JavaScript 1.0">document.write("executed");</script></li>
-    <li>JavaScript 1.1 <script language="JavaScript 1.1">document.write("executed");</script></li>
-    <li>JavaScript 1.1.1 <script language="JavaScript 1.1.1">document.write("executed");</script></li>
-    <li>JavaScript 1.2 <script language="JavaScript 1.2">document.write("executed");</script></li>
-    <li>JavaScript 1.3 <script language="JavaScript 1.3">document.write("executed");</script></li>
-    <li>JavaScript 1.4 <script language="JavaScript 1.4">document.write("executed");</script></li>
-    <li>JavaScript 1.5 <script language="JavaScript 1.5">document.write("executed");</script></li>
-    <li>JavaScript 1.6 <script language="JavaScript 1.6">document.write("executed");</script></li>
-    <li>JavaScript 1.7 <script language="JavaScript 1.7">document.write("executed");</script></li>
-    <li>JavaScript 1.8 <script language="JavaScript 1.8">document.write("executed");</script></li>
-    <li>JavaScript 1.9 <script language="JavaScript 1.9">document.write("executed");</script></li>
-    <li>JavaScript 2 <script language="JavaScript 2">document.write("executed");</script></li>
-    <li>JavaScript 2.1 <script language="JavaScript 2.1">document.write("executed");</script></li>
-    <li>JavaScript 10 <script language="JavaScript 10">document.write("executed");</script></li>
-    <li>JavaScript 10.0 <script language="JavaScript 10.0">document.write("executed");</script></li>
-    <li>_javascript <script language="_javascript">document.write("executed");</script></li>
-    <li>javascript_ <script language="javascript_">document.write("executed");</script></li>
-    <li>javascript_1.0 <script language="javascript_1.0">document.write("executed");</script></li>
-    <li>javascript 1.0 x <script language="javascript 1.0 x">document.write("executed");</script></li>
-    <li>JavaScript1 <script language="JavaScript1">document.write("executed");</script></li>
-    <li>JavaScript1.8 <script language="JavaScript1.8">document.write("executed");</script></li>
-    <li>JavaScript1.9 <script language="JavaScript1.9">document.write("executed");</script></li>
-    <li>JavaScript1.4.1 <script language="JavaScript1.4.1">document.write("executed");</script></li>
-    <li>1.0 javascript <script language="1.0 javascript">document.write("executed");</script></li>
-    <li>' javascript ' <script language=" javascript ">document.write("executed");</script></li>
-    <li>' javascript1.1 ' <script language=" javascript1.1 ">document.write("executed");</script></li>
-    <li>'&nbsp;&nbsp;&nbsp;javascript&nbsp;&nbsp;&nbsp;' <script language="   javascript   ">document.write("executed");</script></li>
-    <li>' javascript 1.0 ' <script language=" javascript 1.0 ">document.write("executed");</script></li>
-    <li>' javascript&nbsp;&nbsp;1.0 ' <script language=" javascript  1.0 ">document.write("executed");</script></li>
-    <li>jscript 1 <script language="jscript 1">document.write("executed");</script></li>
-    <li>jscript 1.0 <script language="jscript 1.0">document.write("executed");</script></li>
-    <li>ecmascript 1 <script language="ecmascript 1">document.write("executed");</script></li>
-    <li>ecmascript 1.0 <script language="ecmascript 1.0">document.write("executed");</script></li>
-    <li>livescript 1 <script language="livescript 1">document.write("executed");</script></li>
-    <li>livescript 1.0 <script language="livescript 1.0">document.write("executed");</script></li>
-    <li>' jscript&nbsp;&nbsp;1.0 ' <script language=" jscript  1.0 ">document.write("executed");</script></li>
-    <li>disabled_javascript <script language="disabled_javascript">document.write("executed");</script></li>
-    <li>xxxjavascriptxxx <script language="xxxjavascriptxxx">document.write("executed");</script></li>
-    <li>bogus <script language="bogus">document.write("executed");</script></li>
-</ol>
-
-<h3>Variations on combined type and language attributes of script tag</h3>
-<h4>These scripts should execute</h4>
-<ol>
-    <li>empty string type, "javascript" language <script type="" language="javascript">document.write("executed");</script></li>
-    <li>empty string language, "text/javascript" type <script type="text/javascript" language="">document.write("executed");</script></li>
-    <li>"javascript" language, "text/javascript" type <script type="text/javascript" language="javascript">document.write("executed");</script></li>
-    <li>"bogus" language, "text/javascript" type <script type="text/javascript" language="bogus">document.write("executed");</script></li>
-    <li>"livescript" language, "text/javascript" type <script type="text/javascript" language="livescript">document.write("executed");</script></li>
-    <li>"javascript1.2" language, "text/javascript" type <script type="text/javascript" language="javascript1.2">document.write("executed");</script></li>
-    <li>empty string type, "bogus" language <script type="" language="bogus">document.write("executed");</script></li>
-</ol>
-<h4>These scripts should not execute</h4>
-<ol>
-    <li>"javascript" language, "bogus" type <script type="bogus" language="javascript">document.write("executed");</script></li>
-    <li>empty string language, "bogus" type <script type="bogus" language="">document.write("executed");</script></li>
-</ol>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/fenced-frame/setWebLifecycleState-fenced-frame.https.js b/third_party/blink/web_tests/http/tests/inspector-protocol/fenced-frame/setWebLifecycleState-fenced-frame.https.js
new file mode 100644
index 0000000..3ad1545
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/fenced-frame/setWebLifecycleState-fenced-frame.https.js
@@ -0,0 +1,26 @@
+(async function(testRunner) {
+  const {session, dp} = await testRunner.startURL(
+      'resources/page-with-fenced-frame.php',
+      'Tests that Page.setWebLifecycleState() in a fenced frame is not allowed.');
+  await dp.Page.enable();
+  await dp.Runtime.enable();
+
+  dp.Target.setAutoAttach(
+      {autoAttach: true, waitForDebuggerOnStart: false, flatten: true});
+  let {sessionId} = (await dp.Target.onceAttachedToTarget()).params;
+
+  let childSession = session.createChild(sessionId);
+  let ffdp = childSession.protocol;
+
+  // Wait for FF to finish loading.
+  await ffdp.Page.enable();
+  ffdp.Page.setLifecycleEventsEnabled({enabled: true});
+  await ffdp.Page.onceLifecycleEvent(event => event.params.name === 'load');
+
+  // setWebLifecycleState() in a fenced frame gets an error.
+  const result = await ffdp.Page.setWebLifecycleState({state: 'frozen'});
+  testRunner.log(
+      'Page.setWebLifecycleState() from a fenced frame:\n' +
+      (result.error ? 'PASS: ' + result.error.message : 'FAIL: no error'));
+  testRunner.completeTest();
+})
\ No newline at end of file
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/html/semantics/scripting-1/the-script-element/script-type-and-language-js-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/html/semantics/scripting-1/the-script-element/script-type-and-language-js-expected.txt
deleted file mode 100644
index 43acb10..0000000
--- a/third_party/blink/web_tests/platform/generic/external/wpt/html/semantics/scripting-1/the-script-element/script-type-and-language-js-expected.txt
+++ /dev/null
@@ -1,460 +0,0 @@
-This is a testharness.js-based test.
-Found 456 tests; 454 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS Script should run with type=""
-PASS Script shouldn't run with type=" "
-PASS Script should run with type="application/ecmascript"
-PASS Script should run with type="application/javascript"
-PASS Script should run with type="application/x-ecmascript"
-PASS Script should run with type="application/x-javascript"
-PASS Script should run with type="APPLICATION/ECMASCRIPT"
-PASS Script should run with type="APPLICATION/JAVASCRIPT"
-PASS Script should run with type="APPLICATION/X-ECMASCRIPT"
-PASS Script should run with type="APPLICATION/X-JAVASCRIPT"
-PASS Script should run with type="application/ecmascript "
-PASS Script should run with type="application/javascript "
-PASS Script should run with type="application/x-ecmascript "
-PASS Script should run with type="application/x-javascript "
-PASS Script should run with type=" application/ecmascript"
-PASS Script should run with type=" application/javascript"
-PASS Script should run with type=" application/x-ecmascript"
-PASS Script should run with type=" application/x-javascript"
-PASS Script should run with type="application/ecmascript\t"
-PASS Script should run with type="application/javascript\t"
-PASS Script should run with type="application/x-ecmascript\t"
-PASS Script should run with type="application/x-javascript\t"
-PASS Script should run with type="\tapplication/ecmascript"
-PASS Script should run with type="\tapplication/javascript"
-PASS Script should run with type="\tapplication/x-ecmascript"
-PASS Script should run with type="\tapplication/x-javascript"
-PASS Script should run with type="application/ecmascript\n"
-PASS Script should run with type="application/javascript\n"
-PASS Script should run with type="application/x-ecmascript\n"
-PASS Script should run with type="application/x-javascript\n"
-PASS Script should run with type="\napplication/ecmascript"
-PASS Script should run with type="\napplication/javascript"
-PASS Script should run with type="\napplication/x-ecmascript"
-PASS Script should run with type="\napplication/x-javascript"
-PASS Script should run with type="application/ecmascript\r"
-PASS Script should run with type="application/javascript\r"
-PASS Script should run with type="application/x-ecmascript\r"
-PASS Script should run with type="application/x-javascript\r"
-PASS Script should run with type="\rapplication/ecmascript"
-PASS Script should run with type="\rapplication/javascript"
-PASS Script should run with type="\rapplication/x-ecmascript"
-PASS Script should run with type="\rapplication/x-javascript"
-PASS Script should run with type="application/ecmascript\f"
-PASS Script should run with type="application/javascript\f"
-PASS Script should run with type="application/x-ecmascript\f"
-PASS Script should run with type="application/x-javascript\f"
-PASS Script should run with type="\fapplication/ecmascript"
-PASS Script should run with type="\fapplication/javascript"
-PASS Script should run with type="\fapplication/x-ecmascript"
-PASS Script should run with type="\fapplication/x-javascript"
-PASS Script shouldn't run with type="application/ecmascript\0"
-PASS Script shouldn't run with type="application/javascript\0"
-PASS Script shouldn't run with type="application/x-ecmascript\0"
-PASS Script shouldn't run with type="application/x-javascript\0"
-PASS Script shouldn't run with type="application/ecmascript\0foo"
-PASS Script shouldn't run with type="application/javascript\0foo"
-PASS Script shouldn't run with type="application/x-ecmascript\0foo"
-PASS Script shouldn't run with type="application/x-javascript\0foo"
-PASS Script should run with type="text/ecmascript"
-PASS Script should run with type="text/javascript"
-PASS Script should run with type="text/javascript1.0"
-PASS Script should run with type="text/javascript1.1"
-PASS Script should run with type="text/javascript1.2"
-PASS Script should run with type="text/javascript1.3"
-PASS Script should run with type="text/javascript1.4"
-PASS Script should run with type="text/javascript1.5"
-PASS Script should run with type="text/jscript"
-PASS Script should run with type="text/livescript"
-PASS Script should run with type="text/x-ecmascript"
-PASS Script should run with type="text/x-javascript"
-PASS Script should run with type="TEXT/ECMASCRIPT"
-PASS Script should run with type="TEXT/JAVASCRIPT"
-PASS Script should run with type="TEXT/JAVASCRIPT1.0"
-PASS Script should run with type="TEXT/JAVASCRIPT1.1"
-PASS Script should run with type="TEXT/JAVASCRIPT1.2"
-PASS Script should run with type="TEXT/JAVASCRIPT1.3"
-PASS Script should run with type="TEXT/JAVASCRIPT1.4"
-PASS Script should run with type="TEXT/JAVASCRIPT1.5"
-PASS Script should run with type="TEXT/JSCRIPT"
-PASS Script should run with type="TEXT/LIVESCRIPT"
-PASS Script should run with type="TEXT/X-ECMASCRIPT"
-PASS Script should run with type="TEXT/X-JAVASCRIPT"
-PASS Script shouldn't run with type="text/javascript1.6"
-PASS Script shouldn't run with type="text/javascript1.7"
-PASS Script shouldn't run with type="text/javascript1.8"
-PASS Script shouldn't run with type="text/javascript1.9"
-PASS Script should run with type="text/ecmascript "
-PASS Script should run with type="text/javascript "
-PASS Script should run with type="text/javascript1.0 "
-PASS Script should run with type="text/javascript1.1 "
-PASS Script should run with type="text/javascript1.2 "
-PASS Script should run with type="text/javascript1.3 "
-PASS Script should run with type="text/javascript1.4 "
-PASS Script should run with type="text/javascript1.5 "
-PASS Script should run with type="text/jscript "
-PASS Script should run with type="text/livescript "
-PASS Script should run with type="text/x-ecmascript "
-PASS Script should run with type="text/x-javascript "
-PASS Script should run with type=" text/ecmascript"
-PASS Script should run with type=" text/javascript"
-PASS Script should run with type=" text/javascript1.0"
-PASS Script should run with type=" text/javascript1.1"
-PASS Script should run with type=" text/javascript1.2"
-PASS Script should run with type=" text/javascript1.3"
-PASS Script should run with type=" text/javascript1.4"
-PASS Script should run with type=" text/javascript1.5"
-PASS Script should run with type=" text/jscript"
-PASS Script should run with type=" text/livescript"
-PASS Script should run with type=" text/x-ecmascript"
-PASS Script should run with type=" text/x-javascript"
-PASS Script should run with type="text/ecmascript\t"
-PASS Script should run with type="text/javascript\t"
-PASS Script should run with type="text/javascript1.0\t"
-PASS Script should run with type="text/javascript1.1\t"
-PASS Script should run with type="text/javascript1.2\t"
-PASS Script should run with type="text/javascript1.3\t"
-PASS Script should run with type="text/javascript1.4\t"
-PASS Script should run with type="text/javascript1.5\t"
-PASS Script should run with type="text/jscript\t"
-PASS Script should run with type="text/livescript\t"
-PASS Script should run with type="text/x-ecmascript\t"
-PASS Script should run with type="text/x-javascript\t"
-PASS Script should run with type="\ttext/ecmascript"
-PASS Script should run with type="\ttext/javascript"
-PASS Script should run with type="\ttext/javascript1.0"
-PASS Script should run with type="\ttext/javascript1.1"
-PASS Script should run with type="\ttext/javascript1.2"
-PASS Script should run with type="\ttext/javascript1.3"
-PASS Script should run with type="\ttext/javascript1.4"
-PASS Script should run with type="\ttext/javascript1.5"
-PASS Script should run with type="\ttext/jscript"
-PASS Script should run with type="\ttext/livescript"
-PASS Script should run with type="\ttext/x-ecmascript"
-PASS Script should run with type="\ttext/x-javascript"
-PASS Script should run with type="text/ecmascript\n"
-PASS Script should run with type="text/javascript\n"
-PASS Script should run with type="text/javascript1.0\n"
-PASS Script should run with type="text/javascript1.1\n"
-PASS Script should run with type="text/javascript1.2\n"
-PASS Script should run with type="text/javascript1.3\n"
-PASS Script should run with type="text/javascript1.4\n"
-PASS Script should run with type="text/javascript1.5\n"
-PASS Script should run with type="text/jscript\n"
-PASS Script should run with type="text/livescript\n"
-PASS Script should run with type="text/x-ecmascript\n"
-PASS Script should run with type="text/x-javascript\n"
-PASS Script should run with type="\ntext/ecmascript"
-PASS Script should run with type="\ntext/javascript"
-PASS Script should run with type="\ntext/javascript1.0"
-PASS Script should run with type="\ntext/javascript1.1"
-PASS Script should run with type="\ntext/javascript1.2"
-PASS Script should run with type="\ntext/javascript1.3"
-PASS Script should run with type="\ntext/javascript1.4"
-PASS Script should run with type="\ntext/javascript1.5"
-PASS Script should run with type="\ntext/jscript"
-PASS Script should run with type="\ntext/livescript"
-PASS Script should run with type="\ntext/x-ecmascript"
-PASS Script should run with type="\ntext/x-javascript"
-PASS Script should run with type="text/ecmascript\r"
-PASS Script should run with type="text/javascript\r"
-PASS Script should run with type="text/javascript1.0\r"
-PASS Script should run with type="text/javascript1.1\r"
-PASS Script should run with type="text/javascript1.2\r"
-PASS Script should run with type="text/javascript1.3\r"
-PASS Script should run with type="text/javascript1.4\r"
-PASS Script should run with type="text/javascript1.5\r"
-PASS Script should run with type="text/jscript\r"
-PASS Script should run with type="text/livescript\r"
-PASS Script should run with type="text/x-ecmascript\r"
-PASS Script should run with type="text/x-javascript\r"
-PASS Script should run with type="\rtext/ecmascript"
-PASS Script should run with type="\rtext/javascript"
-PASS Script should run with type="\rtext/javascript1.0"
-PASS Script should run with type="\rtext/javascript1.1"
-PASS Script should run with type="\rtext/javascript1.2"
-PASS Script should run with type="\rtext/javascript1.3"
-PASS Script should run with type="\rtext/javascript1.4"
-PASS Script should run with type="\rtext/javascript1.5"
-PASS Script should run with type="\rtext/jscript"
-PASS Script should run with type="\rtext/livescript"
-PASS Script should run with type="\rtext/x-ecmascript"
-PASS Script should run with type="\rtext/x-javascript"
-PASS Script should run with type="text/ecmascript\f"
-PASS Script should run with type="text/javascript\f"
-PASS Script should run with type="text/javascript1.0\f"
-PASS Script should run with type="text/javascript1.1\f"
-PASS Script should run with type="text/javascript1.2\f"
-PASS Script should run with type="text/javascript1.3\f"
-PASS Script should run with type="text/javascript1.4\f"
-PASS Script should run with type="text/javascript1.5\f"
-PASS Script should run with type="text/jscript\f"
-PASS Script should run with type="text/livescript\f"
-PASS Script should run with type="text/x-ecmascript\f"
-PASS Script should run with type="text/x-javascript\f"
-PASS Script should run with type="\ftext/ecmascript"
-PASS Script should run with type="\ftext/javascript"
-PASS Script should run with type="\ftext/javascript1.0"
-PASS Script should run with type="\ftext/javascript1.1"
-PASS Script should run with type="\ftext/javascript1.2"
-PASS Script should run with type="\ftext/javascript1.3"
-PASS Script should run with type="\ftext/javascript1.4"
-PASS Script should run with type="\ftext/javascript1.5"
-PASS Script should run with type="\ftext/jscript"
-PASS Script should run with type="\ftext/livescript"
-PASS Script should run with type="\ftext/x-ecmascript"
-PASS Script should run with type="\ftext/x-javascript"
-PASS Script shouldn't run with type="text/ecmascript\0"
-PASS Script shouldn't run with type="text/javascript\0"
-PASS Script shouldn't run with type="text/javascript1.0\0"
-PASS Script shouldn't run with type="text/javascript1.1\0"
-PASS Script shouldn't run with type="text/javascript1.2\0"
-PASS Script shouldn't run with type="text/javascript1.3\0"
-PASS Script shouldn't run with type="text/javascript1.4\0"
-PASS Script shouldn't run with type="text/javascript1.5\0"
-PASS Script shouldn't run with type="text/jscript\0"
-PASS Script shouldn't run with type="text/livescript\0"
-PASS Script shouldn't run with type="text/x-ecmascript\0"
-PASS Script shouldn't run with type="text/x-javascript\0"
-PASS Script shouldn't run with type="text/ecmascript\0foo"
-PASS Script shouldn't run with type="text/javascript\0foo"
-PASS Script shouldn't run with type="text/javascript1.0\0foo"
-PASS Script shouldn't run with type="text/javascript1.1\0foo"
-PASS Script shouldn't run with type="text/javascript1.2\0foo"
-PASS Script shouldn't run with type="text/javascript1.3\0foo"
-PASS Script shouldn't run with type="text/javascript1.4\0foo"
-PASS Script shouldn't run with type="text/javascript1.5\0foo"
-PASS Script shouldn't run with type="text/jscript\0foo"
-PASS Script shouldn't run with type="text/livescript\0foo"
-PASS Script shouldn't run with type="text/x-ecmascript\0foo"
-PASS Script shouldn't run with type="text/x-javascript\0foo"
-PASS Script shouldn't run with type="ecmascript"
-PASS Script shouldn't run with type="javascript"
-PASS Script shouldn't run with type="javascript1.0"
-PASS Script shouldn't run with type="javascript1.1"
-PASS Script shouldn't run with type="javascript1.2"
-PASS Script shouldn't run with type="javascript1.3"
-PASS Script shouldn't run with type="javascript1.4"
-PASS Script shouldn't run with type="javascript1.5"
-PASS Script shouldn't run with type="jscript"
-PASS Script shouldn't run with type="livescript"
-PASS Script shouldn't run with type="x-ecmascript"
-PASS Script shouldn't run with type="x-javascript"
-PASS Script shouldn't run with type="javascript1.6"
-PASS Script shouldn't run with type="javascript1.7"
-PASS Script shouldn't run with type="javascript1.8"
-PASS Script shouldn't run with type="javascript1.9"
-PASS Script should run with language=""
-PASS Script shouldn't run with language=" "
-PASS Script should run with language="ecmascript"
-PASS Script should run with language="javascript"
-PASS Script should run with language="javascript1.0"
-PASS Script should run with language="javascript1.1"
-PASS Script should run with language="javascript1.2"
-PASS Script should run with language="javascript1.3"
-PASS Script should run with language="javascript1.4"
-PASS Script should run with language="javascript1.5"
-PASS Script should run with language="jscript"
-PASS Script should run with language="livescript"
-PASS Script should run with language="x-ecmascript"
-PASS Script should run with language="x-javascript"
-PASS Script should run with language="ECMASCRIPT"
-PASS Script should run with language="JAVASCRIPT"
-PASS Script should run with language="JAVASCRIPT1.0"
-PASS Script should run with language="JAVASCRIPT1.1"
-PASS Script should run with language="JAVASCRIPT1.2"
-PASS Script should run with language="JAVASCRIPT1.3"
-PASS Script should run with language="JAVASCRIPT1.4"
-PASS Script should run with language="JAVASCRIPT1.5"
-PASS Script should run with language="JSCRIPT"
-PASS Script should run with language="LIVESCRIPT"
-PASS Script should run with language="X-ECMASCRIPT"
-PASS Script should run with language="X-JAVASCRIPT"
-FAIL Script shouldn't run with language="javascript1.6" assert_equals: expected false but got true
-FAIL Script shouldn't run with language="javascript1.7" assert_equals: expected false but got true
-PASS Script shouldn't run with language="javascript1.8"
-PASS Script shouldn't run with language="javascript1.9"
-PASS Script shouldn't run with language="ecmascript "
-PASS Script shouldn't run with language="javascript "
-PASS Script shouldn't run with language="javascript1.0 "
-PASS Script shouldn't run with language="javascript1.1 "
-PASS Script shouldn't run with language="javascript1.2 "
-PASS Script shouldn't run with language="javascript1.3 "
-PASS Script shouldn't run with language="javascript1.4 "
-PASS Script shouldn't run with language="javascript1.5 "
-PASS Script shouldn't run with language="jscript "
-PASS Script shouldn't run with language="livescript "
-PASS Script shouldn't run with language="x-ecmascript "
-PASS Script shouldn't run with language="x-javascript "
-PASS Script shouldn't run with language=" ecmascript"
-PASS Script shouldn't run with language=" javascript"
-PASS Script shouldn't run with language=" javascript1.0"
-PASS Script shouldn't run with language=" javascript1.1"
-PASS Script shouldn't run with language=" javascript1.2"
-PASS Script shouldn't run with language=" javascript1.3"
-PASS Script shouldn't run with language=" javascript1.4"
-PASS Script shouldn't run with language=" javascript1.5"
-PASS Script shouldn't run with language=" jscript"
-PASS Script shouldn't run with language=" livescript"
-PASS Script shouldn't run with language=" x-ecmascript"
-PASS Script shouldn't run with language=" x-javascript"
-PASS Script shouldn't run with language="ecmascript\t"
-PASS Script shouldn't run with language="javascript\t"
-PASS Script shouldn't run with language="javascript1.0\t"
-PASS Script shouldn't run with language="javascript1.1\t"
-PASS Script shouldn't run with language="javascript1.2\t"
-PASS Script shouldn't run with language="javascript1.3\t"
-PASS Script shouldn't run with language="javascript1.4\t"
-PASS Script shouldn't run with language="javascript1.5\t"
-PASS Script shouldn't run with language="jscript\t"
-PASS Script shouldn't run with language="livescript\t"
-PASS Script shouldn't run with language="x-ecmascript\t"
-PASS Script shouldn't run with language="x-javascript\t"
-PASS Script shouldn't run with language="\tecmascript"
-PASS Script shouldn't run with language="\tjavascript"
-PASS Script shouldn't run with language="\tjavascript1.0"
-PASS Script shouldn't run with language="\tjavascript1.1"
-PASS Script shouldn't run with language="\tjavascript1.2"
-PASS Script shouldn't run with language="\tjavascript1.3"
-PASS Script shouldn't run with language="\tjavascript1.4"
-PASS Script shouldn't run with language="\tjavascript1.5"
-PASS Script shouldn't run with language="\tjscript"
-PASS Script shouldn't run with language="\tlivescript"
-PASS Script shouldn't run with language="\tx-ecmascript"
-PASS Script shouldn't run with language="\tx-javascript"
-PASS Script shouldn't run with language="ecmascript\n"
-PASS Script shouldn't run with language="javascript\n"
-PASS Script shouldn't run with language="javascript1.0\n"
-PASS Script shouldn't run with language="javascript1.1\n"
-PASS Script shouldn't run with language="javascript1.2\n"
-PASS Script shouldn't run with language="javascript1.3\n"
-PASS Script shouldn't run with language="javascript1.4\n"
-PASS Script shouldn't run with language="javascript1.5\n"
-PASS Script shouldn't run with language="jscript\n"
-PASS Script shouldn't run with language="livescript\n"
-PASS Script shouldn't run with language="x-ecmascript\n"
-PASS Script shouldn't run with language="x-javascript\n"
-PASS Script shouldn't run with language="\necmascript"
-PASS Script shouldn't run with language="\njavascript"
-PASS Script shouldn't run with language="\njavascript1.0"
-PASS Script shouldn't run with language="\njavascript1.1"
-PASS Script shouldn't run with language="\njavascript1.2"
-PASS Script shouldn't run with language="\njavascript1.3"
-PASS Script shouldn't run with language="\njavascript1.4"
-PASS Script shouldn't run with language="\njavascript1.5"
-PASS Script shouldn't run with language="\njscript"
-PASS Script shouldn't run with language="\nlivescript"
-PASS Script shouldn't run with language="\nx-ecmascript"
-PASS Script shouldn't run with language="\nx-javascript"
-PASS Script shouldn't run with language="ecmascript\r"
-PASS Script shouldn't run with language="javascript\r"
-PASS Script shouldn't run with language="javascript1.0\r"
-PASS Script shouldn't run with language="javascript1.1\r"
-PASS Script shouldn't run with language="javascript1.2\r"
-PASS Script shouldn't run with language="javascript1.3\r"
-PASS Script shouldn't run with language="javascript1.4\r"
-PASS Script shouldn't run with language="javascript1.5\r"
-PASS Script shouldn't run with language="jscript\r"
-PASS Script shouldn't run with language="livescript\r"
-PASS Script shouldn't run with language="x-ecmascript\r"
-PASS Script shouldn't run with language="x-javascript\r"
-PASS Script shouldn't run with language="\recmascript"
-PASS Script shouldn't run with language="\rjavascript"
-PASS Script shouldn't run with language="\rjavascript1.0"
-PASS Script shouldn't run with language="\rjavascript1.1"
-PASS Script shouldn't run with language="\rjavascript1.2"
-PASS Script shouldn't run with language="\rjavascript1.3"
-PASS Script shouldn't run with language="\rjavascript1.4"
-PASS Script shouldn't run with language="\rjavascript1.5"
-PASS Script shouldn't run with language="\rjscript"
-PASS Script shouldn't run with language="\rlivescript"
-PASS Script shouldn't run with language="\rx-ecmascript"
-PASS Script shouldn't run with language="\rx-javascript"
-PASS Script shouldn't run with language="ecmascript\f"
-PASS Script shouldn't run with language="javascript\f"
-PASS Script shouldn't run with language="javascript1.0\f"
-PASS Script shouldn't run with language="javascript1.1\f"
-PASS Script shouldn't run with language="javascript1.2\f"
-PASS Script shouldn't run with language="javascript1.3\f"
-PASS Script shouldn't run with language="javascript1.4\f"
-PASS Script shouldn't run with language="javascript1.5\f"
-PASS Script shouldn't run with language="jscript\f"
-PASS Script shouldn't run with language="livescript\f"
-PASS Script shouldn't run with language="x-ecmascript\f"
-PASS Script shouldn't run with language="x-javascript\f"
-PASS Script shouldn't run with language="\fecmascript"
-PASS Script shouldn't run with language="\fjavascript"
-PASS Script shouldn't run with language="\fjavascript1.0"
-PASS Script shouldn't run with language="\fjavascript1.1"
-PASS Script shouldn't run with language="\fjavascript1.2"
-PASS Script shouldn't run with language="\fjavascript1.3"
-PASS Script shouldn't run with language="\fjavascript1.4"
-PASS Script shouldn't run with language="\fjavascript1.5"
-PASS Script shouldn't run with language="\fjscript"
-PASS Script shouldn't run with language="\flivescript"
-PASS Script shouldn't run with language="\fx-ecmascript"
-PASS Script shouldn't run with language="\fx-javascript"
-PASS Script shouldn't run with language="ecmascriptxyz"
-PASS Script shouldn't run with language="javascriptxyz"
-PASS Script shouldn't run with language="javascript1.0xyz"
-PASS Script shouldn't run with language="javascript1.1xyz"
-PASS Script shouldn't run with language="javascript1.2xyz"
-PASS Script shouldn't run with language="javascript1.3xyz"
-PASS Script shouldn't run with language="javascript1.4xyz"
-PASS Script shouldn't run with language="javascript1.5xyz"
-PASS Script shouldn't run with language="jscriptxyz"
-PASS Script shouldn't run with language="livescriptxyz"
-PASS Script shouldn't run with language="x-ecmascriptxyz"
-PASS Script shouldn't run with language="x-javascriptxyz"
-PASS Script shouldn't run with language="xyzecmascript"
-PASS Script shouldn't run with language="xyzjavascript"
-PASS Script shouldn't run with language="xyzjavascript1.0"
-PASS Script shouldn't run with language="xyzjavascript1.1"
-PASS Script shouldn't run with language="xyzjavascript1.2"
-PASS Script shouldn't run with language="xyzjavascript1.3"
-PASS Script shouldn't run with language="xyzjavascript1.4"
-PASS Script shouldn't run with language="xyzjavascript1.5"
-PASS Script shouldn't run with language="xyzjscript"
-PASS Script shouldn't run with language="xyzlivescript"
-PASS Script shouldn't run with language="xyzx-ecmascript"
-PASS Script shouldn't run with language="xyzx-javascript"
-PASS Script shouldn't run with language="ecmascript\0"
-PASS Script shouldn't run with language="javascript\0"
-PASS Script shouldn't run with language="javascript1.0\0"
-PASS Script shouldn't run with language="javascript1.1\0"
-PASS Script shouldn't run with language="javascript1.2\0"
-PASS Script shouldn't run with language="javascript1.3\0"
-PASS Script shouldn't run with language="javascript1.4\0"
-PASS Script shouldn't run with language="javascript1.5\0"
-PASS Script shouldn't run with language="jscript\0"
-PASS Script shouldn't run with language="livescript\0"
-PASS Script shouldn't run with language="x-ecmascript\0"
-PASS Script shouldn't run with language="x-javascript\0"
-PASS Script shouldn't run with language="ecmascript\0foo"
-PASS Script shouldn't run with language="javascript\0foo"
-PASS Script shouldn't run with language="javascript1.0\0foo"
-PASS Script shouldn't run with language="javascript1.1\0foo"
-PASS Script shouldn't run with language="javascript1.2\0foo"
-PASS Script shouldn't run with language="javascript1.3\0foo"
-PASS Script shouldn't run with language="javascript1.4\0foo"
-PASS Script shouldn't run with language="javascript1.5\0foo"
-PASS Script shouldn't run with language="jscript\0foo"
-PASS Script shouldn't run with language="livescript\0foo"
-PASS Script shouldn't run with language="x-ecmascript\0foo"
-PASS Script shouldn't run with language="x-javascript\0foo"
-PASS Script shouldn't run with type=javascript (parser-inserted)
-PASS Script shouldn't run with type=javascript1.0 (parser-inserted)
-PASS Script shouldn't run with type=javascript1.1 (parser-inserted)
-PASS Script shouldn't run with type=javascript1.2 (parser-inserted)
-PASS Script shouldn't run with type=javascript1.3 (parser-inserted)
-PASS Script shouldn't run with type=javascript1.4 (parser-inserted)
-PASS Script shouldn't run with type=javascript1.5 (parser-inserted)
-PASS Script shouldn't run with type=javascript1.6 (parser-inserted)
-PASS Script shouldn't run with type=javascript1.7 (parser-inserted)
-PASS Script shouldn't run with type=livescript (parser-inserted)
-PASS Script shouldn't run with type=ecmascript (parser-inserted)
-PASS Script shouldn't run with type=jscript (parser-inserted)
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/html/semantics/scripting-1/the-script-element/script-type-and-language-js-xhtml-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/html/semantics/scripting-1/the-script-element/script-type-and-language-js-xhtml-expected.txt
deleted file mode 100644
index 43acb10..0000000
--- a/third_party/blink/web_tests/platform/generic/external/wpt/html/semantics/scripting-1/the-script-element/script-type-and-language-js-xhtml-expected.txt
+++ /dev/null
@@ -1,460 +0,0 @@
-This is a testharness.js-based test.
-Found 456 tests; 454 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS Script should run with type=""
-PASS Script shouldn't run with type=" "
-PASS Script should run with type="application/ecmascript"
-PASS Script should run with type="application/javascript"
-PASS Script should run with type="application/x-ecmascript"
-PASS Script should run with type="application/x-javascript"
-PASS Script should run with type="APPLICATION/ECMASCRIPT"
-PASS Script should run with type="APPLICATION/JAVASCRIPT"
-PASS Script should run with type="APPLICATION/X-ECMASCRIPT"
-PASS Script should run with type="APPLICATION/X-JAVASCRIPT"
-PASS Script should run with type="application/ecmascript "
-PASS Script should run with type="application/javascript "
-PASS Script should run with type="application/x-ecmascript "
-PASS Script should run with type="application/x-javascript "
-PASS Script should run with type=" application/ecmascript"
-PASS Script should run with type=" application/javascript"
-PASS Script should run with type=" application/x-ecmascript"
-PASS Script should run with type=" application/x-javascript"
-PASS Script should run with type="application/ecmascript\t"
-PASS Script should run with type="application/javascript\t"
-PASS Script should run with type="application/x-ecmascript\t"
-PASS Script should run with type="application/x-javascript\t"
-PASS Script should run with type="\tapplication/ecmascript"
-PASS Script should run with type="\tapplication/javascript"
-PASS Script should run with type="\tapplication/x-ecmascript"
-PASS Script should run with type="\tapplication/x-javascript"
-PASS Script should run with type="application/ecmascript\n"
-PASS Script should run with type="application/javascript\n"
-PASS Script should run with type="application/x-ecmascript\n"
-PASS Script should run with type="application/x-javascript\n"
-PASS Script should run with type="\napplication/ecmascript"
-PASS Script should run with type="\napplication/javascript"
-PASS Script should run with type="\napplication/x-ecmascript"
-PASS Script should run with type="\napplication/x-javascript"
-PASS Script should run with type="application/ecmascript\r"
-PASS Script should run with type="application/javascript\r"
-PASS Script should run with type="application/x-ecmascript\r"
-PASS Script should run with type="application/x-javascript\r"
-PASS Script should run with type="\rapplication/ecmascript"
-PASS Script should run with type="\rapplication/javascript"
-PASS Script should run with type="\rapplication/x-ecmascript"
-PASS Script should run with type="\rapplication/x-javascript"
-PASS Script should run with type="application/ecmascript\f"
-PASS Script should run with type="application/javascript\f"
-PASS Script should run with type="application/x-ecmascript\f"
-PASS Script should run with type="application/x-javascript\f"
-PASS Script should run with type="\fapplication/ecmascript"
-PASS Script should run with type="\fapplication/javascript"
-PASS Script should run with type="\fapplication/x-ecmascript"
-PASS Script should run with type="\fapplication/x-javascript"
-PASS Script shouldn't run with type="application/ecmascript\0"
-PASS Script shouldn't run with type="application/javascript\0"
-PASS Script shouldn't run with type="application/x-ecmascript\0"
-PASS Script shouldn't run with type="application/x-javascript\0"
-PASS Script shouldn't run with type="application/ecmascript\0foo"
-PASS Script shouldn't run with type="application/javascript\0foo"
-PASS Script shouldn't run with type="application/x-ecmascript\0foo"
-PASS Script shouldn't run with type="application/x-javascript\0foo"
-PASS Script should run with type="text/ecmascript"
-PASS Script should run with type="text/javascript"
-PASS Script should run with type="text/javascript1.0"
-PASS Script should run with type="text/javascript1.1"
-PASS Script should run with type="text/javascript1.2"
-PASS Script should run with type="text/javascript1.3"
-PASS Script should run with type="text/javascript1.4"
-PASS Script should run with type="text/javascript1.5"
-PASS Script should run with type="text/jscript"
-PASS Script should run with type="text/livescript"
-PASS Script should run with type="text/x-ecmascript"
-PASS Script should run with type="text/x-javascript"
-PASS Script should run with type="TEXT/ECMASCRIPT"
-PASS Script should run with type="TEXT/JAVASCRIPT"
-PASS Script should run with type="TEXT/JAVASCRIPT1.0"
-PASS Script should run with type="TEXT/JAVASCRIPT1.1"
-PASS Script should run with type="TEXT/JAVASCRIPT1.2"
-PASS Script should run with type="TEXT/JAVASCRIPT1.3"
-PASS Script should run with type="TEXT/JAVASCRIPT1.4"
-PASS Script should run with type="TEXT/JAVASCRIPT1.5"
-PASS Script should run with type="TEXT/JSCRIPT"
-PASS Script should run with type="TEXT/LIVESCRIPT"
-PASS Script should run with type="TEXT/X-ECMASCRIPT"
-PASS Script should run with type="TEXT/X-JAVASCRIPT"
-PASS Script shouldn't run with type="text/javascript1.6"
-PASS Script shouldn't run with type="text/javascript1.7"
-PASS Script shouldn't run with type="text/javascript1.8"
-PASS Script shouldn't run with type="text/javascript1.9"
-PASS Script should run with type="text/ecmascript "
-PASS Script should run with type="text/javascript "
-PASS Script should run with type="text/javascript1.0 "
-PASS Script should run with type="text/javascript1.1 "
-PASS Script should run with type="text/javascript1.2 "
-PASS Script should run with type="text/javascript1.3 "
-PASS Script should run with type="text/javascript1.4 "
-PASS Script should run with type="text/javascript1.5 "
-PASS Script should run with type="text/jscript "
-PASS Script should run with type="text/livescript "
-PASS Script should run with type="text/x-ecmascript "
-PASS Script should run with type="text/x-javascript "
-PASS Script should run with type=" text/ecmascript"
-PASS Script should run with type=" text/javascript"
-PASS Script should run with type=" text/javascript1.0"
-PASS Script should run with type=" text/javascript1.1"
-PASS Script should run with type=" text/javascript1.2"
-PASS Script should run with type=" text/javascript1.3"
-PASS Script should run with type=" text/javascript1.4"
-PASS Script should run with type=" text/javascript1.5"
-PASS Script should run with type=" text/jscript"
-PASS Script should run with type=" text/livescript"
-PASS Script should run with type=" text/x-ecmascript"
-PASS Script should run with type=" text/x-javascript"
-PASS Script should run with type="text/ecmascript\t"
-PASS Script should run with type="text/javascript\t"
-PASS Script should run with type="text/javascript1.0\t"
-PASS Script should run with type="text/javascript1.1\t"
-PASS Script should run with type="text/javascript1.2\t"
-PASS Script should run with type="text/javascript1.3\t"
-PASS Script should run with type="text/javascript1.4\t"
-PASS Script should run with type="text/javascript1.5\t"
-PASS Script should run with type="text/jscript\t"
-PASS Script should run with type="text/livescript\t"
-PASS Script should run with type="text/x-ecmascript\t"
-PASS Script should run with type="text/x-javascript\t"
-PASS Script should run with type="\ttext/ecmascript"
-PASS Script should run with type="\ttext/javascript"
-PASS Script should run with type="\ttext/javascript1.0"
-PASS Script should run with type="\ttext/javascript1.1"
-PASS Script should run with type="\ttext/javascript1.2"
-PASS Script should run with type="\ttext/javascript1.3"
-PASS Script should run with type="\ttext/javascript1.4"
-PASS Script should run with type="\ttext/javascript1.5"
-PASS Script should run with type="\ttext/jscript"
-PASS Script should run with type="\ttext/livescript"
-PASS Script should run with type="\ttext/x-ecmascript"
-PASS Script should run with type="\ttext/x-javascript"
-PASS Script should run with type="text/ecmascript\n"
-PASS Script should run with type="text/javascript\n"
-PASS Script should run with type="text/javascript1.0\n"
-PASS Script should run with type="text/javascript1.1\n"
-PASS Script should run with type="text/javascript1.2\n"
-PASS Script should run with type="text/javascript1.3\n"
-PASS Script should run with type="text/javascript1.4\n"
-PASS Script should run with type="text/javascript1.5\n"
-PASS Script should run with type="text/jscript\n"
-PASS Script should run with type="text/livescript\n"
-PASS Script should run with type="text/x-ecmascript\n"
-PASS Script should run with type="text/x-javascript\n"
-PASS Script should run with type="\ntext/ecmascript"
-PASS Script should run with type="\ntext/javascript"
-PASS Script should run with type="\ntext/javascript1.0"
-PASS Script should run with type="\ntext/javascript1.1"
-PASS Script should run with type="\ntext/javascript1.2"
-PASS Script should run with type="\ntext/javascript1.3"
-PASS Script should run with type="\ntext/javascript1.4"
-PASS Script should run with type="\ntext/javascript1.5"
-PASS Script should run with type="\ntext/jscript"
-PASS Script should run with type="\ntext/livescript"
-PASS Script should run with type="\ntext/x-ecmascript"
-PASS Script should run with type="\ntext/x-javascript"
-PASS Script should run with type="text/ecmascript\r"
-PASS Script should run with type="text/javascript\r"
-PASS Script should run with type="text/javascript1.0\r"
-PASS Script should run with type="text/javascript1.1\r"
-PASS Script should run with type="text/javascript1.2\r"
-PASS Script should run with type="text/javascript1.3\r"
-PASS Script should run with type="text/javascript1.4\r"
-PASS Script should run with type="text/javascript1.5\r"
-PASS Script should run with type="text/jscript\r"
-PASS Script should run with type="text/livescript\r"
-PASS Script should run with type="text/x-ecmascript\r"
-PASS Script should run with type="text/x-javascript\r"
-PASS Script should run with type="\rtext/ecmascript"
-PASS Script should run with type="\rtext/javascript"
-PASS Script should run with type="\rtext/javascript1.0"
-PASS Script should run with type="\rtext/javascript1.1"
-PASS Script should run with type="\rtext/javascript1.2"
-PASS Script should run with type="\rtext/javascript1.3"
-PASS Script should run with type="\rtext/javascript1.4"
-PASS Script should run with type="\rtext/javascript1.5"
-PASS Script should run with type="\rtext/jscript"
-PASS Script should run with type="\rtext/livescript"
-PASS Script should run with type="\rtext/x-ecmascript"
-PASS Script should run with type="\rtext/x-javascript"
-PASS Script should run with type="text/ecmascript\f"
-PASS Script should run with type="text/javascript\f"
-PASS Script should run with type="text/javascript1.0\f"
-PASS Script should run with type="text/javascript1.1\f"
-PASS Script should run with type="text/javascript1.2\f"
-PASS Script should run with type="text/javascript1.3\f"
-PASS Script should run with type="text/javascript1.4\f"
-PASS Script should run with type="text/javascript1.5\f"
-PASS Script should run with type="text/jscript\f"
-PASS Script should run with type="text/livescript\f"
-PASS Script should run with type="text/x-ecmascript\f"
-PASS Script should run with type="text/x-javascript\f"
-PASS Script should run with type="\ftext/ecmascript"
-PASS Script should run with type="\ftext/javascript"
-PASS Script should run with type="\ftext/javascript1.0"
-PASS Script should run with type="\ftext/javascript1.1"
-PASS Script should run with type="\ftext/javascript1.2"
-PASS Script should run with type="\ftext/javascript1.3"
-PASS Script should run with type="\ftext/javascript1.4"
-PASS Script should run with type="\ftext/javascript1.5"
-PASS Script should run with type="\ftext/jscript"
-PASS Script should run with type="\ftext/livescript"
-PASS Script should run with type="\ftext/x-ecmascript"
-PASS Script should run with type="\ftext/x-javascript"
-PASS Script shouldn't run with type="text/ecmascript\0"
-PASS Script shouldn't run with type="text/javascript\0"
-PASS Script shouldn't run with type="text/javascript1.0\0"
-PASS Script shouldn't run with type="text/javascript1.1\0"
-PASS Script shouldn't run with type="text/javascript1.2\0"
-PASS Script shouldn't run with type="text/javascript1.3\0"
-PASS Script shouldn't run with type="text/javascript1.4\0"
-PASS Script shouldn't run with type="text/javascript1.5\0"
-PASS Script shouldn't run with type="text/jscript\0"
-PASS Script shouldn't run with type="text/livescript\0"
-PASS Script shouldn't run with type="text/x-ecmascript\0"
-PASS Script shouldn't run with type="text/x-javascript\0"
-PASS Script shouldn't run with type="text/ecmascript\0foo"
-PASS Script shouldn't run with type="text/javascript\0foo"
-PASS Script shouldn't run with type="text/javascript1.0\0foo"
-PASS Script shouldn't run with type="text/javascript1.1\0foo"
-PASS Script shouldn't run with type="text/javascript1.2\0foo"
-PASS Script shouldn't run with type="text/javascript1.3\0foo"
-PASS Script shouldn't run with type="text/javascript1.4\0foo"
-PASS Script shouldn't run with type="text/javascript1.5\0foo"
-PASS Script shouldn't run with type="text/jscript\0foo"
-PASS Script shouldn't run with type="text/livescript\0foo"
-PASS Script shouldn't run with type="text/x-ecmascript\0foo"
-PASS Script shouldn't run with type="text/x-javascript\0foo"
-PASS Script shouldn't run with type="ecmascript"
-PASS Script shouldn't run with type="javascript"
-PASS Script shouldn't run with type="javascript1.0"
-PASS Script shouldn't run with type="javascript1.1"
-PASS Script shouldn't run with type="javascript1.2"
-PASS Script shouldn't run with type="javascript1.3"
-PASS Script shouldn't run with type="javascript1.4"
-PASS Script shouldn't run with type="javascript1.5"
-PASS Script shouldn't run with type="jscript"
-PASS Script shouldn't run with type="livescript"
-PASS Script shouldn't run with type="x-ecmascript"
-PASS Script shouldn't run with type="x-javascript"
-PASS Script shouldn't run with type="javascript1.6"
-PASS Script shouldn't run with type="javascript1.7"
-PASS Script shouldn't run with type="javascript1.8"
-PASS Script shouldn't run with type="javascript1.9"
-PASS Script should run with language=""
-PASS Script shouldn't run with language=" "
-PASS Script should run with language="ecmascript"
-PASS Script should run with language="javascript"
-PASS Script should run with language="javascript1.0"
-PASS Script should run with language="javascript1.1"
-PASS Script should run with language="javascript1.2"
-PASS Script should run with language="javascript1.3"
-PASS Script should run with language="javascript1.4"
-PASS Script should run with language="javascript1.5"
-PASS Script should run with language="jscript"
-PASS Script should run with language="livescript"
-PASS Script should run with language="x-ecmascript"
-PASS Script should run with language="x-javascript"
-PASS Script should run with language="ECMASCRIPT"
-PASS Script should run with language="JAVASCRIPT"
-PASS Script should run with language="JAVASCRIPT1.0"
-PASS Script should run with language="JAVASCRIPT1.1"
-PASS Script should run with language="JAVASCRIPT1.2"
-PASS Script should run with language="JAVASCRIPT1.3"
-PASS Script should run with language="JAVASCRIPT1.4"
-PASS Script should run with language="JAVASCRIPT1.5"
-PASS Script should run with language="JSCRIPT"
-PASS Script should run with language="LIVESCRIPT"
-PASS Script should run with language="X-ECMASCRIPT"
-PASS Script should run with language="X-JAVASCRIPT"
-FAIL Script shouldn't run with language="javascript1.6" assert_equals: expected false but got true
-FAIL Script shouldn't run with language="javascript1.7" assert_equals: expected false but got true
-PASS Script shouldn't run with language="javascript1.8"
-PASS Script shouldn't run with language="javascript1.9"
-PASS Script shouldn't run with language="ecmascript "
-PASS Script shouldn't run with language="javascript "
-PASS Script shouldn't run with language="javascript1.0 "
-PASS Script shouldn't run with language="javascript1.1 "
-PASS Script shouldn't run with language="javascript1.2 "
-PASS Script shouldn't run with language="javascript1.3 "
-PASS Script shouldn't run with language="javascript1.4 "
-PASS Script shouldn't run with language="javascript1.5 "
-PASS Script shouldn't run with language="jscript "
-PASS Script shouldn't run with language="livescript "
-PASS Script shouldn't run with language="x-ecmascript "
-PASS Script shouldn't run with language="x-javascript "
-PASS Script shouldn't run with language=" ecmascript"
-PASS Script shouldn't run with language=" javascript"
-PASS Script shouldn't run with language=" javascript1.0"
-PASS Script shouldn't run with language=" javascript1.1"
-PASS Script shouldn't run with language=" javascript1.2"
-PASS Script shouldn't run with language=" javascript1.3"
-PASS Script shouldn't run with language=" javascript1.4"
-PASS Script shouldn't run with language=" javascript1.5"
-PASS Script shouldn't run with language=" jscript"
-PASS Script shouldn't run with language=" livescript"
-PASS Script shouldn't run with language=" x-ecmascript"
-PASS Script shouldn't run with language=" x-javascript"
-PASS Script shouldn't run with language="ecmascript\t"
-PASS Script shouldn't run with language="javascript\t"
-PASS Script shouldn't run with language="javascript1.0\t"
-PASS Script shouldn't run with language="javascript1.1\t"
-PASS Script shouldn't run with language="javascript1.2\t"
-PASS Script shouldn't run with language="javascript1.3\t"
-PASS Script shouldn't run with language="javascript1.4\t"
-PASS Script shouldn't run with language="javascript1.5\t"
-PASS Script shouldn't run with language="jscript\t"
-PASS Script shouldn't run with language="livescript\t"
-PASS Script shouldn't run with language="x-ecmascript\t"
-PASS Script shouldn't run with language="x-javascript\t"
-PASS Script shouldn't run with language="\tecmascript"
-PASS Script shouldn't run with language="\tjavascript"
-PASS Script shouldn't run with language="\tjavascript1.0"
-PASS Script shouldn't run with language="\tjavascript1.1"
-PASS Script shouldn't run with language="\tjavascript1.2"
-PASS Script shouldn't run with language="\tjavascript1.3"
-PASS Script shouldn't run with language="\tjavascript1.4"
-PASS Script shouldn't run with language="\tjavascript1.5"
-PASS Script shouldn't run with language="\tjscript"
-PASS Script shouldn't run with language="\tlivescript"
-PASS Script shouldn't run with language="\tx-ecmascript"
-PASS Script shouldn't run with language="\tx-javascript"
-PASS Script shouldn't run with language="ecmascript\n"
-PASS Script shouldn't run with language="javascript\n"
-PASS Script shouldn't run with language="javascript1.0\n"
-PASS Script shouldn't run with language="javascript1.1\n"
-PASS Script shouldn't run with language="javascript1.2\n"
-PASS Script shouldn't run with language="javascript1.3\n"
-PASS Script shouldn't run with language="javascript1.4\n"
-PASS Script shouldn't run with language="javascript1.5\n"
-PASS Script shouldn't run with language="jscript\n"
-PASS Script shouldn't run with language="livescript\n"
-PASS Script shouldn't run with language="x-ecmascript\n"
-PASS Script shouldn't run with language="x-javascript\n"
-PASS Script shouldn't run with language="\necmascript"
-PASS Script shouldn't run with language="\njavascript"
-PASS Script shouldn't run with language="\njavascript1.0"
-PASS Script shouldn't run with language="\njavascript1.1"
-PASS Script shouldn't run with language="\njavascript1.2"
-PASS Script shouldn't run with language="\njavascript1.3"
-PASS Script shouldn't run with language="\njavascript1.4"
-PASS Script shouldn't run with language="\njavascript1.5"
-PASS Script shouldn't run with language="\njscript"
-PASS Script shouldn't run with language="\nlivescript"
-PASS Script shouldn't run with language="\nx-ecmascript"
-PASS Script shouldn't run with language="\nx-javascript"
-PASS Script shouldn't run with language="ecmascript\r"
-PASS Script shouldn't run with language="javascript\r"
-PASS Script shouldn't run with language="javascript1.0\r"
-PASS Script shouldn't run with language="javascript1.1\r"
-PASS Script shouldn't run with language="javascript1.2\r"
-PASS Script shouldn't run with language="javascript1.3\r"
-PASS Script shouldn't run with language="javascript1.4\r"
-PASS Script shouldn't run with language="javascript1.5\r"
-PASS Script shouldn't run with language="jscript\r"
-PASS Script shouldn't run with language="livescript\r"
-PASS Script shouldn't run with language="x-ecmascript\r"
-PASS Script shouldn't run with language="x-javascript\r"
-PASS Script shouldn't run with language="\recmascript"
-PASS Script shouldn't run with language="\rjavascript"
-PASS Script shouldn't run with language="\rjavascript1.0"
-PASS Script shouldn't run with language="\rjavascript1.1"
-PASS Script shouldn't run with language="\rjavascript1.2"
-PASS Script shouldn't run with language="\rjavascript1.3"
-PASS Script shouldn't run with language="\rjavascript1.4"
-PASS Script shouldn't run with language="\rjavascript1.5"
-PASS Script shouldn't run with language="\rjscript"
-PASS Script shouldn't run with language="\rlivescript"
-PASS Script shouldn't run with language="\rx-ecmascript"
-PASS Script shouldn't run with language="\rx-javascript"
-PASS Script shouldn't run with language="ecmascript\f"
-PASS Script shouldn't run with language="javascript\f"
-PASS Script shouldn't run with language="javascript1.0\f"
-PASS Script shouldn't run with language="javascript1.1\f"
-PASS Script shouldn't run with language="javascript1.2\f"
-PASS Script shouldn't run with language="javascript1.3\f"
-PASS Script shouldn't run with language="javascript1.4\f"
-PASS Script shouldn't run with language="javascript1.5\f"
-PASS Script shouldn't run with language="jscript\f"
-PASS Script shouldn't run with language="livescript\f"
-PASS Script shouldn't run with language="x-ecmascript\f"
-PASS Script shouldn't run with language="x-javascript\f"
-PASS Script shouldn't run with language="\fecmascript"
-PASS Script shouldn't run with language="\fjavascript"
-PASS Script shouldn't run with language="\fjavascript1.0"
-PASS Script shouldn't run with language="\fjavascript1.1"
-PASS Script shouldn't run with language="\fjavascript1.2"
-PASS Script shouldn't run with language="\fjavascript1.3"
-PASS Script shouldn't run with language="\fjavascript1.4"
-PASS Script shouldn't run with language="\fjavascript1.5"
-PASS Script shouldn't run with language="\fjscript"
-PASS Script shouldn't run with language="\flivescript"
-PASS Script shouldn't run with language="\fx-ecmascript"
-PASS Script shouldn't run with language="\fx-javascript"
-PASS Script shouldn't run with language="ecmascriptxyz"
-PASS Script shouldn't run with language="javascriptxyz"
-PASS Script shouldn't run with language="javascript1.0xyz"
-PASS Script shouldn't run with language="javascript1.1xyz"
-PASS Script shouldn't run with language="javascript1.2xyz"
-PASS Script shouldn't run with language="javascript1.3xyz"
-PASS Script shouldn't run with language="javascript1.4xyz"
-PASS Script shouldn't run with language="javascript1.5xyz"
-PASS Script shouldn't run with language="jscriptxyz"
-PASS Script shouldn't run with language="livescriptxyz"
-PASS Script shouldn't run with language="x-ecmascriptxyz"
-PASS Script shouldn't run with language="x-javascriptxyz"
-PASS Script shouldn't run with language="xyzecmascript"
-PASS Script shouldn't run with language="xyzjavascript"
-PASS Script shouldn't run with language="xyzjavascript1.0"
-PASS Script shouldn't run with language="xyzjavascript1.1"
-PASS Script shouldn't run with language="xyzjavascript1.2"
-PASS Script shouldn't run with language="xyzjavascript1.3"
-PASS Script shouldn't run with language="xyzjavascript1.4"
-PASS Script shouldn't run with language="xyzjavascript1.5"
-PASS Script shouldn't run with language="xyzjscript"
-PASS Script shouldn't run with language="xyzlivescript"
-PASS Script shouldn't run with language="xyzx-ecmascript"
-PASS Script shouldn't run with language="xyzx-javascript"
-PASS Script shouldn't run with language="ecmascript\0"
-PASS Script shouldn't run with language="javascript\0"
-PASS Script shouldn't run with language="javascript1.0\0"
-PASS Script shouldn't run with language="javascript1.1\0"
-PASS Script shouldn't run with language="javascript1.2\0"
-PASS Script shouldn't run with language="javascript1.3\0"
-PASS Script shouldn't run with language="javascript1.4\0"
-PASS Script shouldn't run with language="javascript1.5\0"
-PASS Script shouldn't run with language="jscript\0"
-PASS Script shouldn't run with language="livescript\0"
-PASS Script shouldn't run with language="x-ecmascript\0"
-PASS Script shouldn't run with language="x-javascript\0"
-PASS Script shouldn't run with language="ecmascript\0foo"
-PASS Script shouldn't run with language="javascript\0foo"
-PASS Script shouldn't run with language="javascript1.0\0foo"
-PASS Script shouldn't run with language="javascript1.1\0foo"
-PASS Script shouldn't run with language="javascript1.2\0foo"
-PASS Script shouldn't run with language="javascript1.3\0foo"
-PASS Script shouldn't run with language="javascript1.4\0foo"
-PASS Script shouldn't run with language="javascript1.5\0foo"
-PASS Script shouldn't run with language="jscript\0foo"
-PASS Script shouldn't run with language="livescript\0foo"
-PASS Script shouldn't run with language="x-ecmascript\0foo"
-PASS Script shouldn't run with language="x-javascript\0foo"
-PASS Script shouldn't run with type=javascript (parser-inserted)
-PASS Script shouldn't run with type=javascript1.0 (parser-inserted)
-PASS Script shouldn't run with type=javascript1.1 (parser-inserted)
-PASS Script shouldn't run with type=javascript1.2 (parser-inserted)
-PASS Script shouldn't run with type=javascript1.3 (parser-inserted)
-PASS Script shouldn't run with type=javascript1.4 (parser-inserted)
-PASS Script shouldn't run with type=javascript1.5 (parser-inserted)
-PASS Script shouldn't run with type=javascript1.6 (parser-inserted)
-PASS Script shouldn't run with type=javascript1.7 (parser-inserted)
-PASS Script shouldn't run with type=livescript (parser-inserted)
-PASS Script shouldn't run with type=ecmascript (parser-inserted)
-PASS Script shouldn't run with type=jscript (parser-inserted)
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/generic/fast/html/script-allowed-types-languages-expected.txt b/third_party/blink/web_tests/platform/generic/fast/html/script-allowed-types-languages-expected.txt
deleted file mode 100644
index de825321..0000000
--- a/third_party/blink/web_tests/platform/generic/fast/html/script-allowed-types-languages-expected.txt
+++ /dev/null
@@ -1,80 +0,0 @@
-This page tests the allowed values for the type and language attributes of the <script> tag. Below you will see the allowed values.
-
-Type: unspecified, Language: unspecified
-Type: "", Language: unspecified
-Type: "text/javascript", Language: unspecified
-Type: "text/ecmascript", Language: unspecified
-Type: "text/x-javascript", Language: unspecified
-Type: "text/x-ecmascript", Language: unspecified
-Type: "application/javascript", Language: unspecified
-Type: "application/ecmascript", Language: unspecified
-Type: "application/x-javascript", Language: unspecified
-Type: "application/x-ecmascript", Language: unspecified
-Type: "text/javascript1.0", Language: unspecified
-Type: "text/javascript1.1", Language: unspecified
-Type: "text/javascript1.2", Language: unspecified
-Type: "text/javascript1.3", Language: unspecified
-Type: "text/javascript1.4", Language: unspecified
-Type: "text/javascript1.5", Language: unspecified
-Type: "text/jscript", Language: unspecified
-Type: "text/livescript", Language: unspecified
-Type: "  text/javascript", Language: unspecified
-Type: "text/javascript  ", Language: unspecified
-Type: "  text/javascript  ", Language: unspecified
-Type: unspecified, Language: ""
-Type: unspecified, Language: "javascript"
-Type: unspecified, Language: "javascript1.0"
-Type: unspecified, Language: "javascript1.1"
-Type: unspecified, Language: "javascript1.2"
-Type: unspecified, Language: "javascript1.3"
-Type: unspecified, Language: "javascript1.4"
-Type: unspecified, Language: "javascript1.5"
-Type: unspecified, Language: "javascript1.6"
-Type: unspecified, Language: "javascript1.7"
-Type: unspecified, Language: "ecmascript"
-Type: unspecified, Language: "livescript"
-Type: unspecified, Language: "jscript"
-Type: "", Language: ""
-Type: "", Language: "javascript"
-Type: "", Language: "javascript1.0"
-Type: "", Language: "javascript1.1"
-Type: "", Language: "javascript1.2"
-Type: "", Language: "javascript1.3"
-Type: "", Language: "javascript1.4"
-Type: "", Language: "javascript1.5"
-Type: "", Language: "javascript1.6"
-Type: "", Language: "javascript1.7"
-Type: "", Language: "javascript1.8"
-Type: "", Language: "javascript1.9"
-Type: "", Language: "ecmascript"
-Type: "", Language: "livescript"
-Type: "", Language: "jscript"
-Type: "", Language: "ebayScript"
-Type: "", Language: "    "
-Type: "", Language: "  javascript"
-Type: "", Language: "javascript  "
-Type: "", Language: "  javascript  "
-Type: "", Language: "abcdefg"
-When a type is specified, the language attribute should be ignored.
-Type: "text/javascript", Language: ""
-Type: "text/javascript", Language: "javascript"
-Type: "text/javascript", Language: "javascript1.0"
-Type: "text/javascript", Language: "javascript1.1"
-Type: "text/javascript", Language: "javascript1.2"
-Type: "text/javascript", Language: "javascript1.3"
-Type: "text/javascript", Language: "javascript1.4"
-Type: "text/javascript", Language: "javascript1.5"
-Type: "text/javascript", Language: "javascript1.6"
-Type: "text/javascript", Language: "javascript1.7"
-Type: "text/javascript", Language: "javascript1.8"
-Type: "text/javascript", Language: "javascript1.9"
-Type: "text/javascript", Language: "ecmascript"
-Type: "text/javascript", Language: "livescript"
-Type: "text/javascript", Language: "jscript"
-Type: "text/javascript", Language: "ebayScript"
-Type: "text/javascript", Language: "    "
-Type: "text/javascript", Language: "  javascript"
-Type: "text/javascript", Language: "javascript  "
-Type: "text/javascript", Language: "  javascript  "
-Type: "text/javascript", Language: "abcdefg"
-
diff --git a/third_party/blink/web_tests/platform/generic/fast/tokenizer/004-expected.txt b/third_party/blink/web_tests/platform/generic/fast/tokenizer/004-expected.txt
deleted file mode 100644
index 33cd2ffe..0000000
--- a/third_party/blink/web_tests/platform/generic/fast/tokenizer/004-expected.txt
+++ /dev/null
@@ -1,165 +0,0 @@
-Variations on type attribute of script tag
-These scripts should execute
-no type attribute executed
-empty string executed
-text/javascript executed
-text/JAVASCRIPT executed
-TEXT/JAVASCRIPT executed
-'text/javascript ' executed
-' text/javascript ' executed
-text/jscript executed
-text/ecmascript executed
-text/livescript executed
-text/javascript1.0 executed
-text/javascript1.1 executed
-text/javascript1.2 executed
-text/javascript1.3 executed
-text/javascript1.4 executed
-text/javascript1.5 executed
-text/x-javascript executed
-text/x-ecmascript executed
-application/javascript executed
-application/ecmascript executed
-application/x-javascript executed
-application/x-ecmascript executed
-These scripts should not execute
-one space
-text/
-text/vbscript
-text/vbs
-text/xml
-text/javascript1
-text/javascript1.6
-application/jscript
-application/x-jscript
-application/livescript
-application/x-livescript
-application/javascript1.2
-application/x-javascript1.2
-javascript
-jscript
-ecmascript
-livescript
-livescript1.1
-JAVASCRIPT
-JavaScript
-JavaScript 1
-JavaScript 1.0
-JavaScript 1.1
-JavaScript 1.1.1
-JavaScript 1.2
-JavaScript 1.3
-JavaScript 1.4
-JavaScript 1.5
-JavaScript 1.6
-JavaScript 1.7
-JavaScript 1.8
-JavaScript 1.9
-JavaScript 2
-JavaScript 2.1
-JavaScript 10
-JavaScript 10.0
-_javascript
-javascript_
-javascript_1.0
-javascript 1.0 x
-JavaScript1
-JavaScript1.0
-JavaScript1.1
-JavaScript1.2
-JavaScript1.3
-JavaScript1.4
-JavaScript1.4.1
-JavaScript1.5
-JavaScript1.6
-JavaScript1.7
-1.0 javascript
-' javascript '
-' javascript1.1 '
-'   javascript   '
-' javascript 1.0 '
-' javascript  1.0 '
-jscript 1
-jscript 1.0
-ecmascript 1
-ecmascript 1.0
-livescript 1
-livescript 1.0
-' jscript  1.0 '
-disabled_javascript
-xxxjavascriptxxx
-bogus
-Variations on language attribute of script tag
-These scripts should execute
-no language attribute executed
-empty string executed
-jscript executed
-ecmascript executed
-livescript executed
-javascript executed
-JAVASCRIPT executed
-JavaScript executed
-JavaScript1.0 executed
-JavaScript1.1 executed
-JavaScript1.2 executed
-JavaScript1.3 executed
-JavaScript1.4 executed
-JavaScript1.5 executed
-JavaScript1.6 executed
-JavaScript1.7 executed
-These scripts should not execute
-one space
-vbscript
-livescript1.1
-JavaScript 1
-JavaScript 1.0
-JavaScript 1.1
-JavaScript 1.1.1
-JavaScript 1.2
-JavaScript 1.3
-JavaScript 1.4
-JavaScript 1.5
-JavaScript 1.6
-JavaScript 1.7
-JavaScript 1.8
-JavaScript 1.9
-JavaScript 2
-JavaScript 2.1
-JavaScript 10
-JavaScript 10.0
-_javascript
-javascript_
-javascript_1.0
-javascript 1.0 x
-JavaScript1
-JavaScript1.8
-JavaScript1.9
-JavaScript1.4.1
-1.0 javascript
-' javascript '
-' javascript1.1 '
-'   javascript   '
-' javascript 1.0 '
-' javascript  1.0 '
-jscript 1
-jscript 1.0
-ecmascript 1
-ecmascript 1.0
-livescript 1
-livescript 1.0
-' jscript  1.0 '
-disabled_javascript
-xxxjavascriptxxx
-bogus
-Variations on combined type and language attributes of script tag
-These scripts should execute
-empty string type, "javascript" language executed
-empty string language, "text/javascript" type executed
-"javascript" language, "text/javascript" type executed
-"bogus" language, "text/javascript" type executed
-"livescript" language, "text/javascript" type executed
-"javascript1.2" language, "text/javascript" type executed
-empty string type, "bogus" language executed
-These scripts should not execute
-"javascript" language, "bogus" type
-empty string language, "bogus" type
diff --git a/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/fenced-frame/setWebLifecycleState-fenced-frame.https-expected.txt b/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/fenced-frame/setWebLifecycleState-fenced-frame.https-expected.txt
new file mode 100644
index 0000000..c2f10b7
--- /dev/null
+++ b/third_party/blink/web_tests/platform/generic/http/tests/inspector-protocol/fenced-frame/setWebLifecycleState-fenced-frame.https-expected.txt
@@ -0,0 +1,4 @@
+Tests that Page.setWebLifecycleState() in a fenced frame is not allowed.
+Page.setWebLifecycleState() from a fenced frame:
+PASS: This is only supported for top-level frames
+
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/preload/avoid-delaying-onload-link-modulepreload-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/preload/avoid-delaying-onload-link-modulepreload-expected.txt
deleted file mode 100644
index 6e471cab..0000000
--- a/third_party/blink/web_tests/platform/linux/external/wpt/preload/avoid-delaying-onload-link-modulepreload-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Fetching modulepreload should not block the window's load event assert_equals: resources/dummy.js?pipe=trickle(d5) expected 0 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/preload/avoid-delaying-onload-link-modulepreload-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/preload/avoid-delaying-onload-link-modulepreload-expected.txt
deleted file mode 100644
index 6e471cab..0000000
--- a/third_party/blink/web_tests/platform/mac/external/wpt/preload/avoid-delaying-onload-link-modulepreload-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Fetching modulepreload should not block the window's load event assert_equals: resources/dummy.js?pipe=trickle(d5) expected 0 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win10/external/wpt/preload/avoid-delaying-onload-link-modulepreload-expected.txt b/third_party/blink/web_tests/platform/win10/external/wpt/preload/avoid-delaying-onload-link-modulepreload-expected.txt
deleted file mode 100644
index 6e471cab..0000000
--- a/third_party/blink/web_tests/platform/win10/external/wpt/preload/avoid-delaying-onload-link-modulepreload-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Fetching modulepreload should not block the window's load event assert_equals: resources/dummy.js?pipe=trickle(d5) expected 0 but got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/closure_compiler/externs/file_manager_private.js b/third_party/closure_compiler/externs/file_manager_private.js
index 05c4695..6679497 100644
--- a/third_party/closure_compiler/externs/file_manager_private.js
+++ b/third_party/closure_compiler/externs/file_manager_private.js
@@ -1185,9 +1185,10 @@
  * Gets recently modified files across file systems.
  * @param {string} restriction
  * @param {string} fileType
+ * @param {boolean} invalidateCache
  * @param {function((!Array<!FileEntry>))} callback
  */
-chrome.fileManagerPrivate.getRecentFiles = function(restriction, fileType, callback) {};
+chrome.fileManagerPrivate.getRecentFiles = function(restriction, fileType, invalidateCache, callback) {};
 
 /**
  * Requests the root directory of a volume. The ID of the volume must be
@@ -1405,8 +1406,10 @@
  * @param {!chrome.fileManagerPrivate.IOTaskType} type
  * @param {!Array<!Entry>} entries
  * @param {!chrome.fileManagerPrivate.IOTaskParams} params
+ * @param {(function(number): void)=} callback Returns the task ID.
  */
-chrome.fileManagerPrivate.startIOTask = function(type, entries, params) {};
+chrome.fileManagerPrivate.startIOTask = function(
+    type, entries, params, callback) {};
 
 /**
  * Cancels an I/O task by id. Task ids are communicated to the Files App in
diff --git a/third_party/zlib/chromeconf.h b/third_party/zlib/chromeconf.h
index 7c2241a..c365fa9 100644
--- a/third_party/zlib/chromeconf.h
+++ b/third_party/zlib/chromeconf.h
@@ -194,7 +194,6 @@
 #define arm_cpu_enable_pmull Cr_z_arm_cpu_enable_pmull
 #define arm_check_features Cr_z_arm_check_features
 #define armv8_crc32_little Cr_z_armv8_crc32_little
-#define armv8_crc32_pmull_little Cr_z_armv8_crc32_pmull_little
 
 /* Symbols added by cpu_features.c */
 #define cpu_check_features Cr_z_cpu_check_features
diff --git a/third_party/zlib/cpu_features.c b/third_party/zlib/cpu_features.c
index 9391d7b4..70f01be 100644
--- a/third_party/zlib/cpu_features.c
+++ b/third_party/zlib/cpu_features.c
@@ -18,16 +18,13 @@
 /* TODO(cavalcantii): remove checks for x86_flags on deflate.
  */
 #if defined(ARMV8_OS_MACOS)
-/* Crypto extensions (crc32/pmull) are a baseline feature in ARMv8.1-A, and
- * OSX running on arm64 is new enough that these can be assumed without
- * runtime detection.
- */
+/* crc32 is a baseline feature in ARMv8.1-A, and macOS running on arm64 is new
+ * enough that this can be assumed without runtime detection. */
 int ZLIB_INTERNAL arm_cpu_enable_crc32 = 1;
-int ZLIB_INTERNAL arm_cpu_enable_pmull = 1;
 #else
 int ZLIB_INTERNAL arm_cpu_enable_crc32 = 0;
-int ZLIB_INTERNAL arm_cpu_enable_pmull = 0;
 #endif
+int ZLIB_INTERNAL arm_cpu_enable_pmull = 0;
 int ZLIB_INTERNAL x86_cpu_enable_sse2 = 0;
 int ZLIB_INTERNAL x86_cpu_enable_ssse3 = 0;
 int ZLIB_INTERNAL x86_cpu_enable_simd = 0;
diff --git a/third_party/zlib/crc32.c b/third_party/zlib/crc32.c
index e60c372..142f1e8 100644
--- a/third_party/zlib/crc32.c
+++ b/third_party/zlib/crc32.c
@@ -1101,29 +1101,23 @@
     const unsigned char FAR *buf;
     uInt len;
 {
-    /* Some bots compile with optimizations disabled, others will emulate
-     * ARM on x86 and other weird combinations.
-     */
 #if defined(CRC32_ARMV8_CRC32)
-    if (arm_cpu_enable_crc32) {
-#if defined(__aarch64__)
-        /* PMULL is 64bit only, plus code needs at least a 64 bytes buffer. */
-        if (arm_cpu_enable_pmull && (len > Z_CRC32_PMULL_MINIMUM_LENGTH)) {
-            const size_t chunk_size = len & ~Z_CRC32_PMULL_CHUNKSIZE_MASK;
-            crc = ~armv8_crc32_pmull_little(buf, chunk_size, ~(uint32_t)crc);
-            /* Check remaining data. */
-            len -= chunk_size;
-            if (!len)
-                return crc;
-
-            /* Fall through for the remaining data. */
-            buf += chunk_size;
-        }
-#endif
-        return armv8_crc32_little(buf, len, crc); /* Armv8@32bit or tail. */
+    /* We got to verify ARM CPU features, so exploit the common usage pattern
+     * of calling this function with Z_NULL for an initial valid crc value.
+     * This allows to cache the result of the feature check and avoid extraneous
+     * function calls.
+     * TODO: try to move this to crc32_z if we don't loose performance on ARM.
+     */
+    if (buf == Z_NULL) {
+        if (!len) /* Assume user is calling crc32(0, NULL, 0); */
+            cpu_check_features();
+        return 0UL;
     }
+
+    if (arm_cpu_enable_crc32)
+        return armv8_crc32_little(crc, buf, len);
 #endif
-    return crc32_z(crc, buf, len); /* Armv7 or Armv8 w/o crypto extensions. */
+    return crc32_z(crc, buf, len);
 }
 
 /* ========================================================================= */
diff --git a/third_party/zlib/crc32_simd.c b/third_party/zlib/crc32_simd.c
index 14a8534..c8e5592 100644
--- a/third_party/zlib/crc32_simd.c
+++ b/third_party/zlib/crc32_simd.c
@@ -157,6 +157,8 @@
 #elif defined(CRC32_ARMV8_CRC32)
 
 /* CRC32 checksums using ARMv8-a crypto instructions.
+ *
+ * TODO: implement a version using the PMULL instruction.
  */
 
 #if defined(__clang__)
@@ -176,23 +178,13 @@
  * feature for this target (ignoring feature)." This appears to be a harmless
  * bug in clang.
  */
-/* XXX: Cannot hook into builtins with XCode for arm64. */
-#if !defined(ARMV8_OS_MACOS)
 #define __crc32b __builtin_arm_crc32b
 #define __crc32d __builtin_arm_crc32d
 #define __crc32w __builtin_arm_crc32w
 #define __crc32cw __builtin_arm_crc32cw
-#endif
-
-/* We need some extra types for using PMULL.
- */
-#if defined(__aarch64__)
-#include <arm_neon.h>
-#include <arm_acle.h>
-#endif
 
 #if defined(__aarch64__)
-#define TARGET_ARMV8_WITH_CRC __attribute__((target("aes,crc")))
+#define TARGET_ARMV8_WITH_CRC __attribute__((target("crc")))
 #else  // !defined(__aarch64__)
 #define TARGET_ARMV8_WITH_CRC __attribute__((target("armv8-a,crc")))
 #endif  // defined(__aarch64__)
@@ -208,10 +200,9 @@
 #endif
 
 TARGET_ARMV8_WITH_CRC
-uint32_t ZLIB_INTERNAL armv8_crc32_little(
-    const unsigned char *buf,
-    z_size_t len,
-    uint32_t crc)
+uint32_t ZLIB_INTERNAL armv8_crc32_little(unsigned long crc,
+                                          const unsigned char *buf,
+                                          z_size_t len)
 {
     uint32_t c = (uint32_t) ~crc;
 
@@ -249,178 +240,4 @@
     return ~c;
 }
 
-#if defined(__aarch64__) || defined(ARMV8_OS_MACOS) /* aarch64 specific code. */
-
-/*
- * crc32_pmull_simd_(): compute the crc32 of the buffer, where the buffer
- * length must be at least 64, and a multiple of 16. Based on:
- *
- * "Fast CRC Computation for Generic Polynomials Using PCLMULQDQ Instruction"
- *  V. Gopal, E. Ozturk, et al., 2009, http://intel.ly/2ySEwL0
- */
-TARGET_ARMV8_WITH_CRC
-static inline uint8x16_t pmull_lo(const uint64x2_t a, const uint64x2_t b)
-{
-    uint8x16_t r;
-    __asm__ __volatile__ ("pmull  %0.1q, %1.1d, %2.1d \n\t"
-        : "=w" (r) : "w" (a), "w" (b) );
-    return r;
-}
-
-TARGET_ARMV8_WITH_CRC
-static inline uint8x16_t pmull_01(const uint64x2_t a, const uint64x2_t b)
-{
-    uint8x16_t r;
-    __asm__ __volatile__ ("pmull  %0.1q, %1.1d, %2.1d \n\t"
-        : "=w" (r) : "w" (a), "w" (vgetq_lane_u64(b, 1)) );
-    return r;
-}
-
-TARGET_ARMV8_WITH_CRC
-static inline uint8x16_t pmull_hi(const uint64x2_t a, const uint64x2_t b)
-{
-    uint8x16_t r;
-    __asm__ __volatile__ ("pmull2 %0.1q, %1.2d, %2.2d \n\t"
-        : "=w" (r) : "w" (a), "w" (b) );
-    return r;
-}
-
-TARGET_ARMV8_WITH_CRC
-uint32_t ZLIB_INTERNAL armv8_crc32_pmull_little(
-    const unsigned char *buf,
-    z_size_t len,
-    uint32_t crc)
-{
-    /*
-     * Definitions of the bit-reflected domain constants k1,k2,k3, etc and
-     * the CRC32+Barrett polynomials given at the end of the paper.
-     */
-    static const uint64_t zalign(16) k1k2[] = { 0x0154442bd4, 0x01c6e41596 };
-    static const uint64_t zalign(16) k3k4[] = { 0x01751997d0, 0x00ccaa009e };
-    static const uint64_t zalign(16) k5k0[] = { 0x0163cd6124, 0x0000000000 };
-    static const uint64_t zalign(16) poly[] = { 0x01db710641, 0x01f7011641 };
-
-    uint64x2_t x0, x1, x2, x3, x4, x5, x6, x7, x8, y5, y6, y7, y8;
-
-    /*
-     * There's at least one block of 64.
-     */
-    x1 = vld1q_u64((const uint64_t *)(buf + 0x00));
-    x2 = vld1q_u64((const uint64_t *)(buf + 0x10));
-    x3 = vld1q_u64((const uint64_t *)(buf + 0x20));
-    x4 = vld1q_u64((const uint64_t *)(buf + 0x30));
-
-    x1 = veorq_u64(x1, (uint64x2_t) vsetq_lane_u32(crc, vdupq_n_u32(0), 0));
-
-    x0 = vld1q_u64(k1k2);
-
-    buf += 64;
-    len -= 64;
-
-    /*
-     * Parallel fold blocks of 64, if any.
-     */
-    while (len >= 64)
-    {
-        x5 = (uint64x2_t) pmull_lo(x1, x0);
-        x6 = (uint64x2_t) pmull_lo(x2, x0);
-        x7 = (uint64x2_t) pmull_lo(x3, x0);
-        x8 = (uint64x2_t) pmull_lo(x4, x0);
-
-        y5 = vld1q_u64((const uint64_t *)(buf + 0x00));
-        y6 = vld1q_u64((const uint64_t *)(buf + 0x10));
-        y7 = vld1q_u64((const uint64_t *)(buf + 0x20));
-        y8 = vld1q_u64((const uint64_t *)(buf + 0x30));
-
-        x1 = (uint64x2_t) pmull_hi(x1, x0);
-        x2 = (uint64x2_t) pmull_hi(x2, x0);
-        x3 = (uint64x2_t) pmull_hi(x3, x0);
-        x4 = (uint64x2_t) pmull_hi(x4, x0);
-
-        x1 = veorq_u64(x1, x5);
-        x2 = veorq_u64(x2, x6);
-        x3 = veorq_u64(x3, x7);
-        x4 = veorq_u64(x4, x8);
-
-        x1 = veorq_u64(x1, y5);
-        x2 = veorq_u64(x2, y6);
-        x3 = veorq_u64(x3, y7);
-        x4 = veorq_u64(x4, y8);
-
-        buf += 64;
-        len -= 64;
-    }
-
-    /*
-     * Fold into 128-bits.
-     */
-    x0 = vld1q_u64(k3k4);
-
-    x5 = (uint64x2_t) pmull_lo(x1, x0);
-    x1 = (uint64x2_t) pmull_hi(x1, x0);
-    x1 = veorq_u64(x1, x2);
-    x1 = veorq_u64(x1, x5);
-
-    x5 = (uint64x2_t) pmull_lo(x1, x0);
-    x1 = (uint64x2_t) pmull_hi(x1, x0);
-    x1 = veorq_u64(x1, x3);
-    x1 = veorq_u64(x1, x5);
-
-    x5 = (uint64x2_t) pmull_lo(x1, x0);
-    x1 = (uint64x2_t) pmull_hi(x1, x0);
-    x1 = veorq_u64(x1, x4);
-    x1 = veorq_u64(x1, x5);
-
-    /*
-     * Single fold blocks of 16, if any.
-     */
-    while (len >= 16)
-    {
-        x2 = vld1q_u64((const uint64_t *)buf);
-
-        x5 = (uint64x2_t) pmull_lo(x1, x0);
-        x1 = (uint64x2_t) pmull_hi(x1, x0);
-        x1 = veorq_u64(x1, x2);
-        x1 = veorq_u64(x1, x5);
-
-        buf += 16;
-        len -= 16;
-    }
-
-    /*
-     * Fold 128-bits to 64-bits.
-     */
-    static uint32_t zalign(16) mask[] = { ~0u, 0u, ~0u, 0u };
-
-    x2 = (uint64x2_t) pmull_01(x1, x0);
-    x1 = (uint64x2_t) vextq_u8(vreinterpretq_u8_u64(x1), vdupq_n_u8(0), 8);
-    x3 = (uint64x2_t) vld1q_u32(mask);
-    x1 = veorq_u64(x1, x2);
-
-    x0 = vld1q_u64(k5k0);
-
-    x2 = (uint64x2_t) pmull_01(x2, x0);
-    x2 = (uint64x2_t) vextq_u8(vreinterpretq_u8_u64(x1), vdupq_n_u8(0), 4);
-    x1 = vandq_u64(x1, x3);
-    x1 = (uint64x2_t) pmull_lo(x1, x0);
-    x1 = veorq_u64(x1, x2);
-
-    /*
-     * Barret reduce to 32-bits.
-     */
-    x0 = vld1q_u64(poly);
-
-    x2 = vandq_u64(x1, x3);
-    x2 = (uint64x2_t) pmull_01(x2, x0);
-    x2 = vandq_u64(x2, x3);
-    x2 = (uint64x2_t) pmull_lo(x2, x0);
-    x1 = veorq_u64(x1, x2);
-
-    /*
-     * Return the crc32.
-     */
-    return vgetq_lane_u32(vreinterpretq_u32_u64(x1), 1);
-}
-#endif /* aarch64 specific code. */
-
 #endif
diff --git a/third_party/zlib/crc32_simd.h b/third_party/zlib/crc32_simd.h
index 6985cbb..68bc235c 100644
--- a/third_party/zlib/crc32_simd.h
+++ b/third_party/zlib/crc32_simd.h
@@ -15,9 +15,10 @@
  * crc32_sse42_simd_(): compute the crc32 of the buffer, where the buffer
  * length must be at least 64, and a multiple of 16.
  */
-uint32_t ZLIB_INTERNAL crc32_sse42_simd_(const unsigned char* buf,
-                                         z_size_t len,
-                                         uint32_t crc);
+uint32_t ZLIB_INTERNAL crc32_sse42_simd_(
+    const unsigned char *buf,
+    z_size_t len,
+    uint32_t crc);
 
 /*
  * crc32_sse42_simd_ buffer size constraints: see the use in zlib/crc32.c
@@ -29,23 +30,7 @@
 /*
  * CRC32 checksums using ARMv8-a crypto instructions.
  */
-uint32_t ZLIB_INTERNAL armv8_crc32_little(const unsigned char* buf,
-                                          z_size_t len,
-                                          uint32_t crc);
+uint32_t ZLIB_INTERNAL armv8_crc32_little(unsigned long crc,
+                                          const unsigned char* buf,
+                                          z_size_t len);
 
-/* aarch64 specific code. */
-#if defined(__aarch64__)
-
-/* 128 is the sweet spot at the time of coding (late 2020). */
-#define Z_CRC32_PMULL_MINIMUM_LENGTH 128
-#define Z_CRC32_PMULL_CHUNKSIZE_MASK 15
-
-/*
- * CRC32 checksums using ARMv8-a PMULL instructions, where the buffer
- * length must be at least 64, and a multiple of 16.
- */
-uint32_t ZLIB_INTERNAL armv8_crc32_pmull_little(const unsigned char* buf,
-                                                z_size_t len,
-                                                uint32_t crc);
-
-#endif
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 43f7ff4..4a4b56a 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -13437,6 +13437,13 @@
   <int value="5" label="Path FileInfo Failed"/>
 </enum>
 
+<enum name="CacheTransparencyCacheNotUsedReason">
+  <int value="0" label="Trying Single Keyed Cache"/>
+  <int value="1" label="Incompatible Request Type"/>
+  <int value="2" label="Incompatible Request Load Flags"/>
+  <int value="3" label="Incompatible Request Headers"/>
+</enum>
+
 <enum name="CALayerResult">
   <int value="0" label="Success"/>
   <int value="1" label="Unknown failure"/>
@@ -55213,6 +55220,8 @@
   <int value="-1638815914" label="enable-experimental-productivity-features"/>
   <int value="-1637552275" label="NtpRealboxUseGoogleGIcon:disabled"/>
   <int value="-1636188191" label="IncognitoNtpRevamp:enabled"/>
+  <int value="-1635872214"
+      label="AutofillConsiderPlaceholderForParsing:disabled"/>
   <int value="-1635048938" label="DetectFormSubmissionOnFormClear:disabled"/>
   <int value="-1634878515" label="ChromeHomeModernLayout:enabled"/>
   <int value="-1634490190"
@@ -58868,6 +58877,8 @@
   <int value="761770770"
       label="OverrideLanguagePrefsForHrefTranslate:disabled"/>
   <int value="762700519" label="enable-checker-imaging"/>
+  <int value="763667542"
+      label="AutofillFillCreditCardAsPerFormatString:enabled"/>
   <int value="763947368" label="HomepageLocationPolicy:disabled"/>
   <int value="764508124" label="NavigationNetworkResponseQueue:disabled"/>
   <int value="765266228" label="TabGroupsCollapse:disabled"/>
@@ -58906,6 +58917,7 @@
   <int value="781785788" label="ClipboardSuggestionContentHidden:disabled"/>
   <int value="782167080" label="enable-new-qp-input-view"/>
   <int value="783270752" label="AndroidHistoryManager:enabled"/>
+  <int value="783502146" label="AutofillConsiderPlaceholderForParsing:enabled"/>
   <int value="785273919" label="CompositingBasedThrottling:disabled"/>
   <int value="787080596" label="DynamicTcmallocTuning:enabled"/>
   <int value="787385958" label="RegionalLocalesAsDisplayUI:enabled"/>
@@ -60091,6 +60103,8 @@
   <int value="1594993731" label="BluetoothRevamp:enabled"/>
   <int value="1595208893" label="AudioWorkletRealtimeThread:enabled"/>
   <int value="1596407332" label="EnableSavedDesks:enabled"/>
+  <int value="1596615083"
+      label="AutofillFillCreditCardAsPerFormatString:disabled"/>
   <int value="1597880096" label="FocusMode:disabled"/>
   <int value="1600850069" label="MobileIdentityConsistency:disabled"/>
   <int value="1600926040" label="TranslateCompactUI:enabled"/>
@@ -89531,17 +89545,6 @@
              profiling started"/>
 </enum>
 
-<enum name="StartupTabPreloaderLoadDecisionCause">
-  <int value="0" label="DisabledByIntent"/>
-  <int value="1" label="Incognito"/>
-  <int value="2" label="IntentIgnored"/>
-  <int value="3" label="NoUrl"/>
-  <int value="4" label="NoTabCreator"/>
-  <int value="5" label="WrongTabCreator"/>
-  <int value="6" label="DisabledByFeature"/>
-  <int value="7" label="AllSatisfied"/>
-</enum>
-
 <enum name="StartupTemperature">
   <int value="0" label="Cold startup (mostly hard faults)"/>
   <int value="1" label="Warm startup (nearly no hard faults)"/>
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml
index 1d4cf6e..0f592c52 100644
--- a/tools/metrics/histograms/metadata/android/histograms.xml
+++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -3046,147 +3046,6 @@
   </summary>
 </histogram>
 
-<histogram name="Android.StartupTabPreloader.ActivityStartToLoadDecision"
-    units="ms" expires_after="2022-11-06">
-  <owner>blundell@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    The time in a cold start between the start of the activity and the
-    triggerpoint for a startup tab being preloaded. Recorded only in startups
-    for which Android.Startup.Cold.TimeToFirstVisibleContent is being tracked.
-  </summary>
-</histogram>
-
-<histogram
-    name="Android.StartupTabPreloader.LoadDecisionToFirstContentfulPaint.{LoadAndMatchResult}"
-    units="ms" expires_after="2022-09-01">
-  <owner>blundell@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    The time in a cold start between the triggerpoint for a startup tab being
-    preloaded and Android.Startup.Cold.TimeToFirstContentfulPaint being
-    recorded, recorded in the case where a startup tab preload is determined
-    {LoadAndMatchResult}. In the case where the ElideTabPreloadAtStartup feature
-    is enabled, this metric will be segmented to reflect the state that would
-    have resulted if tab preloading was not disabled by the feature. Recorded
-    only in startups for which Android.Startup.Cold.TimeToFirstVisibleContent is
-    being tracked.
-  </summary>
-  <token key="LoadAndMatchResult">
-    <variant name="LoadAndMatch"
-        summary="to be viable and the preload is a match for the actual
-                 initial load"/>
-    <variant name="LoadAndMismatch"
-        summary="to be viable and the preload is not a match for the actual
-                 initial load"/>
-    <variant name="LoadPreMatch"
-        summary="to be viable and first contentful paint is recorded before
-                 it was determined whether the preload was a match for the
-                 actual initial load. Note that it is not expected that this
-                 case occurs in practice, but it is theoretically possible"/>
-    <variant name="NoLoad" summary="not to be viable"/>
-  </token>
-</histogram>
-
-<histogram
-    name="Android.StartupTabPreloader.LoadDecisionToFirstNavigationCommit.{LoadAndMatchResult}"
-    units="ms" expires_after="2022-09-01">
-  <owner>blundell@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    The time in a cold start between the triggerpoint for a startup tab being
-    preloaded and Android.Startup.Cold.TimeToFirstNavigationCommit being
-    recorded, recorded in the case where a startup tab preload is determined
-    {LoadAndMatchResult}. In the case where the ElideTabPreloadAtStartup feature
-    is enabled, this metric will be segmented to reflect the state that would
-    have resulted if tab preloading was not disabled by the feature.
-  </summary>
-  <token key="LoadAndMatchResult">
-    <variant name="LoadAndMatch"
-        summary="to be viable and the preload is a match for the actual
-                 initial load"/>
-    <variant name="LoadAndMismatch"
-        summary="to be viable and the preload is not a match for the actual
-                 initial load"/>
-    <variant name="LoadPreMatch"
-        summary="to be viable and first navigation commit is recorded before
-                 it was determined whether the preload was a match for the
-                 actual initial load. Note that it is not expected that this
-                 case occurs in practice, but it is theoretically possible"/>
-    <variant name="NoLoad" summary="not to be viable"/>
-  </token>
-</histogram>
-
-<histogram
-    name="Android.StartupTabPreloader.LoadDecisionToFirstNavigationStart.{LoadDecision}"
-    units="ms" expires_after="2022-09-01">
-  <owner>blundell@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    The time in a cold start between the triggerpoint for a startup tab being
-    preloaded and first navigation start, recorded in the case where a startup
-    tab preload is determined {LoadDecision} viable. In the case where the
-    ElideTabPreloadAtStartup feature is enabled, this metric will be segmented
-    to reflect the state that would have resulted if tab preloading was not
-    disabled by the feature. Recorded only for startups in which
-    Android.Startup.Cold.TimeToFirstNavigationCommit is recorded for ability to
-    compare with that metric and its derived metrics.
-  </summary>
-  <token key="LoadDecision">
-    <variant name="Load" summary="to be"/>
-    <variant name="NoLoad" summary="not to be"/>
-  </token>
-</histogram>
-
-<histogram
-    name="Android.StartupTabPreloader.LoadDecisionToFirstVisibleContent.{LoadAndMatchResult}"
-    units="ms" expires_after="2022-09-01">
-  <owner>blundell@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    The time in a cold start between the triggerpoint for a startup tab being
-    preloaded and Android.Startup.Cold.TimeToFirstVisibleContent being recorded,
-    recorded in the case where a startup tab preload is determined
-    {LoadAndMatchResult}. In the case where the ElideTabPreloadAtStartup feature
-    is enabled, this metric will be segmented to reflect the state that would
-    have resulted if tab preloading was not disabled by the feature.
-  </summary>
-  <token key="LoadAndMatchResult">
-    <variant name="LoadAndMatch"
-        summary="to be viable and the preload is a match for the actual
-                 initial load"/>
-    <variant name="LoadAndMismatch"
-        summary="to be viable and the preload is not a match for the actual
-                 initial load"/>
-    <variant name="LoadPreMatch"
-        summary="to be viable and first visible content is recorded before it
-                 was determined whether the preload was a match for the
-                 actual initial load. Note that it is not expected that this
-                 case occurs in practice, but it is theoretically possible"/>
-    <variant name="NoLoad" summary="not to be viable"/>
-  </token>
-</histogram>
-
-<histogram
-    name="Android.StartupTabPreloader.LoadDecisionToMatchDecision.{LoadDecision}"
-    units="ms" expires_after="2022-09-01">
-  <owner>blundell@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    The time in a cold start between the triggerpoint for a startup tab being
-    preloaded and the decision being made on whether the preload is a match for
-    the information of the actual initial load that needs to occur, recorded in
-    the case where a startup tab preload is determined {LoadDecision} viable. In
-    the case where the ElideTabPreloadAtStartup feature is enabled, this metric
-    will be segmented to reflect the state that would have resulted if tab
-    preloading was not disabled by the feature.
-  </summary>
-  <token key="LoadDecision">
-    <variant name="Load" summary="to be"/>
-    <variant name="NoLoad" summary="not to be"/>
-  </token>
-</histogram>
-
 <histogram name="Android.StrictMode.OverrideUrlLoadingTime" units="ms"
     expires_after="2022-10-30">
   <owner>yfriedman@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/network/histograms.xml b/tools/metrics/histograms/metadata/network/histograms.xml
index 748bc83..8ddbcb1f 100644
--- a/tools/metrics/histograms/metadata/network/histograms.xml
+++ b/tools/metrics/histograms/metadata/network/histograms.xml
@@ -132,6 +132,65 @@
   </token>
 </histogram>
 
+<histogram name="Network.CacheTransparency.CacheNotUsed"
+    enum="CacheTransparencyCacheNotUsedReason" expires_after="2022-11-01">
+  <owner>nidhijaju@chromium.org</owner>
+  <owner>ricea@chromium.org</owner>
+  <summary>
+    Records why a URL does not use the single-keyed cache due to a reason in
+    //services/network, when a URL request is made. Reasons include different
+    request type (i.e. not GET), incompatible request load flags, incompatible
+    request headers, etc.
+  </summary>
+</histogram>
+
+<histogram name="Network.CacheTransparency.MarkedUnusable" units="list index"
+    expires_after="2022-11-01">
+  <owner>nidhijaju@chromium.org</owner>
+  <owner>ricea@chromium.org</owner>
+  <summary>
+    Records whether a URL in the pervasive payloads list is marked as
+    &quot;unusable&quot; when the cached response is read. The list index is the
+    index of the URL in the pervasive payloads list.
+  </summary>
+</histogram>
+
+<histogram name="Network.CacheTransparency.MismatchedChecksums"
+    units="list index" expires_after="2022-11-01">
+  <owner>nidhijaju@chromium.org</owner>
+  <owner>ricea@chromium.org</owner>
+  <summary>
+    Records whether a URL in the pervasive payloads list has a different
+    checksum than what is expected when the response checksums are compared in
+    HttpCache::Transaction. The list index is the index of the URL in the
+    pervasive payloads list.
+  </summary>
+</histogram>
+
+<histogram name="Network.CacheTransparency.SingleKeyedCacheIsUsed"
+    units="list index" expires_after="2022-11-01">
+  <owner>nidhijaju@chromium.org</owner>
+  <owner>ricea@chromium.org</owner>
+  <summary>
+    Records whether the single-keyed cache is used for a URL in the pervasive
+    payloads list (not just when a cache entry is hit because there could be an
+    &quot;unusable&quot; flag set). This is recorded when the response checksum
+    matches the expected checksum in HttpCache::Transaction. The list index is
+    the index of the URL in the pervasive payloads list.
+  </summary>
+</histogram>
+
+<histogram name="Network.CacheTransparency.URLMatched" units="list index"
+    expires_after="2022-11-01">
+  <owner>nidhijaju@chromium.org</owner>
+  <owner>ricea@chromium.org</owner>
+  <summary>
+    Records whether a requested resource's URL matched with any of the URLs in
+    the pervasive payloads list when a URL request is made. The list index is
+    the index of the URL in the pervasive payloads list.
+  </summary>
+</histogram>
+
 <histogram name="Network.Cellular.Apn.UseAttachApnOnSave" enum="Boolean"
     expires_after="2022-05-18">
   <owner>hsuregan@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/startup/histograms.xml b/tools/metrics/histograms/metadata/startup/histograms.xml
index 57a6214..810df945 100644
--- a/tools/metrics/histograms/metadata/startup/histograms.xml
+++ b/tools/metrics/histograms/metadata/startup/histograms.xml
@@ -330,43 +330,6 @@
   </summary>
 </histogram>
 
-<histogram name="Startup.Android.StartupTabPreloader.LoadDecisionReason"
-    enum="StartupTabPreloaderLoadDecisionCause" expires_after="2022-11-06">
-  <owner>blundell@chromium.org</owner>
-  <owner>yfriedman@chromium.org</owner>
-  <summary>
-    Android: Gives the reason for StartupTabPreloader's decision of whether to
-    load a tab at startup. As reasons for not doing a startup tab preload are
-    not necessarily orthogonal, gives highest-priority reason (see computation
-    of metric in the codebase). Recorded when a profile is created, assuming a
-    StartupTabPreloader has been constructed for intents with a url and either
-    regular Chrome or a Custom Tab will be loaded.
-  </summary>
-</histogram>
-
-<histogram name="Startup.Android.StartupTabPreloader.TabLoaded" units="Boolean"
-    expires_after="2022-11-06">
-  <owner>skyostil@chromium.org</owner>
-  <summary>
-    Android: Whether or not creation of a profile lead to the
-    StartupTabPreloader speculatively created a tab. Recorded when a profile is
-    created, assuming a StartupTabPreloader has been constructed for intents
-    with a url and either regular Chrome or a Custom Tab will be loaded.
-  </summary>
-</histogram>
-
-<histogram name="Startup.Android.StartupTabPreloader.TabTaken" units="Boolean"
-    expires_after="2022-11-06">
-  <owner>skyostil@chromium.org</owner>
-  <summary>
-    Android: Whether or not a tab speculatively created by the
-    StartupTabPreloader was subsequently adopted by ChromeTabCreator. Recorded
-    when a tab is loaded, assuming a StartupTabPreloader has been constructed
-    for intents with a url for either regular Chrome or a Custom Tab will be
-    loaded. Warning: this histogram was expired from 2020-11-08 through M95.
-  </summary>
-</histogram>
-
 <histogram name="Startup.Android.ThumbnailFetchedForGTSFirstMeaningfulPaint"
     units="thumbnails" expires_after="2020-08-02">
   <owner>yusufo@chromium.org</owner>
diff --git a/ui/chromeos/styles/cros_colors.json5 b/ui/chromeos/styles/cros_colors.json5
index 0c37fd4..5ab5c77e 100644
--- a/ui/chromeos/styles/cros_colors.json5
+++ b/ui/chromeos/styles/cros_colors.json5
@@ -192,8 +192,8 @@
      * Other foundational colors.
      */
     focus_ring_color: {
-      light: "$color_prominent",
-      dark: "$color_prominent",
+      light: "$color_prominent_light",
+      dark: "$color_prominent_dark",
       generate_per_mode: true,
     },
     focus_ring_color_inactive: "$icon_color_secondary",
diff --git a/ui/file_manager/file_manager/background/js/BUILD.gn b/ui/file_manager/file_manager/background/js/BUILD.gn
index b1581a7..dbc4ca5 100644
--- a/ui/file_manager/file_manager/background/js/BUILD.gn
+++ b/ui/file_manager/file_manager/background/js/BUILD.gn
@@ -372,6 +372,9 @@
     "//ui/webui/resources/js:assert.m",
     "//ui/webui/resources/js/cr:event_target.m",
   ]
+  visibility += [
+    "//ui/file_manager/file_manager/foreground/js:directory_model_unittest.m",
+  ]
 }
 
 js_library("file_operation_manager") {
@@ -380,6 +383,7 @@
     ":metadata_proxy",
     ":trash",
     ":volume_manager_factory",
+    "//ui/file_manager/file_manager/common/js:api",
     "//ui/file_manager/file_manager/common/js:async_util",
     "//ui/file_manager/file_manager/common/js:file_operation_common",
     "//ui/file_manager/file_manager/common/js:trash",
diff --git a/ui/file_manager/file_manager/background/js/file_operation_manager.js b/ui/file_manager/file_manager/background/js/file_operation_manager.js
index c29e5a1..7d2cf6d 100644
--- a/ui/file_manager/file_manager/background/js/file_operation_manager.js
+++ b/ui/file_manager/file_manager/background/js/file_operation_manager.js
@@ -4,6 +4,7 @@
 
 import {assert} from 'chrome://resources/js/assert.m.js';
 
+import {startIOTask} from '../../common/js/api.js';
 import {AsyncUtil} from '../../common/js/async_util.js';
 import {FileOperationError, FileOperationProgressEvent} from '../../common/js/file_operation_common.js';
 import {TrashEntry, TrashRootEntry} from '../../common/js/trash.js';
@@ -452,8 +453,7 @@
   deleteEntries(entries, permanentlyDelete = false) {
     if (permanentlyDelete) {
       if (window.isSWA) {
-        chrome.fileManagerPrivate.startIOTask(
-            chrome.fileManagerPrivate.IOTaskType.DELETE, entries, {});
+        startIOTask(chrome.fileManagerPrivate.IOTaskType.DELETE, entries, {});
         return;
       }
     }
diff --git a/ui/file_manager/file_manager/background/js/mock_file_operation_manager.js b/ui/file_manager/file_manager/background/js/mock_file_operation_manager.js
index 38450c9..8a292ff2 100644
--- a/ui/file_manager/file_manager/background/js/mock_file_operation_manager.js
+++ b/ui/file_manager/file_manager/background/js/mock_file_operation_manager.js
@@ -94,13 +94,23 @@
     return this.generatedTaskIds.indexOf(id) !== -1;
   }
 
-  hasQueuedTasks() {}
-  filterSameDirectoryEntry() {}
-  willUseTrash() {}
+  /** @return {boolean} */
+  hasQueuedTasks() {
+    throw new Error('Not implemented');
+  }
+  /** @return {Promise} */
+  filterSameDirectoryEntry(sourceEntries, targetEntry, isMove) {}
+  /** @return {boolean} */
+  willUseTrash(volumeManager, entries) {
+    throw new Error('Not implemented');
+  }
   deleteEntries() {}
   restoreDeleted() {}
   emptyTrash() {}
   zipSelection() {}
   cancelZip() {}
-  async writeFile() {}
+  /** @return {!Promise<!FileEntry>} */
+  async writeFile(file, destination) {
+    throw new Error('Not implemented');
+  }
 }
diff --git a/ui/file_manager/file_manager/background/js/mock_volume_manager.js b/ui/file_manager/file_manager/background/js/mock_volume_manager.js
index 6016e48f..522aaf1 100644
--- a/ui/file_manager/file_manager/background/js/mock_volume_manager.js
+++ b/ui/file_manager/file_manager/background/js/mock_volume_manager.js
@@ -117,9 +117,14 @@
    */
   getLocationInfo(entry) {
     if (util.isFakeEntry(entry)) {
+      const isReadOnly =
+          entry.rootType === VolumeManagerCommon.RootType.RECENT ?
+          !util.isRecentsFilterV2Enabled() :
+          true;
       return new EntryLocationImpl(
           this.volumeInfoList.item(0),
-          /** @type {!FakeEntry} */ (entry).rootType, true, true);
+          /** @type {!FakeEntry} */ (entry).rootType, /* isRootType= */ true,
+          isReadOnly);
     }
 
     if (entry.filesystem.name === VolumeManagerCommon.VolumeType.DRIVE) {
@@ -223,6 +228,9 @@
     return volumeInfo;
   }
 
+  /**
+   * @return {!Promise<!VolumeInfo>}
+   */
   async mountArchive(fileUrl, password) {
     throw new Error('Not implemented');
   }
@@ -235,7 +243,7 @@
     throw new Error('Not implemented');
   }
 
-  configure(volumeInfo) {
+  async configure(volumeInfo) {
     throw new Error('Not implemented');
   }
 
@@ -247,6 +255,9 @@
     throw new Error('Not implemented');
   }
 
+  /**
+   * @return {boolean}
+   */
   dispatchEvent(event) {
     throw new Error('Not implemented');
   }
diff --git a/ui/file_manager/file_manager/background/js/volume_manager_impl.js b/ui/file_manager/file_manager/background/js/volume_manager_impl.js
index 950c4c5..dee63e3 100644
--- a/ui/file_manager/file_manager/background/js/volume_manager_impl.js
+++ b/ui/file_manager/file_manager/background/js/volume_manager_impl.js
@@ -397,10 +397,13 @@
     const volumeInfo = this.getVolumeInfo(entry);
 
     if (util.isFakeEntry(entry)) {
+      const isReadOnly =
+          entry.rootType === VolumeManagerCommon.RootType.RECENT ?
+          !util.isRecentsFilterV2Enabled() :
+          true;
       return new EntryLocationImpl(
           volumeInfo, assert(entry.rootType),
-          true /* the entry points a root directory. */,
-          true /* fake entries are read only. */);
+          true /* The entry points a root directory. */, isReadOnly);
     }
 
     if (!volumeInfo) {
diff --git a/ui/file_manager/file_manager/common/js/api.js b/ui/file_manager/file_manager/common/js/api.js
index ee304bc0..675ddfea 100644
--- a/ui/file_manager/file_manager/common/js/api.js
+++ b/ui/file_manager/file_manager/common/js/api.js
@@ -191,3 +191,16 @@
     return '#ffffff';
   }
 }
+
+/**
+ * Starts an IOTask of `type` and returns a taskId that can be used to cancel
+ * or identify the ongoing IO operation.
+ * @param {!chrome.fileManagerPrivate.IOTaskType} type
+ * @param {!Array<!Entry>} entries
+ * @param {!chrome.fileManagerPrivate.IOTaskParams} params
+ * @returns {!Promise<!number>}
+ */
+export async function startIOTask(type, entries, params) {
+  return promisify(
+      chrome.fileManagerPrivate.startIOTask, type, entries, params);
+}
diff --git a/ui/file_manager/file_manager/common/js/volume_manager_types.js b/ui/file_manager/file_manager/common/js/volume_manager_types.js
index 964deae..8f81cdf 100644
--- a/ui/file_manager/file_manager/common/js/volume_manager_types.js
+++ b/ui/file_manager/file_manager/common/js/volume_manager_types.js
@@ -446,6 +446,14 @@
 VolumeManagerCommon.PHOTOS_DOCUMENTS_PROVIDER_VOLUME_ID =
     'documents_provider:com.google.android.apps.photos.photoprovider/com.google.android.apps.photos';
 
+/**
+ * ID of the MediaDocumentsProvider. All the files returned by ARC source in
+ * Recents have this ID prefix in their filesystem.
+ * @const {string}
+ */
+VolumeManagerCommon.MEDIA_DOCUMENTS_PROVIDER_ID =
+    'com.android.providers.media.documents';
+
 
 /**
  * Creates an CustomEvent object for changing current directory when an archive
@@ -460,4 +468,17 @@
       {detail: {mountPoint: mountPoint}});
 };
 
+/**
+ * Checks if a file entry is a Recent entry coming from ARC source.
+ * @param {?Entry} entry
+ * @return {boolean}
+ */
+VolumeManagerCommon.isRecentArcEntry = entry => {
+  if (!entry) {
+    return false;
+  }
+  return entry.filesystem.name.startsWith(
+      VolumeManagerCommon.MEDIA_DOCUMENTS_PROVIDER_ID);
+};
+
 export {VolumeManagerCommon};
diff --git a/ui/file_manager/file_manager/common/js/volume_manager_types_unittest.m.js b/ui/file_manager/file_manager/common/js/volume_manager_types_unittest.m.js
index 468c92d51..b549024 100644
--- a/ui/file_manager/file_manager/common/js/volume_manager_types_unittest.m.js
+++ b/ui/file_manager/file_manager/common/js/volume_manager_types_unittest.m.js
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {assertTrue} from 'chrome://test/chai_assert.js';
+import {assertFalse, assertTrue} from 'chrome://test/chai_assert.js';
+
+import {MockFileEntry, MockFileSystem} from './mock_entry.js';
 import {VolumeManagerCommon} from './volume_manager_types.js';
 
 // Test that every volumeType has a rootType, and that it maps back to the same
@@ -55,3 +57,17 @@
     assertTrue(volumeType !== undefined);
   });
 }
+
+// Tests that IsRecentArcEntry() should return true/false if an entry belongs/
+// doesn't belong to recent.
+export function testIsRecentArcEntry() {
+  assertFalse(VolumeManagerCommon.isRecentArcEntry(null));
+  const otherEntry = MockFileEntry.create(
+      new MockFileSystem('download:Downloads'), 'test.txt');
+  assertFalse(VolumeManagerCommon.isRecentArcEntry(otherEntry));
+  const recentEntry = MockFileEntry.create(
+      new MockFileSystem(
+          'com.android.providers.media.documents:documents_root'),
+      'Documents/abc.pdf');
+  assertTrue(VolumeManagerCommon.isRecentArcEntry(recentEntry));
+}
diff --git a/ui/file_manager/file_manager/foreground/js/BUILD.gn b/ui/file_manager/file_manager/foreground/js/BUILD.gn
index c605af9..d28685b 100644
--- a/ui/file_manager/file_manager/foreground/js/BUILD.gn
+++ b/ui/file_manager/file_manager/foreground/js/BUILD.gn
@@ -446,6 +446,20 @@
   ]
 }
 
+js_unittest("directory_model_unittest.m") {
+  deps = [
+    ":directory_contents",
+    ":directory_model",
+    "metadata:mock_metadata",
+    "//chrome/test/data/webui:chai_assert",
+    "//ui/file_manager/file_manager/background/js:mock_file_operation_manager",
+    "//ui/file_manager/file_manager/background/js:mock_volume_manager",
+    "//ui/file_manager/file_manager/common/js:mock_chrome",
+    "//ui/file_manager/file_manager/common/js:volume_manager_types",
+    "//ui/webui/resources/js:load_time_data.m",
+  ]
+}
+
 js_library("navigation_uma") {
   deps = [
     "//ui/file_manager/file_manager/common/js:metrics",
@@ -622,6 +636,7 @@
     ":webui_command_extender",
     "ui:directory_tree",
     "ui:files_confirm_dialog",
+    "//ui/file_manager/file_manager/common/js:api",
     "//ui/file_manager/file_manager/common/js:dialog_type",
     "//ui/file_manager/file_manager/common/js:file_operation_common",
     "//ui/file_manager/file_manager/common/js:file_type",
@@ -742,6 +757,7 @@
     "ui:directory_tree",
     "ui:drag_selector",
     "ui:list_container",
+    "//ui/file_manager/file_manager/common/js:api",
     "//ui/file_manager/file_manager/common/js:file_type",
     "//ui/file_manager/file_manager/common/js:progress_center_common",
     "//ui/file_manager/file_manager/common/js:util",
@@ -1329,6 +1345,7 @@
     ":banner_controller_unittest.m",
     ":banner_util_unittest.m",
     ":directory_contents_unittest.m",
+    ":directory_model_unittest.m",
     ":file_list_model_unittest.m",
     ":file_manager_commands_unittest.m",
     ":file_tasks_unittest.m",
diff --git a/ui/file_manager/file_manager/foreground/js/directory_contents.js b/ui/file_manager/file_manager/foreground/js/directory_contents.js
index ea1f3f99..b20cbb6a 100644
--- a/ui/file_manager/file_manager/foreground/js/directory_contents.js
+++ b/ui/file_manager/file_manager/foreground/js/directory_contents.js
@@ -37,8 +37,13 @@
    * @param {function()} successCallback Called when the scan is completed
    *     successfully.
    * @param {function(DOMError)} errorCallback Called an error occurs.
+   * @param {boolean=} invalidateCache True to invalidate the backend scanning
+   *     result cache. This param only works if the corresponding backend
+   *     scanning supports cache.
    */
-  async scan(entriesCallback, successCallback, errorCallback) {}
+  async scan(
+      entriesCallback, successCallback, errorCallback,
+      invalidateCache = false) {}
 
   /**
    * Request cancelling of the running scan. When the cancelling is done,
@@ -65,7 +70,9 @@
    * Starts to read the entries in the directory.
    * @override
    */
-  async scan(entriesCallback, successCallback, errorCallback) {
+  async scan(
+      entriesCallback, successCallback, errorCallback,
+      invalidateCache = false) {
     if (!this.entry_ || !this.entry_.createReader) {
       // If entry is not specified or if entry doesn't implement createReader,
       // we cannot read it.
@@ -113,7 +120,9 @@
    * Starts to search on Drive File System.
    * @override
    */
-  async scan(entriesCallback, successCallback, errorCallback) {
+  async scan(
+      entriesCallback, successCallback, errorCallback,
+      invalidateCache = false) {
     // Let's give another search a chance to cancel us before we begin.
     setTimeout(() => {
       // Check cancelled state before read the entries.
@@ -193,7 +202,9 @@
    * Starts the file name search.
    * @override
    */
-  async scan(entriesCallback, successCallback, errorCallback) {
+  async scan(
+      entriesCallback, successCallback, errorCallback,
+      invalidateCache = false) {
     util.readEntriesRecursively(assert(this.entry_), (entries) => {
       const matchEntries = entries.filter(
           entry => entry.name.toLowerCase().indexOf(this.query_) >= 0);
@@ -222,7 +233,9 @@
    * Starts to metadata-search on Drive File System.
    * @override
    */
-  async scan(entriesCallback, successCallback, errorCallback) {
+  async scan(
+      entriesCallback, successCallback, errorCallback,
+      invalidateCache = false) {
     chrome.fileManagerPrivate.searchDriveMetadata(
         {query: '', types: this.searchType_, maxResults: 100}, results => {
           if (chrome.runtime.lastError) {
@@ -282,9 +295,12 @@
   /**
    * @override
    */
-  async scan(entriesCallback, successCallback, errorCallback) {
+  async scan(
+      entriesCallback, successCallback, errorCallback,
+      invalidateCache = false) {
     chrome.fileManagerPrivate.getRecentFiles(
-        this.sourceRestriction_, this.recentFileType_, entries => {
+        this.sourceRestriction_, this.recentFileType_, invalidateCache,
+        entries => {
           if (chrome.runtime.lastError) {
             console.error(chrome.runtime.lastError.message);
             errorCallback(
@@ -320,11 +336,13 @@
    * hierarchy. We need to list files under the root directory to provide
    * flatten view. A file will not be shown in multiple directories in
    * media-view hierarchy since no folders will be added in media documents
-   * provider. We can list all files without duplication by just retrieveing
+   * provider. We can list all files without duplication by just retrieving
    * files in directories recursively.
    * @override
    */
-  async scan(entriesCallback, successCallback, errorCallback) {
+  async scan(
+      entriesCallback, successCallback, errorCallback,
+      invalidateCache = false) {
     // To provide flatten view of files, this media-view scanner retrieves files
     // in directories inside the media's root entry recursively.
     util.readEntriesRecursively(
@@ -351,7 +369,9 @@
   /**
    * @override
    */
-  async scan(entriesCallback, successCallback, errorCallback) {
+  async scan(
+      entriesCallback, successCallback, errorCallback,
+      invalidateCache = false) {
     chrome.fileManagerPrivate.mountCrostini(() => {
       if (chrome.runtime.lastError) {
         console.error(
@@ -390,7 +410,9 @@
   /**
    * @override
    */
-  async scan(entriesCallback, successCallback, errorCallback) {
+  async scan(
+      entriesCallback, successCallback, errorCallback,
+      invalidateCache = false) {
     try {
       await mountGuest(this.guest_id_);
       successCallback();
@@ -790,8 +812,11 @@
    *
    * @param {boolean} refresh True to refresh metadata, or false to use cached
    *     one.
+   * @param {boolean} invalidateCache True to invalidate the backend scanning
+   *     result cache. This param only works if the corresponding backend
+   *     scanning supports cache.
    */
-  scan(refresh) {
+  scan(refresh, invalidateCache) {
     /**
      * Invoked when the scanning is completed successfully.
      * @this {DirectoryContents}
@@ -818,7 +843,7 @@
     this.scanner_ = this.scannerFactory_();
     this.scanner_.scan(
         this.onNewEntries_.bind(this, refresh), completionCallback.bind(this),
-        errorCallback.bind(this));
+        errorCallback.bind(this), invalidateCache);
   }
 
   /**
diff --git a/ui/file_manager/file_manager/foreground/js/directory_model.js b/ui/file_manager/file_manager/foreground/js/directory_model.js
index e1c10eb6..a18a988 100644
--- a/ui/file_manager/file_manager/foreground/js/directory_model.js
+++ b/ui/file_manager/file_manager/foreground/js/directory_model.js
@@ -114,6 +114,12 @@
     this.fileWatcher_.addEventListener(
         'watcher-directory-changed',
         this.onWatcherDirectoryChanged_.bind(this));
+    // For non-watchable directory (e.g. FakeEntry), we need to subscribe to
+    // the IOTask and manually refresh.
+    if (util.isRecentsFilterV2Enabled()) {
+      chrome.fileManagerPrivate.onIOTaskProgressStatus.addListener(
+          this.updateFileListAfterIOTask_.bind(this));
+    }
     util.addEventListenerToBackgroundComponent(
         fileOperationManager, 'entries-changed',
         this.onEntriesChanged_.bind(this));
@@ -368,7 +374,7 @@
           });
     } else {
       // Invokes force refresh if the detailed information isn't provided.
-      // This can occur very frequently (e.g. when copying files into Downlaods)
+      // This can occur very frequently (e.g. when copying files into Downloads)
       // and rescan is heavy operation, so we keep some interval for each
       // rescan.
       this.rescanAggregator_.run();
@@ -484,9 +490,12 @@
    * Schedule rescan with short delay.
    * @param {boolean} refresh True to refresh metadata, or false to use cached
    *     one.
+   * @param {boolean=} invalidateCache True to invalidate the backend scanning
+   *     result cache. This param only works if the corresponding backend
+   *     scanning supports cache.
    */
-  rescanSoon(refresh) {
-    this.scheduleRescan(SHORT_RESCAN_INTERVAL, refresh);
+  rescanSoon(refresh, invalidateCache = false) {
+    this.scheduleRescan(SHORT_RESCAN_INTERVAL, refresh, invalidateCache);
   }
 
   /**
@@ -494,9 +503,12 @@
    * notification.
    * @param {boolean} refresh True to refresh metadata, or false to use cached
    *     one.
+   * @param {boolean=} invalidateCache True to invalidate the backend scanning
+   *     result cache. This param only works if the corresponding backend
+   *     scanning supports cache.
    */
-  rescanLater(refresh) {
-    this.scheduleRescan(SIMULTANEOUS_RESCAN_INTERVAL, refresh);
+  rescanLater(refresh, invalidateCache = false) {
+    this.scheduleRescan(SIMULTANEOUS_RESCAN_INTERVAL, refresh, invalidateCache);
   }
 
   /**
@@ -506,8 +518,11 @@
    * @param {number} delay Delay in ms after which the rescan will be performed.
    * @param {boolean} refresh True to refresh metadata, or false to use cached
    *     one.
+   * @param {boolean=} invalidateCache True to invalidate the backend scanning
+   *     result cache. This param only works if the corresponding backend
+   *     scanning supports cache.
    */
-  scheduleRescan(delay, refresh) {
+  scheduleRescan(delay, refresh, invalidateCache = false) {
     if (this.rescanTime_) {
       if (this.rescanTime_ <= Date.now() + delay) {
         return;
@@ -521,7 +536,7 @@
     this.rescanTimeoutId_ = setTimeout(() => {
       this.rescanTimeoutId_ = null;
       if (sequence === this.changeDirectorySequence_) {
-        this.rescan(refresh);
+        this.rescan(refresh, invalidateCache);
       }
     }, delay);
   }
@@ -548,8 +563,11 @@
    *
    * @param {boolean} refresh True to refresh metadata, or false to use cached
    *     one.
+   * @param {boolean=} invalidateCache True to invalidate the backend scanning
+   *     result cache. This param only works if the corresponding backend
+   *     scanning supports cache.
    */
-  rescan(refresh) {
+  rescan(refresh, invalidateCache = false) {
     this.clearRescanTimeout_();
     if (this.runningScan_) {
       this.pendingRescan_ = true;
@@ -571,7 +589,8 @@
     };
 
     this.scan_(
-        dirContents, refresh, successCallback, () => {}, () => {}, () => {});
+        dirContents, refresh, invalidateCache, successCallback, () => {},
+        () => {}, () => {});
   }
 
   /**
@@ -678,7 +697,7 @@
     dispatchSimpleEvent(this, 'scan-started');
     fileList.splice(0, fileList.length);
     this.scan_(
-        this.currentDirContents_, false, onDone, onFailed, onUpdated,
+        this.currentDirContents_, false, true, onDone, onFailed, onUpdated,
         onCancelled);
   }
 
@@ -747,6 +766,7 @@
    *     the scan will be run.
    * @param {boolean} refresh True to refresh metadata, or false to use cached
    *     one.
+   * @param {boolean} invalidateCache True to invalidate scanning result cache.
    * @param {function()} successCallback Callback on success.
    * @param {function(DOMError)} failureCallback Callback on failure.
    * @param {function()} updatedCallback Callback on update. Only on the last
@@ -755,10 +775,8 @@
    * @private
    */
   scan_(
-      dirContents, refresh, successCallback, failureCallback, updatedCallback,
-      cancelledCallback) {
-    const self = this;
-
+      dirContents, refresh, invalidateCache, successCallback, failureCallback,
+      updatedCallback, cancelledCallback) {
     /**
      * Runs pending scan if there is one.
      *
@@ -837,7 +855,7 @@
     dirContents.addEventListener('scan-updated', updatedCallback);
     dirContents.addEventListener('scan-failed', onFailure);
     dirContents.addEventListener('scan-cancelled', onCancelled);
-    dirContents.scan(refresh);
+    dirContents.scan(refresh, invalidateCache);
   }
 
   /**
@@ -1593,4 +1611,33 @@
       this.onClearSearch_ = null;
     }
   }
+
+  /**
+   * Update the file list when curtain IO task is finished. Fake directory
+   * entries like RecentEntry is not watchable, to keep the file list
+   * refresh, we need to explicitly subscribe to the IO task status event, and
+   * manually refresh.
+   * @param {!chrome.fileManagerPrivate.ProgressStatus} event
+   * @private
+   */
+  updateFileListAfterIOTask_(event) {
+    /** @type {!Set<!chrome.fileManagerPrivate.IOTaskType>} */
+    const eventTypesRequireRefresh = new Set([
+      chrome.fileManagerPrivate.IOTaskType.DELETE,
+      chrome.fileManagerPrivate.IOTaskType.MOVE,
+    ]);
+    /** @type {!Set<?VolumeManagerCommon.RootType>} */
+    const rootTypesRequireRefresh =
+        new Set([VolumeManagerCommon.RootType.RECENT]);
+
+    const currentRootType = this.getCurrentRootType();
+    if (!rootTypesRequireRefresh.has(currentRootType)) {
+      return;
+    }
+    const isIOTaskFinished =
+        event.state === chrome.fileManagerPrivate.IOTaskState.SUCCESS;
+    if (isIOTaskFinished && eventTypesRequireRefresh.has(event.type)) {
+      this.rescanLater(/* refresh= */ false, /* invalidateCache= */ true);
+    }
+  }
 }
diff --git a/ui/file_manager/file_manager/foreground/js/directory_model_unittest.m.js b/ui/file_manager/file_manager/foreground/js/directory_model_unittest.m.js
new file mode 100644
index 0000000..60358bf
--- /dev/null
+++ b/ui/file_manager/file_manager/foreground/js/directory_model_unittest.m.js
@@ -0,0 +1,130 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
+import {assertFalse, assertTrue} from 'chrome://test/chai_assert.js';
+
+import {MockFileOperationManager} from '../../background/js/mock_file_operation_manager.js';
+import {MockVolumeManager} from '../../background/js/mock_volume_manager.js';
+import {installMockChrome} from '../../common/js/mock_chrome.js';
+import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js';
+
+import {FileFilter} from './directory_contents.js';
+import {DirectoryModel} from './directory_model.js';
+import {MockMetadataModel} from './metadata/mock_metadata.js';
+
+/**
+ * @type {?function(!chrome.fileManagerPrivate.ProgressStatus):void}
+ */
+let onIOTaskProgressStatusCallback;
+
+/**
+ * Initializes the test environment.
+ */
+export function setUp() {
+  // Mock loadTimeData strings.
+  loadTimeData.resetForTesting({
+    DRIVE_DIRECTORY_LABEL: 'Google Drive',
+    DRIVE_OFFLINE_COLLECTION_LABEL: 'Offline',
+    DRIVE_SHARED_WITH_ME_COLLECTION_LABEL: 'Shared with me',
+    DOWNLOADS_DIRECTORY_LABEL: 'Downloads',
+    FILTERS_IN_RECENTS_V2_ENABLED: true,
+  });
+
+  /**
+   * Mock chrome APIs.
+   * @type {!Object}
+   */
+  const mockChrome = {
+    fileManagerPrivate: {
+      SourceRestriction: {
+        ANY_SOURCE: 'any_source',
+      },
+      RecentFileType: {
+        ALL: 'all',
+      },
+      SearchType: {
+        EXCLUDE_DIRECTORIES: 'EXCLUDE_DIRECTORIES',
+        SHARED_WITH_ME: 'SHARED_WITH_ME',
+        OFFLINE: 'OFFLINE',
+        ALL: 'ALL',
+      },
+      DriveConnectionStateType: {
+        OFFLINE: 'OFFLINE',
+      },
+      onIOTaskProgressStatus: {
+        /**
+         * @param {?function(!chrome.fileManagerPrivate.ProgressStatus):void}
+         *     callback
+         */
+        addListener(callback) {
+          onIOTaskProgressStatusCallback = callback;
+        }
+      },
+      IOTaskType: {
+        DELETE: 'delete',
+        COPY: 'copy',
+      },
+      IOTaskState: {
+        SUCCESS: 'success',
+      },
+      onDirectoryChanged: {addListener(callback) {}},
+      getRecentFiles: () => {},
+    },
+  };
+
+  // Install mock chrome APIs.
+  installMockChrome(mockChrome);
+}
+
+/**
+ * Mock DirectoryModel's dependencies and return a DirectoryModel instance.
+ *
+ * @returns {!DirectoryModel}
+ */
+function getDirectoryModel() {
+  const volumeManager = new MockVolumeManager();
+  MockVolumeManager.installMockSingleton(volumeManager);
+  const fileFilter = new FileFilter(volumeManager);
+  const metadataModel = new MockMetadataModel({});
+  const fileOperationManager = new MockFileOperationManager();
+  return new DirectoryModel(
+      false, fileFilter, metadataModel, volumeManager, fileOperationManager);
+}
+
+/**
+ * Tests that the directory will be re-scanned after the delete operation.
+ */
+export function testRecanAfterDeletionForRecents() {
+  const deleteEvent = /** @type {chrome.fileManagerPrivate.ProgressStatus} */ ({
+    type: chrome.fileManagerPrivate.IOTaskType.DELETE,
+    state: chrome.fileManagerPrivate.IOTaskState.SUCCESS,
+  });
+  const otherEvent = /** @type {chrome.fileManagerPrivate.ProgressStatus} */ ({
+    type: chrome.fileManagerPrivate.IOTaskType.COPY,
+    state: chrome.fileManagerPrivate.IOTaskState.SUCCESS,
+  });
+
+  const directoryModel = getDirectoryModel();
+  let isRescanCalled = false;
+  directoryModel.rescanLater = () => {
+    isRescanCalled = true;
+  };
+
+  // Current directory is not Recent.
+  directoryModel.getCurrentRootType = () =>
+      VolumeManagerCommon.RootType.DOWNLOADS;
+  onIOTaskProgressStatusCallback(deleteEvent);
+  assertFalse(isRescanCalled);
+  onIOTaskProgressStatusCallback(otherEvent);
+  assertFalse(isRescanCalled);
+
+  // Current directory is Recent.
+  directoryModel.getCurrentRootType = () => VolumeManagerCommon.RootType.RECENT;
+  onIOTaskProgressStatusCallback(deleteEvent);
+  assertTrue(isRescanCalled);
+  isRescanCalled = false;
+  onIOTaskProgressStatusCallback(otherEvent);
+  assertFalse(isRescanCalled);
+}
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
index 0ef796cb..ef60c664 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -9,7 +9,7 @@
 import {contextMenuHandler} from 'chrome://resources/js/cr/ui/context_menu_handler.m.js';
 import {List} from 'chrome://resources/js/cr/ui/list.m.js';
 
-import {getHoldingSpaceState} from '../../common/js/api.js';
+import {getHoldingSpaceState, startIOTask} from '../../common/js/api.js';
 import {DialogType} from '../../common/js/dialog_type.js';
 import {FileOperationProgressEvent} from '../../common/js/file_operation_common.js';
 import {FileType} from '../../common/js/file_type.js';
@@ -1613,7 +1613,10 @@
         fileManager.volumeManager.getLocationInfo(parentEntry) :
         null;
     const volumeIsNotReadOnly = !!locationInfo && !locationInfo.isReadOnly;
+    // ARC doesn't support rename for now. http://b/232152680
+    const isRecentArcEntry = VolumeManagerCommon.isRecentArcEntry(entries[0]);
     event.canExecute = entries.length === 1 && volumeIsNotReadOnly &&
+        !isRecentArcEntry &&
         CommandUtil.hasCapability(fileManager, entries, 'canRename');
     event.command.setHidden(false);
   }
@@ -2081,7 +2084,7 @@
 
     const selectionEntries = fileManager.getSelection().entries;
     if (util.isExtractArchiveEnabled()) {
-      chrome.fileManagerPrivate.startIOTask(
+      startIOTask(
           chrome.fileManagerPrivate.IOTaskType.EXTRACT, selectionEntries,
           {destinationFolder: /** @type {!DirectoryEntry} */ (dirEntry)});
     }
@@ -2132,7 +2135,7 @@
 
     const selectionEntries = fileManager.getSelection().entries;
     if (window.isSWA) {
-      chrome.fileManagerPrivate.startIOTask(
+      startIOTask(
           chrome.fileManagerPrivate.IOTaskType.ZIP, selectionEntries,
           {destinationFolder: /** @type {!DirectoryEntry} */ (dirEntry)});
     } else {
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands_unittest.m.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands_unittest.m.js
index e1773c22..88390d2 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager_commands_unittest.m.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands_unittest.m.js
@@ -6,6 +6,7 @@
 import {assertArrayEquals, assertEquals, assertFalse, assertNotEquals, assertTrue} from 'chrome://test/chai_assert.js';
 
 import {MockVolumeManager} from '../../background/js/mock_volume_manager.js';
+import {FakeEntryImpl} from '../../common/js/files_app_entry_types.js';
 import {installMockChrome} from '../../common/js/mock_chrome.js';
 import {MockDirectoryEntry, MockEntry} from '../../common/js/mock_entry.js';
 import {waitUntil} from '../../common/js/test_error_reporting.js';
@@ -363,3 +364,67 @@
 
   done();
 }
+
+/**
+ * Tests that rename command should be disabled for Recent entry.
+ */
+export async function testRenameCommand(done) {
+  loadTimeData.resetForTesting({});
+
+  // Check: `rename` command exists.
+  const command = CommandHandler.getCommand('rename');
+  assertNotEquals(command, undefined);
+
+  // Mock volume manager.
+  const volumeManager = new MockVolumeManager();
+
+  // Create `documents_root` volume.
+  const documentsRootVolumeInfo = volumeManager.createVolumeInfo(
+      VolumeManagerCommon.VolumeType.MEDIA_VIEW,
+      'com.android.providers.media.documents:documents_root', 'Documents');
+
+  // Mock file entries.
+  const recentEntry =
+      new FakeEntryImpl('Recent', VolumeManagerCommon.RootType.RECENT);
+  const pdfEntry = MockDirectoryEntry.create(
+      documentsRootVolumeInfo.fileSystem, 'Documents/abc.pdf');
+
+  // Mock `Event`.
+  const event = {
+    canExecute: true,
+    target: {
+      entry: pdfEntry,
+    },
+    command: {
+      hidden: false,
+      setHidden: (hidden) => {
+        event.command.hidden = hidden;
+      },
+    },
+  };
+
+  // The current selection for testing.
+  const currentSelection = {
+    entries: [pdfEntry],
+    iconType: 'none',
+    totalCount: 1,
+  };
+
+  // Mock `FileManager`.
+  const fileManager = {
+    directoryModel: {
+      isOnNative: () => true,
+      isReadOnly: () => false,
+    },
+    getCurrentDirectoryEntry: () => recentEntry,
+    getSelection: () => currentSelection,
+    volumeManager: volumeManager,
+  };
+
+  // Check: canExecute is false and command is disabled.
+  command.canExecute(event, fileManager);
+  assertFalse(event.canExecute);
+  assertFalse(event.command.hidden);
+
+  done();
+}
diff --git a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
index dda3981..e1eb28b 100644
--- a/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
+++ b/ui/file_manager/file_manager/foreground/js/file_transfer_controller.js
@@ -8,7 +8,7 @@
 import {TreeItem} from 'chrome://resources/js/cr/ui/tree.js';
 import {queryRequiredElement} from 'chrome://resources/js/util.m.js';
 
-import {getDirectory, getDisallowedTransfers} from '../../common/js/api.js';
+import {getDirectory, getDisallowedTransfers, startIOTask} from '../../common/js/api.js';
 import {FileType} from '../../common/js/file_type.js';
 import {ProgressCenterItem, ProgressItemState, ProgressItemType} from '../../common/js/progress_center_common.js';
 import {str, strf, util} from '../../common/js/util.js';
@@ -612,17 +612,25 @@
         .then(/**
                * @param {!Array<Entry>} filteredEntries
                */
-              filteredEntries => {
+              async filteredEntries => {
                 entries = filteredEntries;
                 if (entries.length === 0) {
                   return Promise.reject('ABORT');
                 }
-                // Send only the copy operation to IO Queue in the C++.
                 if (window.isSWA) {
-                  chrome.fileManagerPrivate.startIOTask(
-                      toMove ? chrome.fileManagerPrivate.IOTaskType.MOVE :
-                               chrome.fileManagerPrivate.IOTaskType.COPY,
-                      entries, {destinationFolder: destinationEntry});
+                  const taskType = toMove ?
+                      chrome.fileManagerPrivate.IOTaskType.MOVE :
+                      chrome.fileManagerPrivate.IOTaskType.COPY;
+                  try {
+                    // TODO(crbug/1290197): Start tracking the copy/move
+                    // operation starting here as both the legacy taskId and
+                    // IOTask taskId are available.
+                    await startIOTask(
+                        taskType, entries,
+                        {destinationFolder: destinationEntry});
+                  } catch (e) {
+                    console.error(`Failed to start ${taskType} io task:`, e);
+                  }
                   return;
                 }
 
@@ -1310,6 +1318,12 @@
       return false;
     }
 
+    // Recent isn't read-only, but it doesn't support paste/drop.
+    if (destinationLocationInfo.rootType ===
+        VolumeManagerCommon.RootType.RECENT) {
+      return false;
+    }
+
     if (destinationLocationInfo.volumeInfo &&
         destinationLocationInfo.volumeInfo.error) {
       return false;
@@ -1489,6 +1503,11 @@
         destinationLocationInfo.volumeInfo.error) {
       return new DropEffectAndLabel(DropEffectType.NONE, null);
     }
+    // Recent isn't read-only, but it doesn't support drop.
+    if (destinationLocationInfo.rootType ===
+        VolumeManagerCommon.RootType.RECENT) {
+      return new DropEffectAndLabel(DropEffectType.NONE, null);
+    }
     if (destinationLocationInfo.isReadOnly) {
       if (destinationLocationInfo.isSpecialSearchRoot) {
         // The location is a fake entry that corresponds to special search.
diff --git a/ui/file_manager/integration_tests/file_manager/recents.js b/ui/file_manager/integration_tests/file_manager/recents.js
index eb6cb896..60b28ca 100644
--- a/ui/file_manager/integration_tests/file_manager/recents.js
+++ b/ui/file_manager/integration_tests/file_manager/recents.js
@@ -67,6 +67,17 @@
 }
 
 /**
+ * Checks if the #file-filters-in-recents-v2 flag has been enabled or not.
+ *
+ * @return {!Promise<boolean>} Flag enabled or not.
+ */
+async function isFiltersInRecentsV2Enabled() {
+  const isFiltersInRecentsEnabled =
+      await sendTestMessage({name: 'isFiltersInRecentsEnabledV2'});
+  return isFiltersInRecentsEnabled === 'true';
+}
+
+/**
  * Navigate to Recent folder with specific type and verify the breadcrumb path.
  *
  * @param {string} appId Files app windowId.
@@ -120,9 +131,15 @@
   // Check: the file-list should be selected.
   await remoteCall.waitForElement(appId, '#file-list li[selected]');
 
-  // Test that the delete button isn't visible.
+  // Test that the delete button's visibility based on v2 flag.
   const deleteButton = await remoteCall.waitForElement(appId, '#delete-button');
-  chrome.test.assertTrue(deleteButton.hidden, 'delete button should be hidden');
+  if (await isFiltersInRecentsV2Enabled()) {
+    chrome.test.assertFalse(
+        deleteButton.hidden, 'delete button should be visible');
+  } else {
+    chrome.test.assertTrue(
+        deleteButton.hidden, 'delete button should be hidden');
+  }
 }
 
 /**
diff --git a/weblayer/test/stub_autofill_provider.cc b/weblayer/test/stub_autofill_provider.cc
index b5558733..2d7bf18 100644
--- a/weblayer/test/stub_autofill_provider.cc
+++ b/weblayer/test/stub_autofill_provider.cc
@@ -17,11 +17,12 @@
 
 void StubAutofillProvider::OnAskForValuesToFill(
     autofill::AndroidAutofillManager* manager,
-    int32_t id,
+    int32_t query_id,
     const autofill::FormData& form,
     const autofill::FormFieldData& field,
     const gfx::RectF& bounding_box,
-    bool /*unused_autoselect_first_suggestion*/) {
+    bool /*unused_autoselect_first_suggestion*/,
+    autofill::TouchToFillEligible /*unused_touch_to_fill_eligible*/) {
   on_received_form_data_.Run(form);
 }
 
diff --git a/weblayer/test/stub_autofill_provider.h b/weblayer/test/stub_autofill_provider.h
index 2482725..4df9d6cc 100644
--- a/weblayer/test/stub_autofill_provider.h
+++ b/weblayer/test/stub_autofill_provider.h
@@ -30,11 +30,12 @@
   // AutofillProvider:
   void OnAskForValuesToFill(
       autofill::AndroidAutofillManager* manager,
-      int32_t id,
+      int32_t query_id,
       const autofill::FormData& form,
       const autofill::FormFieldData& field,
       const gfx::RectF& bounding_box,
-      bool /*unused_autoselect_first_suggestion*/) override;
+      bool /*unused_autoselect_first_suggestion*/,
+      autofill::TouchToFillEligible /*unused_touch_to_fill_eligible*/) override;
 
  private:
   base::RepeatingCallback<void(const autofill::FormData&)>