diff --git a/DEPS b/DEPS
index 523b4d8..939431a 100644
--- a/DEPS
+++ b/DEPS
@@ -306,15 +306,15 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'src_internal_revision': '7dad41b491ac6ef10b238af85d0cfe5a91124393',
+  'src_internal_revision': '8ca742cefe79b6c919d7f9a13a41e050a5ef62d1',
   # 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': 'fe4aa8a3ea5380f02ba16568299b2d11a2c0a41e',
+  'skia_revision': '59943f4e92b9728e8bac10903e195c8b9a037365',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '4892aa3e774cdd84597e696d57b4468a6ae3d77f',
+  'v8_revision': '7ac55f9a5e28715fdcc8b0b2a1b49aa6dd5b1ce9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
@@ -825,7 +825,7 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    'ab0b95197af40620e76f2054c376e0068d43a968',
+    '80915fa76a95b7fb3ba6db65df700a789109350f',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
@@ -1663,7 +1663,7 @@
     Var('pdfium_git') + '/pdfium.git' + '@' +  Var('pdfium_revision'),
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '6821c955bdf682556ec4828a174a9cd916d0a02a',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '9b78d80da79be8d58590a2c686d66748161a77ff',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '8ef97ff3b7332e38e61b347a2fbed425a4617151',
@@ -1703,7 +1703,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/r8',
-              'version': 'c2PL3_z2rOvwF74DJ36SLbH9iry7D6V-KG7NU_njKJwC',
+              'version': 'aRZW4VFdf45KlLTJNNkZ-Z8f_PTxChr6X3Nqhjth-FEC',
           },
       ],
       'condition': 'checkout_android',
@@ -1848,7 +1848,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '6493b876ade082dc4e4d883691e8900d5b42f01c',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'fe6178ef7d7f4f25ce93253bdda0b7daae0769a6',
+    Var('webrtc_git') + '/src.git' + '@' + 'cea1c0b9a91be940ec801ab84a7ca3b52e9fc930',
 
   # Wuffs' canonical repository is at github.com/google/wuffs, but we use
   # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file.
@@ -2015,7 +2015,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/projector_app/app',
-        'version': 'M-lPEIY8sklwM9NvTA9EJTXobFbvBY0cCxXZXWVQphMC',
+        'version': 'FQkKHvgesnjRTnf9YY-m0e2A4MAAH1BsxeqoX88UQx0C',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -4055,7 +4055,7 @@
 
   'src/ios_internal':  {
       'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' +
-        '9a183ec88b60cfbeef16ebd32e27a83f9a06126a',
+        'ee8bfecb9125511f41a7f526b5d1cd83157622f1',
       'condition': 'checkout_ios and checkout_src_internal',
   },
 
diff --git a/android_webview/browser/BUILD.gn b/android_webview/browser/BUILD.gn
index 3da54758..4081f77 100644
--- a/android_webview/browser/BUILD.gn
+++ b/android_webview/browser/BUILD.gn
@@ -111,6 +111,8 @@
     "aw_web_contents_view_delegate.h",
     "aw_web_ui_controller_factory.cc",
     "aw_web_ui_controller_factory.h",
+    "component_updater/first_party_sets_component_loader.cc",
+    "component_updater/first_party_sets_component_loader.h",
     "component_updater/loader_policies/empty_component_loader_policy.cc",
     "component_updater/loader_policies/empty_component_loader_policy.h",
     "component_updater/loader_policies/origin_trials_component_loader_policy.cc",
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index e162c2df..27a396d 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -1298,4 +1298,9 @@
   return network::mojom::IpProtectionProxyBypassPolicy::kNone;
 }
 
+bool AwContentBrowserClient::WillProvidePublicFirstPartySets() {
+  return base::CommandLine::ForCurrentProcess()->HasSwitch(
+      switches::kWebViewFpsComponent);
+}
+
 }  // namespace android_webview
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h
index 331557e..eeaa8cc 100644
--- a/android_webview/browser/aw_content_browser_client.h
+++ b/android_webview/browser/aw_content_browser_client.h
@@ -286,6 +286,7 @@
   blink::mojom::OriginTrialsSettingsPtr GetOriginTrialsSettings() override;
   network::mojom::IpProtectionProxyBypassPolicy
   GetIpProtectionProxyBypassPolicy() override;
+  bool WillProvidePublicFirstPartySets() override;
 
   AwFeatureListCreator* aw_feature_list_creator() {
     return aw_feature_list_creator_;
diff --git a/android_webview/browser/component_updater/first_party_sets_component_loader.cc b/android_webview/browser/component_updater/first_party_sets_component_loader.cc
new file mode 100644
index 0000000..d94b03af
--- /dev/null
+++ b/android_webview/browser/component_updater/first_party_sets_component_loader.cc
@@ -0,0 +1,41 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "android_webview/browser/component_updater/first_party_sets_component_loader.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "android_webview/common/aw_switches.h"
+#include "base/command_line.h"
+#include "base/files/file.h"
+#include "base/functional/bind.h"
+#include "base/logging.h"
+#include "base/version.h"
+#include "components/component_updater/android/loader_policies/first_party_sets_component_loader_policy.h"
+#include "components/tpcd/metadata/parser.h"
+#include "content/public/browser/first_party_sets_handler.h"
+#include "services/network/public/cpp/features.h"
+
+namespace android_webview {
+
+void LoadFpsComponent(ComponentLoaderPolicyVector& policies) {
+  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kWebViewFpsComponent)) {
+    return;
+  }
+
+  DVLOG(1) << "Registering first party sets component for loading in "
+              "embedded WebView.";
+
+  policies.push_back(
+      std::make_unique<component_updater::FirstPartySetComponentLoaderPolicy>(
+          base::BindRepeating([](base::Version version, base::File sets_file) {
+            content::FirstPartySetsHandler::GetInstance()
+                ->SetPublicFirstPartySets(version, std::move(sets_file));
+          })));
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/component_updater/first_party_sets_component_loader.h b/android_webview/browser/component_updater/first_party_sets_component_loader.h
new file mode 100644
index 0000000..da416ec
--- /dev/null
+++ b/android_webview/browser/component_updater/first_party_sets_component_loader.h
@@ -0,0 +1,24 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ANDROID_WEBVIEW_BROWSER_COMPONENT_UPDATER_FIRST_PARTY_SETS_COMPONENT_LOADER_H_
+#define ANDROID_WEBVIEW_BROWSER_COMPONENT_UPDATER_FIRST_PARTY_SETS_COMPONENT_LOADER_H_
+
+#include <memory>
+#include <vector>
+
+namespace component_updater {
+class ComponentLoaderPolicy;
+}  // namespace component_updater
+
+namespace android_webview {
+
+using ComponentLoaderPolicyVector =
+    std::vector<std::unique_ptr<component_updater::ComponentLoaderPolicy>>;
+
+void LoadFpsComponent(ComponentLoaderPolicyVector& policies);
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_COMPONENT_UPDATER_FIRST_PARTY_SETS_COMPONENT_LOADER_H_
diff --git a/android_webview/browser/component_updater/registration.cc b/android_webview/browser/component_updater/registration.cc
index 47da5c5..b85cc7c 100644
--- a/android_webview/browser/component_updater/registration.cc
+++ b/android_webview/browser/component_updater/registration.cc
@@ -4,6 +4,7 @@
 
 #include "android_webview/browser/component_updater/registration.h"
 
+#include "android_webview/browser/component_updater/first_party_sets_component_loader.h"
 #include "android_webview/browser/component_updater/loader_policies/empty_component_loader_policy.h"
 #include "android_webview/browser/component_updater/masked_domain_list_component_loader.h"
 #include "android_webview/browser/component_updater/origin_trials_component_loader.h"
@@ -15,6 +16,7 @@
 
 component_updater::ComponentLoaderPolicyVector GetComponentLoaderPolicies() {
   component_updater::ComponentLoaderPolicyVector policies;
+  LoadFpsComponent(policies);
   LoadTrustTokenKeyCommitmentsComponent(policies);
   LoadMaskedDomainListComponent(policies);
   LoadOriginTrialsComponent(policies);
diff --git a/android_webview/common/aw_switches.cc b/android_webview/common/aw_switches.cc
index 916d6cc..2a59674d 100644
--- a/android_webview/common/aw_switches.cc
+++ b/android_webview/common/aw_switches.cc
@@ -84,4 +84,8 @@
 // updater downloading service in nonembedded WebView.
 const char kWebViewTpcdMetadaComponent[] = "webview-tpcd-metadata-component";
 
+// Enables downloading FirstPartySetsComponentInstallerPolicy by the component
+// updater downloading service in nonembedded WebView.
+const char kWebViewFpsComponent[] = "webview-fps-component";
+
 }  // namespace switches
diff --git a/android_webview/common/aw_switches.h b/android_webview/common/aw_switches.h
index af70c222..d102d90 100644
--- a/android_webview/common/aw_switches.h
+++ b/android_webview/common/aw_switches.h
@@ -25,6 +25,7 @@
 extern const char kWebViewEnableAppRecovery[];
 extern const char kWebViewEnableTrustTokensComponent[];
 extern const char kWebViewTpcdMetadaComponent[];
+extern const char kWebViewFpsComponent[];
 
 }  // namespace switches
 
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 c313d4af..29e4d7c 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
@@ -888,6 +888,9 @@
                 BlinkFeatures.BACK_FORWARD_CACHE_SEND_NOT_RESTORED_REASONS,
                 "Expose NotRestoredReasons via PerformanceNavigationTiming API."),
         Flag.baseFeature("SkipUnnecessaryThreadHopsForParseHeaders"),
+        Flag.commandLine(
+                AwSwitches.WEBVIEW_FPS_COMPONENT,
+                "Enables installing the first party sets component to WebViews."),
         // Add new commandline switches and features above. The final entry should have a
         // trailing comma for cleaner diffs.
     };
diff --git a/android_webview/nonembedded/component_updater/registration.cc b/android_webview/nonembedded/component_updater/registration.cc
index 9d61ece..e2f1e20 100644
--- a/android_webview/nonembedded/component_updater/registration.cc
+++ b/android_webview/nonembedded/component_updater/registration.cc
@@ -19,6 +19,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "components/component_updater/component_installer.h"
 #include "components/component_updater/component_updater_service.h"
+#include "components/component_updater/installer_policies/first_party_sets_component_installer_policy.h"
 #include "components/component_updater/installer_policies/masked_domain_list_component_installer_policy.h"
 #include "components/component_updater/installer_policies/origin_trials_component_installer.h"
 #include "components/component_updater/installer_policies/tpcd_metadata_component_installer_policy.h"
@@ -56,6 +57,8 @@
 
   // Note: We're using a command-line switch because finch features
   // isn't supported in nonembedded WebView.
+  // After setting this flag, it may be necessary to force restart the
+  // non-embedded process.
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kWebViewTpcdMetadaComponent)) {
     component_installer_list.push_back(
@@ -67,11 +70,29 @@
                 })));
   }
 
+  // Note: We're using a command-line switch because finch features
+  // isn't supported in nonembedded WebView.
+  // After setting this flag, it may be necessary to force restart the
+  // non-embedded process.
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kWebViewFpsComponent)) {
+    component_installer_list.push_back(
+        std::make_unique<
+            component_updater::FirstPartySetsComponentInstallerPolicy>(
+            /* on_sets_ready= */ base::BindOnce(
+                [](base::Version version, base::File sets_file) {
+                  VLOG(1) << "Received Related Website Sets";
+                }),
+            base::TaskPriority::BEST_EFFORT));
+  }
+
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kWebViewEnableTrustTokensComponent)) {
     // TODO(https://crbug.com/1170468): decide if this component is still
     // needed. Note: We're using a command-line switch because finch features
     // isn't supported in nonembedded WebView.
+    // After setting this flag, it may be necessary to force restart the
+    // non-embedded process.
     component_installer_list.push_back(
         std::make_unique<component_updater::
                              TrustTokenKeyCommitmentsComponentInstallerPolicy>(
diff --git a/ash/system/power/peripheral_battery_notifier.cc b/ash/system/power/peripheral_battery_notifier.cc
index 7e202b4..8523a1a 100644
--- a/ash/system/power/peripheral_battery_notifier.cc
+++ b/ash/system/power/peripheral_battery_notifier.cc
@@ -22,6 +22,7 @@
 #include "base/strings/string_piece.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
+#include "components/device_event_log/device_event_log.h"
 #include "device/bluetooth/bluetooth_adapter_factory.h"
 #include "device/bluetooth/bluetooth_device.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -130,9 +131,6 @@
   // charging.
   if (battery_info.type == PeripheralBatteryListener::BatteryInfo::
                                PeripheralType::kStylusViaCharger) {
-    VLOG(1)
-        << "PeripheralBatteryNotifier: Notification not shown, PeripheralType: "
-        << static_cast<int>(battery_info.type);
     return;
   }
   UpdateBattery(battery_info);
@@ -146,14 +144,13 @@
   const std::string& map_key = battery_info.key;
   CancelNotification(battery_info);
   battery_notifications_.erase(map_key);
+  BLUETOOTH_LOG(EVENT)
+      << "Battery has been removed, erasing notification, battery key: "
+      << map_key;
 }
 
 void PeripheralBatteryNotifier::UpdateBattery(
     const PeripheralBatteryListener::BatteryInfo& battery_info) {
-  VLOG(1) << "PeripheralBatteryNotifier::UpdateBattery, battery key: "
-          << battery_info.key
-          << " battery type: " << static_cast<int>(battery_info.type);
-
   if (!battery_info.level || !battery_info.battery_report_eligible) {
     CancelNotification(battery_info);
     return;
@@ -164,8 +161,6 @@
   auto it = battery_notifications_.find(map_key);
 
   if (it == battery_notifications_.end()) {
-    VLOG(1)
-        << "PeripheralBatteryNotifier::UpdateBattery, new notification created";
     NotificationInfo new_notification_info;
     new_notification_info.level = battery_info.level;
     new_notification_info.last_notification_timestamp =
@@ -173,12 +168,21 @@
     new_notification_info.ever_notified = false;
     battery_notifications_[map_key] = new_notification_info;
   } else {
-    VLOG(1) << "PeripheralBatteryNotifier::UpdateBattery, existing "
-               "notification found";
     NotificationInfo& existing_notification_info = it->second;
     std::optional<uint8_t> old_level = existing_notification_info.level;
     was_old_battery_level_low = old_level && *old_level <= kLowBatteryLevel;
     existing_notification_info.level = battery_info.level;
+
+    BLUETOOTH_LOG(EVENT)
+        << "Battery level updated, battery key: " << map_key
+        << " new battery level: "
+        << (battery_info.level.has_value()
+                ? base::NumberToString(battery_info.level.value())
+                : "empty value")
+        << " old battery level: "
+        << (old_level.has_value() ? base::NumberToString(old_level.value())
+                                  : "empty value")
+        << " battery type: " << static_cast<int>(battery_info.type);
   }
 
   if (*battery_info.level > kLowBatteryLevel) {
@@ -217,9 +221,6 @@
   if (!notification_info.ever_notified ||
       (now - notification_info.last_notification_timestamp >=
        kNotificationInterval)) {
-    VLOG(1) << "PeripheralBatteryNotifier::ShowNotification, new notification "
-               "shown, battery key: "
-            << map_key;
     ShowOrUpdateNotification(battery_info);
     notification_info.last_notification_timestamp = base::TimeTicks::Now();
     notification_info.ever_notified = true;
@@ -230,9 +231,14 @@
     const PeripheralBatteryListener::BatteryInfo& battery_info) {
   const std::string& map_key = battery_info.key;
 
-  VLOG(1)
-      << "PeripheralBatteryNotifier::ShowOrUpdateNotification, battery key: "
-      << map_key;
+  BLUETOOTH_LOG(EVENT)
+      << "Battery notification shown or updated, battery key: " << map_key
+      << " battery level: "
+      << (battery_info.level.has_value()
+              ? base::NumberToString(battery_info.level.value())
+              : "empty value")
+      << " battery type: " << static_cast<int>(battery_info.type);
+
   // Stylus battery notifications differ slightly.
   NotificationParams params =
       (battery_info.type ==
@@ -269,24 +275,30 @@
   const std::string& map_key = battery_info.key;
   const auto it = battery_notifications_.find(map_key);
 
-  VLOG(1) << "PeripheralBatteryNotifier: canceling notification, key: "
-          << battery_info.key
-          << " battery type: " << static_cast<int>(battery_info.type);
-
-  if (it != battery_notifications_.end()) {
-    std::string notification_map_key =
-        (battery_info.type == PeripheralBatteryListener::BatteryInfo::
-                                  PeripheralType::kStylusViaScreen)
-            ? kStylusNotificationId
-            : (kPeripheralDeviceIdPrefix + map_key);
-
-    message_center::MessageCenter::Get()->RemoveNotification(
-        notification_map_key, /*by_user=*/false);
-
-    // Resetting this value allows a new low battery level to post a
-    // notification if the old one was also under the threshold.
-    it->second.level.reset();
+  if (it == battery_notifications_.end()) {
+    return;
   }
+
+  BLUETOOTH_LOG(EVENT)
+      << "Battery notification canceled, battery key: " << map_key
+      << " battery level: "
+      << (battery_info.level.has_value()
+              ? base::NumberToString(battery_info.level.value())
+              : "empty value")
+      << " battery type: " << static_cast<int>(battery_info.type);
+
+  std::string notification_map_key =
+      (battery_info.type ==
+       PeripheralBatteryListener::BatteryInfo::PeripheralType::kStylusViaScreen)
+          ? kStylusNotificationId
+          : (kPeripheralDeviceIdPrefix + map_key);
+
+  message_center::MessageCenter::Get()->RemoveNotification(notification_map_key,
+                                                           /*by_user=*/false);
+
+  // Resetting this value allows a new low battery level to post a
+  // notification if the old one was also under the threshold.
+  it->second.level.reset();
 }
 
 }  // namespace ash
diff --git a/ash/system/tray/tray_item_view_unittest.cc b/ash/system/tray/tray_item_view_unittest.cc
index 86a2ccac..508eda4 100644
--- a/ash/system/tray/tray_item_view_unittest.cc
+++ b/ash/system/tray/tray_item_view_unittest.cc
@@ -268,7 +268,9 @@
 
 // Tests that the smoothness metric for the "hide" animation is still recorded
 // even when the "hide" animation interrupts the "show" animation.
-TEST_F(TrayItemViewTest, HideSmoothnessMetricRecordedWhenHideInterruptsShow) {
+// TODO(b/41496872): Re-enable flaky test.
+TEST_F(TrayItemViewTest,
+       DISABLED_HideSmoothnessMetricRecordedWhenHideInterruptsShow) {
   // Start with the tray item hidden. Note that animations still complete
   // immediately in this part of the test, so no smoothness metrics are emitted.
   tray_item()->SetVisible(false);
diff --git a/build/config/win/BUILD.gn b/build/config/win/BUILD.gn
index 042945f..39da6404 100644
--- a/build/config/win/BUILD.gn
+++ b/build/config/win/BUILD.gn
@@ -420,6 +420,7 @@
     "/DELAYLOAD:credui.dll",
     "/DELAYLOAD:cryptui.dll",
     "/DELAYLOAD:d3d11.dll",
+    "/DELAYLOAD:d3d12.dll",
     "/DELAYLOAD:d3d9.dll",
     "/DELAYLOAD:dwmapi.dll",
     "/DELAYLOAD:dxgi.dll",
diff --git a/chrome/VERSION b/chrome/VERSION
index 9dd77b2..55e85ba 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=123
 MINOR=0
-BUILD=6289
+BUILD=6290
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackupAgentImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackupAgentImpl.java
index 9146e7d..44a78b6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackupAgentImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackupAgentImpl.java
@@ -199,7 +199,7 @@
         final ArrayList<String> backupNames = new ArrayList<>();
         final ArrayList<byte[]> backupValues = new ArrayList<>();
 
-        // TODO(crbug.com/1462552): Remove syncAccount once UNO is launched, given the sync feature
+        // TODO(crbug.com/40066949): Remove syncAccount once UNO is launched, given the sync feature
         // and consent will disappear.
         final AtomicReference<CoreAccountInfo> syncAccount = new AtomicReference<>();
         final AtomicReference<CoreAccountInfo> signedInAccount = new AtomicReference<>();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
index 8c2e532..8de14a5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -92,14 +92,12 @@
             new CustomTabActivityTabProvider.Observer() {
                 @Override
                 public void onInitialTabCreated(@NonNull Tab tab, int mode) {
-                    resetPostMessageHandlersForCurrentSession();
-                    maybeCreateHistoryTabHelper(tab);
+                    onTabInitOrSwapped(tab);
                 }
 
                 @Override
                 public void onTabSwapped(@NonNull Tab tab) {
-                    resetPostMessageHandlersForCurrentSession();
-                    maybeCreateHistoryTabHelper(tab);
+                    onTabInitOrSwapped(tab);
                 }
 
                 @Override
@@ -108,6 +106,11 @@
                 }
             };
 
+    private void onTabInitOrSwapped(@Nullable Tab tab) {
+        resetPostMessageHandlersForCurrentSession();
+        if (tab != null) maybeCreateHistoryTabHelper(tab);
+    }
+
     private void maybeCreateHistoryTabHelper(Tab tab) {
         String appId = mIntentDataProvider.getClientPackageName();
         if (appId != null) HistoryTabHelper.from(tab).setAppId(appId, tab.getWebContents());
@@ -149,7 +152,7 @@
         super.performPreInflationStartup();
         mTabProvider.addObserver(mTabChangeObserver);
         // We might have missed an onInitialTabCreated event.
-        resetPostMessageHandlersForCurrentSession();
+        onTabInitOrSwapped(mTabProvider.getTab());
 
         mSession = mIntentDataProvider.getSession();
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/FeaturesAnnotationsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/FeaturesAnnotationsTest.java
index 273a54c..084c28c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/FeaturesAnnotationsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/FeaturesAnnotationsTest.java
@@ -10,11 +10,13 @@
 
 import androidx.test.filters.SmallTest;
 
+import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import org.chromium.base.CommandLine;
+import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Features;
 import org.chromium.base.test.util.Features.DisableFeatures;
@@ -22,6 +24,7 @@
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
+import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -30,9 +33,15 @@
 /** Tests for {@link Features}. */
 @RunWith(ChromeJUnit4ClassRunner.class)
 @CommandLineFlags.Add(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE)
+@Batch(Batch.PER_CLASS)
 public class FeaturesAnnotationsTest {
+    @ClassRule
+    public static ChromeTabbedActivityTestRule sActivityTestRule =
+            new ChromeTabbedActivityTestRule();
+
     @Rule
-    public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
+    public BlankCTATabInitialStateRule mInitialStateRule =
+            new BlankCTATabInitialStateRule(sActivityTestRule, false);
 
     /**
      * Tests that {@link EnableFeatures} and {@link DisableFeatures} can alter the flags registered
@@ -42,8 +51,7 @@
     @SmallTest
     @EnableFeatures("One")
     @DisableFeatures("Two")
-    public void testFeaturesSetExistingFlags() throws InterruptedException {
-        mActivityTestRule.startMainActivityOnBlankPage();
+    public void testFeaturesSetExistingFlags() {
         List<String> finalEnabledList = getFeatureList(true);
 
         assertThat(finalEnabledList, hasItems("One"));
@@ -65,8 +73,7 @@
     @SmallTest
     @CommandLineFlags.Add("enable-features=One,Two,Three")
     @EnableFeatures("Two")
-    public void testFeaturesDoNotRemoveExistingFlags() throws InterruptedException {
-        mActivityTestRule.startMainActivityOnBlankPage();
+    public void testFeaturesDoNotRemoveExistingFlags() {
         List<String> finalEnabledList = getFeatureList(true);
 
         assertThat(finalEnabledList, hasItems("One", "Two", "Three"));
@@ -84,8 +91,7 @@
     @SmallTest
     @CommandLineFlags.Add("enable-features=One,Two,Three")
     @EnableFeatures({"Three", "Four"})
-    public void testFeaturesAddToExistingFlags() throws InterruptedException {
-        mActivityTestRule.startMainActivityOnBlankPage();
+    public void testFeaturesAddToExistingFlags() {
         List<String> finalEnabledList = getFeatureList(true);
 
         assertThat(finalEnabledList, hasItems("Four"));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/BrowsingDataTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/BrowsingDataTest.java
index b881b966..e6be3ee 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/BrowsingDataTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/BrowsingDataTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.chrome.browser.browsing_data;
 
+import static org.chromium.base.test.util.Matchers.is;
+
 import androidx.test.filters.SmallTest;
 
 import org.junit.Assert;
@@ -16,14 +18,24 @@
 import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.Criteria;
+import org.chromium.base.test.util.CriteriaHelper;
+import org.chromium.base.test.util.Features.EnableFeatures;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
+import org.chromium.chrome.browser.password_manager.FakePasswordStoreAndroidBackendFactoryImpl;
+import org.chromium.chrome.browser.password_manager.PasswordStoreAndroidBackendFactory;
+import org.chromium.chrome.browser.password_manager.PasswordStoreBridge;
+import org.chromium.chrome.browser.password_manager.PasswordStoreCredential;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
 import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule;
+import org.chromium.chrome.test.util.browser.signin.SigninTestRule;
 import org.chromium.content_public.browser.test.util.JavaScriptUtils;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.net.test.EmbeddedTestServer;
+import org.chromium.url.GURL;
 
 import java.util.Arrays;
 import java.util.List;
@@ -47,6 +59,8 @@
     public BlankCTATabInitialStateRule mBlankCTATabInitialStateRule =
             new BlankCTATabInitialStateRule(sActivityTestRule, false);
 
+    @Rule public SigninTestRule mSigninTestRule = new SigninTestRule();
+
     @Before
     public void setUp() throws Exception {
         mTestServer = sActivityTestRule.getTestServer();
@@ -176,6 +190,55 @@
         helper.waitForCallback(0);
     }
 
+    /** Test that both local and account passwords are deleted. */
+    @Test
+    @SmallTest
+    @EnableFeatures({
+        ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_LOCAL_PASSWORDS_ANDROID_NO_MIGRATION
+    })
+    public void testLocalAndAccountPasswordsDeleted() throws Exception {
+        // Set up a syncing user with one password in each store.
+        mSigninTestRule.addTestAccountThenSigninAndEnableSync();
+        PasswordStoreAndroidBackendFactory.setFactoryInstanceForTesting(
+                new FakePasswordStoreAndroidBackendFactoryImpl());
+        PasswordStoreBridge bridge =
+                TestThreadUtils.runOnUiThreadBlockingNoException(() -> new PasswordStoreBridge());
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> {
+                    bridge.insertPasswordCredentialInProfileStore(
+                            new PasswordStoreCredential(
+                                    new GURL("https://site1.com"), "user1", "pwd1"));
+                    bridge.insertPasswordCredentialInAccountStore(
+                            new PasswordStoreCredential(
+                                    new GURL("https://site2.com"), "user2", "pwd2"));
+                });
+        CriteriaHelper.pollUiThread(
+                () -> {
+                    Criteria.checkThat(
+                            "The profile store should've had one password",
+                            bridge.getPasswordStoreCredentialsCountForProfileStore(),
+                            is(1));
+                    Criteria.checkThat(
+                            "The account store should've had one password",
+                            bridge.getPasswordStoreCredentialsCountForAccountStore(),
+                            is(1));
+                });
+
+        clearBrowsingData(BrowsingDataType.PASSWORDS, TimePeriod.ALL_TIME);
+
+        CriteriaHelper.pollUiThread(
+                () -> {
+                    Criteria.checkThat(
+                            "The profile store should be empty",
+                            bridge.getPasswordStoreCredentialsCountForProfileStore(),
+                            is(0));
+                    Criteria.checkThat(
+                            "The account store should be empty",
+                            bridge.getPasswordStoreCredentialsCountForAccountStore(),
+                            is(0));
+                });
+    }
+
     /** Test history deletion. */
     @Test
     @SmallTest
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java
index 829ea0b..4d2346ba 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java
@@ -667,7 +667,6 @@
     @Test
     @SmallTest
     @Feature({"Preferences"})
-    @DisabledTest(message = "TODO(crbug.com/1449833)")
     public void testCookiesNotBlocked() throws Exception {
         SettingsActivity settingsActivity =
                 SiteSettingsTestUtils.startSiteSettingsCategory(
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 6169026..841242f7 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -3745,20 +3745,6 @@
          std::size(kDesktopPWAsLinkCapturingDefaultOff), nullptr}};
 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
 
-const FeatureEntry::FeatureParam
-    kCompressionDictionaryTransportBackendVersionV1[]{
-        {"CompressionDictionaryTransportBackendVersion", "v1"}};
-const FeatureEntry::FeatureParam
-    kCompressionDictionaryTransportBackendVersionV2[]{
-        {"CompressionDictionaryTransportBackendVersion", "v2"}};
-
-const FeatureEntry::FeatureVariation
-    kCompressionDictionaryTransportBackendVariations[] = {
-        {"V1", kCompressionDictionaryTransportBackendVersionV1,
-         std::size(kCompressionDictionaryTransportBackendVersionV1), nullptr},
-        {"V2", kCompressionDictionaryTransportBackendVersionV2,
-         std::size(kCompressionDictionaryTransportBackendVersionV2), nullptr}};
-
 #if BUILDFLAG(IS_ANDROID)
 const FeatureEntry::Choice kAccountBookmarksAndReadingListBehindOptInChoices[] =
     {
@@ -10246,10 +10232,8 @@
      flag_descriptions::kCompressionDictionaryTransportBackendName,
      flag_descriptions::kCompressionDictionaryTransportBackendDescription,
      kOsAll,
-     FEATURE_WITH_PARAMS_VALUE_TYPE(
-         network::features::kCompressionDictionaryTransportBackend,
-         kCompressionDictionaryTransportBackendVariations,
-         "CompressionDictionaryTransportBackend")},
+     FEATURE_VALUE_TYPE(
+         network::features::kCompressionDictionaryTransportBackend)},
 
     {"enable-compression-dictionary-transport-allow-http1",
      flag_descriptions::kCompressionDictionaryTransportOverHttp1Name,
diff --git a/chrome/browser/ash/app_mode/kiosk_profile_loader.cc b/chrome/browser/ash/app_mode/kiosk_profile_loader.cc
index 389dd79..73f38db 100644
--- a/chrome/browser/ash/app_mode/kiosk_profile_loader.cc
+++ b/chrome/browser/ash/app_mode/kiosk_profile_loader.cc
@@ -13,7 +13,6 @@
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "base/memory/ptr_util.h"
-#include "base/memory/raw_ptr.h"
 #include "base/notreached.h"
 #include "base/sequence_checker.h"
 #include "base/syslog_logging.h"
@@ -46,7 +45,7 @@
   return !base::SysInfo::IsRunningOnChromeOS();
 }
 
-KioskAppLaunchError::Error LoginFailureToKioskAppLaunchError(
+KioskAppLaunchError::Error LoginFailureToKioskLaunchError(
     const AuthFailure& error) {
   switch (error.reason()) {
     case AuthFailure::COULD_NOT_MOUNT_TMPFS:
@@ -247,28 +246,63 @@
   base::WeakPtrFactory<SessionStarter> weak_ptr_factory_{this};
 };
 
+void LogErrorToSyslog(KioskAppLaunchError::Error error) {
+  switch (error) {
+    case KioskAppLaunchError::Error::kCryptohomedNotRunning:
+      SYSLOG(ERROR) << "Cryptohome not available when loading Kiosk profile.";
+      break;
+    case KioskAppLaunchError::Error::kAlreadyMounted:
+      SYSLOG(ERROR) << "Cryptohome already mounted when loading Kiosk profile.";
+      break;
+    case KioskAppLaunchError::Error::kUserNotAllowlisted:
+      SYSLOG(ERROR) << "LoginPerformer disallowed Kiosk user sign in.";
+      break;
+    default:
+      SYSLOG(ERROR) << "Unexpected error " << (int)error;
+  }
+}
+
 }  // namespace
 
+std::unique_ptr<CancellableJob> LoadProfile(
+    const AccountId& app_account_id,
+    KioskAppType app_type,
+    KioskProfileLoader::ResultCallback on_done) {
+  return KioskProfileLoader::Run(app_account_id, app_type, std::move(on_done));
+}
+
+std::unique_ptr<CancellableJob> KioskProfileLoader::Run(
+    const AccountId& app_account_id,
+    KioskAppType app_type,
+    ResultCallback on_done) {
+  auto loader = base::WrapUnique(
+      new KioskProfileLoader(app_account_id, app_type, std::move(on_done)));
+  loader->CheckCryptohomeIsNotMounted();
+  return loader;
+}
+
 KioskProfileLoader::KioskProfileLoader(const AccountId& app_account_id,
                                        KioskAppType app_type,
-                                       Delegate* delegate)
-    : account_id_(app_account_id), app_type_(app_type), delegate_(delegate) {}
+                                       ResultCallback on_done)
+    : account_id_(app_account_id),
+      app_type_(app_type),
+      on_done_(std::move(on_done)) {}
 
 KioskProfileLoader::~KioskProfileLoader() = default;
 
-void KioskProfileLoader::Start() {
+void KioskProfileLoader::CheckCryptohomeIsNotMounted() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   current_step_ = CheckCryptohome(base::BindOnce(
       [](KioskProfileLoader* self, std::optional<MountedState> result) {
         if (!result.has_value()) {
-          return self->ReportLaunchResult(
+          return self->ReturnError(
               KioskAppLaunchError::Error::kCryptohomedNotRunning);
         }
         switch (result.value()) {
           case MountedState::kNotMounted:
             return self->LoginAsKioskAccount();
           case MountedState::kMounted:
-            return self->ReportLaunchResult(
+            return self->ReturnError(
                 KioskAppLaunchError::Error::kAlreadyMounted);
         }
       },
@@ -287,17 +321,15 @@
               return self->PrepareProfile(result.value());
             } else if (auto* error = std::get_if<SigninPerformer::LoginError>(
                            &result.error())) {
-              return self->ReportLaunchResult(
-                  SigninErrorToKioskLaunchError(*error));
+              return self->ReturnError(SigninErrorToKioskLaunchError(*error));
             } else if (auto* auth_failure =
                            std::get_if<AuthFailure>(&result.error())) {
-              return self->ReportLaunchResult(
-                  LoginFailureToKioskAppLaunchError(*auth_failure));
+              return self->ReturnError(
+                  LoginFailureToKioskLaunchError(*auth_failure));
             } else if (auto* user_context =
                            std::get_if<OldEncryptionUserContext>(
                                &result.error())) {
-              return self->ReportOldEncryptionUserContext(
-                  std::move(*user_context));
+              return self->ReturnError(std::move(*user_context));
             }
             NOTREACHED_NORETURN();
           },
@@ -308,37 +340,24 @@
 void KioskProfileLoader::PrepareProfile(const UserContext& user_context) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   current_step_ = SessionStarter::Run(
-      user_context, base::BindOnce(&KioskProfileLoader::ReportProfileLoaded,
+      user_context, base::BindOnce(&KioskProfileLoader::ReturnSuccess,
+                                   // Safe because `this` owns `current_step_`
                                    base::Unretained(this)));
 }
 
-void KioskProfileLoader::ReportProfileLoaded(Profile& profile) {
+void KioskProfileLoader::ReturnSuccess(Profile& profile) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   current_step_.reset();
-  delegate_->OnProfileLoaded(&profile);
+  std::move(on_done_).Run(&profile);
 }
 
-void KioskProfileLoader::ReportLaunchResult(KioskAppLaunchError::Error error) {
+void KioskProfileLoader::ReturnError(ErrorResult result) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   current_step_.reset();
-
-  if (error == KioskAppLaunchError::Error::kCryptohomedNotRunning) {
-    SYSLOG(ERROR) << "Cryptohome not available when loading Kiosk profile.";
-  } else if (error == KioskAppLaunchError::Error::kAlreadyMounted) {
-    SYSLOG(ERROR) << "Cryptohome already mounted when loading Kiosk profile.";
-  } else if (error == KioskAppLaunchError::Error::kUserNotAllowlisted) {
-    SYSLOG(ERROR) << "LoginPerformer disallowed Kiosk user sign in.";
+  if (auto* error = std::get_if<KioskAppLaunchError::Error>(&result)) {
+    LogErrorToSyslog(*error);
   }
-
-  if (error != KioskAppLaunchError::Error::kNone) {
-    delegate_->OnProfileLoadFailed(error);
-  }
-}
-
-void KioskProfileLoader::ReportOldEncryptionUserContext(
-    OldEncryptionUserContext user_context) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  delegate_->OnOldEncryptionDetected(std::move(user_context));
+  std::move(on_done_).Run(base::unexpected(std::move(result)));
 }
 
 }  // namespace ash
diff --git a/chrome/browser/ash/app_mode/kiosk_profile_loader.h b/chrome/browser/ash/app_mode/kiosk_profile_loader.h
index 23905ee..8b91d35 100644
--- a/chrome/browser/ash/app_mode/kiosk_profile_loader.h
+++ b/chrome/browser/ash/app_mode/kiosk_profile_loader.h
@@ -8,9 +8,9 @@
 #include <memory>
 #include <string>
 
-#include "base/memory/raw_ptr.h"
 #include "base/sequence_checker.h"
 #include "base/thread_annotations.h"
+#include "base/types/expected.h"
 #include "chrome/browser/ash/app_mode/cancellable_job.h"
 #include "chrome/browser/ash/app_mode/kiosk_app_launch_error.h"
 #include "chrome/browser/ash/app_mode/kiosk_app_types.h"
@@ -24,50 +24,67 @@
 
 class UserContext;
 
-// KioskProfileLoader loads a special profile for a given app. It first
-// attempts to login for the app's generated user id. If the login is
-// successful, it prepares app profile then calls the delegate.
-class KioskProfileLoader {
+// Helper class that implements `LoadProfile()`.
+class KioskProfileLoader : public CancellableJob {
  public:
   using OldEncryptionUserContext = std::unique_ptr<UserContext>;
+  using ErrorResult =
+      std::variant<KioskAppLaunchError::Error, OldEncryptionUserContext>;
+  using Result = base::expected<Profile*, ErrorResult>;
+  using ResultCallback = base::OnceCallback<void(Result result)>;
 
-  class Delegate {
-   public:
-    virtual void OnProfileLoaded(Profile* profile) = 0;
-    virtual void OnProfileLoadFailed(KioskAppLaunchError::Error error) = 0;
-    virtual void OnOldEncryptionDetected(
-        OldEncryptionUserContext user_context) = 0;
+  [[nodiscard]] static std::unique_ptr<CancellableJob> Run(
+      const AccountId& app_account_id,
+      KioskAppType app_type,
+      ResultCallback on_done);
 
-   protected:
-    virtual ~Delegate() = default;
-  };
-
-  KioskProfileLoader(const AccountId& app_account_id,
-                     KioskAppType app_type,
-                     Delegate* delegate);
   KioskProfileLoader(const KioskProfileLoader&) = delete;
   KioskProfileLoader& operator=(const KioskProfileLoader&) = delete;
-  ~KioskProfileLoader();
-
-  // Starts profile load. Calls delegate on success or failure.
-  void Start();
+  ~KioskProfileLoader() override;
 
  private:
+  KioskProfileLoader(const AccountId& app_account_id,
+                     KioskAppType app_type,
+                     ResultCallback on_done);
+
+  void CheckCryptohomeIsNotMounted();
   void LoginAsKioskAccount();
   void PrepareProfile(const UserContext& user_context);
-  void ReportProfileLoaded(Profile& profile);
-  void ReportLaunchResult(KioskAppLaunchError::Error error);
-  void ReportOldEncryptionUserContext(OldEncryptionUserContext user_context);
+  void ReturnSuccess(Profile& profile);
+  void ReturnError(ErrorResult result);
 
   const AccountId account_id_;
   const KioskAppType app_type_;
-  raw_ptr<Delegate> delegate_ GUARDED_BY_CONTEXT(sequence_checker_);
+
   std::unique_ptr<CancellableJob> current_step_
       GUARDED_BY_CONTEXT(sequence_checker_);
+  ResultCallback on_done_ GUARDED_BY_CONTEXT(sequence_checker_);
 
   SEQUENCE_CHECKER(sequence_checker_);
 };
 
+// Loads the Kiosk profile for a given app.
+//
+// It executes the following steps:
+//
+// 1. Wait for cryptohome and verify cryptohome is not yet mounted.
+// 2. Login with the account generated for the Kiosk app.
+// 3. Prepare a `Profile` for the app.
+//
+// `on_done` will either be called with the resulting profile on success, or
+// with a `KioskProfileLoader::ErrorResult` on error.
+//
+// The returned `unique_ptr` can be destroyed to cancel this task. In that case
+// `on_done` will not be called.
+[[nodiscard]] std::unique_ptr<CancellableJob> LoadProfile(
+    const AccountId& app_account_id,
+    KioskAppType app_type,
+    KioskProfileLoader::ResultCallback on_done);
+
+// Convenience define to declare references to `LoadProfile`. Useful for callers
+// to override `LoadProfile` in tests.
+using LoadProfileCallback = base::OnceCallback<decltype(LoadProfile)>;
+
 }  // namespace ash
 
 #endif  // CHROME_BROWSER_ASH_APP_MODE_KIOSK_PROFILE_LOADER_H_
diff --git a/chrome/browser/ash/login/app_mode/kiosk_launch_controller.cc b/chrome/browser/ash/login/app_mode/kiosk_launch_controller.cc
index 33db364..201b1b73 100644
--- a/chrome/browser/ash/login/app_mode/kiosk_launch_controller.cc
+++ b/chrome/browser/ash/login/app_mode/kiosk_launch_controller.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ash/login/app_mode/kiosk_launch_controller.h"
 
 #include <memory>
+#include <variant>
 
 #include "ash/accelerators/accelerator_controller_impl.h"
 #include "ash/constants/ash_switches.h"
@@ -31,6 +32,7 @@
 #include "chrome/browser/ash/app_mode/kiosk_app_launcher.h"
 #include "chrome/browser/ash/app_mode/kiosk_app_types.h"
 #include "chrome/browser/ash/app_mode/kiosk_chrome_app_manager.h"
+#include "chrome/browser/ash/app_mode/kiosk_profile_loader.h"
 #include "chrome/browser/ash/app_mode/lacros_launcher.h"
 #include "chrome/browser/ash/app_mode/startup_app_launcher.h"
 #include "chrome/browser/ash/app_mode/web_app/web_kiosk_app_manager.h"
@@ -65,9 +67,6 @@
 bool g_block_app_launch_for_testing = false;
 // Whether we should prevent Kiosk launcher from exiting when launch fails.
 bool g_block_exit_on_failure_for_testing = false;
-// Whether we should disable any operations using KioskProfileLoader. Used in
-// tests.
-bool g_disable_login_operations = false;
 
 // Enum types for Kiosk.LaunchType UMA so don't change its values.
 // KioskLaunchType in histogram.xml must be updated when making changes here.
@@ -315,6 +314,7 @@
 KioskLaunchController::KioskLaunchController(OobeUI* oobe_ui)
     : KioskLaunchController(LoginDisplayHost::default_host(),
                             oobe_ui->GetView<AppLaunchSplashScreenHandler>(),
+                            base::BindOnce(&LoadProfile),
                             base::BindRepeating(&BuildKioskAppLauncher),
                             std::make_unique<DefaultNetworkMonitor>(),
                             std::make_unique<DefaultAcceleratorController>()) {}
@@ -322,6 +322,7 @@
 KioskLaunchController::KioskLaunchController(
     LoginDisplayHost* host,
     AppLaunchSplashScreenView* splash_screen,
+    LoadProfileCallback profile_loader,
     KioskAppLauncherFactory app_launcher_factory,
     std::unique_ptr<NetworkUiController::NetworkMonitor> network_monitor,
     std::unique_ptr<AcceleratorController> accelerator_controller)
@@ -333,6 +334,7 @@
           host_,
           CHECK_DEREF(splash_screen_view_.get()),
           std::move(network_monitor))),
+      profile_loader_(std::move(profile_loader)),
       accelerator_controller_(std::move(accelerator_controller)) {
   if (!host_) {
     CHECK_IS_TEST();
@@ -373,14 +375,29 @@
                            base::BindOnce(&KioskLaunchController::OnTimerFire,
                                           weak_ptr_factory_.GetWeakPtr()));
 
-  if (g_disable_login_operations) {
-    return;
-  }
-
   CHECK(kiosk_app_id.account_id.is_valid());
-  kiosk_profile_loader_ = std::make_unique<KioskProfileLoader>(
-      kiosk_app_id_.account_id, kiosk_app_id_.type, /*delegate=*/this);
-  kiosk_profile_loader_->Start();
+
+  profile_loader_handle_ =
+      std::move(profile_loader_)
+          .Run(kiosk_app_id.account_id, kiosk_app_id.type,
+               /*on_done=*/
+               base::BindOnce(
+                   [](KioskLaunchController* self,
+                      KioskProfileLoader::Result result) {
+                     CHECK(!self->profile_) << "Kiosk profile loaded twice";
+                     self->profile_loader_handle_.reset();
+
+                     if (!result.has_value()) {
+                       self->HandleProfileLoadError(std::move(result.error()));
+                       return;
+                     }
+
+                     SYSLOG(INFO) << "Profile loaded... Starting app launch.";
+                     self->profile_ = result.value();
+                     self->StartAppLaunch(*self->profile_);
+                   },
+                   // Safe because `this` owns `profile_loader_handle_`.
+                   base::Unretained(this)));
 }
 
 void KioskLaunchController::AddKioskProfileLoadFailedObserver(
@@ -407,18 +424,14 @@
   return false;
 }
 
-void KioskLaunchController::OnProfileLoaded(Profile* profile) {
-  SYSLOG(INFO) << "Profile loaded... Starting app launch.";
-  DCHECK(!profile_) << "OnProfileLoaded called twice";
-  profile_ = profile;
-
+void KioskLaunchController::StartAppLaunch(Profile& profile) {
   // Call `ClearMigrationStep()` once per signin so that the check for migration
   // is run exactly once per signin. Check the comment for `kMigrationStep` in
   // browser_data_migrator.h for details.
   BrowserDataMigratorImpl::ClearMigrationStep(g_browser_process->local_state());
 
   const user_manager::User& user =
-      CHECK_DEREF(ProfileHelper::Get()->GetUserByProfile(profile));
+      CHECK_DEREF(ProfileHelper::Get()->GetUserByProfile(&profile));
 
   if (BrowserDataMigratorImpl::MaybeRestartToMigrate(
           user.GetAccountId(), user.username_hash(),
@@ -435,13 +448,13 @@
   }
 
   // This is needed to trigger input method extensions being loaded.
-  profile->InitChromeOSPreferences();
+  profile.InitChromeOSPreferences();
 
   if (cleaned_up_) {
     LOG(WARNING) << "Profile is loaded after kiosk launch has been aborted.";
     return;
   }
-  CHECK_DEREF(network_ui_controller_.get()).SetProfile(profile);
+  CHECK_DEREF(network_ui_controller_.get()).SetProfile(&profile);
 
   InitializeKeyboard();
   LaunchLacros();
@@ -688,15 +701,25 @@
   }
 }
 
-void KioskLaunchController::OnProfileLoadFailed(
-    KioskAppLaunchError::Error error) {
+void KioskLaunchController::HandleProfileLoadError(
+    KioskProfileLoader::ErrorResult error) {
+  if (auto* user_context =
+          std::get_if<KioskProfileLoader::OldEncryptionUserContext>(&error)) {
+    return HandleOldEncryption(std::move(*user_context));
+  }
+
+  auto launch_error = std::get<KioskAppLaunchError::Error>(error);
+  if (launch_error == KioskAppLaunchError::Error::kNone) {
+    return;
+  }
+
   for (auto& observer : profile_load_failed_observers_) {
     observer.OnKioskProfileLoadFailed();
   }
-  OnLaunchFailed(error);
+  OnLaunchFailed(launch_error);
 }
 
-void KioskLaunchController::OnOldEncryptionDetected(
+void KioskLaunchController::HandleOldEncryption(
     std::unique_ptr<UserContext> user_context) {
   if (kiosk_app_id_.type != KioskAppType::kArcApp) {
     NOTREACHED();
@@ -772,13 +795,6 @@
 
 // static
 std::unique_ptr<base::AutoReset<bool>>
-KioskLaunchController::DisableLoginOperationsForTesting() {
-  return std::make_unique<base::AutoReset<bool>>(&g_disable_login_operations,
-                                                 true);
-}
-
-// static
-std::unique_ptr<base::AutoReset<bool>>
 KioskLaunchController::SkipSplashScreenWaitForTesting() {
   return std::make_unique<base::AutoReset<bool>>(
       &g_skip_splash_wait_for_testing, true);
diff --git a/chrome/browser/ash/login/app_mode/kiosk_launch_controller.h b/chrome/browser/ash/login/app_mode/kiosk_launch_controller.h
index a9609ea..e4f4fb89 100644
--- a/chrome/browser/ash/login/app_mode/kiosk_launch_controller.h
+++ b/chrome/browser/ash/login/app_mode/kiosk_launch_controller.h
@@ -83,8 +83,7 @@
 //
 // It is all encompassed within the combination of two states -- AppState and
 // NetworkUI state.
-class KioskLaunchController : public KioskProfileLoader::Delegate,
-                              public KioskAppLauncher::Observer,
+class KioskLaunchController : public KioskAppLauncher::Observer,
                               public NetworkUiController::Observer {
  public:
   class KioskProfileLoadFailedObserver : public base::CheckedObserver {
@@ -112,6 +111,7 @@
   KioskLaunchController(
       LoginDisplayHost* host,
       AppLaunchSplashScreenView* splash_screen,
+      LoadProfileCallback profile_loader,
       KioskAppLauncherFactory app_launcher_factory,
       std::unique_ptr<NetworkUiController::NetworkMonitor> network_monitor,
       std::unique_ptr<AcceleratorController> accelerator_controller);
@@ -120,8 +120,6 @@
   ~KioskLaunchController() override;
 
   [[nodiscard]] static std::unique_ptr<base::AutoReset<bool>>
-  DisableLoginOperationsForTesting();
-  [[nodiscard]] static std::unique_ptr<base::AutoReset<bool>>
   SkipSplashScreenWaitForTesting();
   [[nodiscard]] static std::unique_ptr<base::AutoReset<bool>>
   BlockAppLaunchForTesting();
@@ -182,11 +180,9 @@
   void OnAppDataUpdated() override;
   void OnAppWindowCreated(const std::optional<std::string>& app_name) override;
 
-  // `KioskProfileLoader::Delegate`
-  void OnProfileLoaded(Profile* profile) override;
-  void OnProfileLoadFailed(KioskAppLaunchError::Error error) override;
-  void OnOldEncryptionDetected(
-      std::unique_ptr<UserContext> user_context) override;
+  void StartAppLaunch(Profile& profile);
+  void HandleProfileLoadError(KioskProfileLoader::ErrorResult error);
+  void HandleOldEncryption(std::unique_ptr<UserContext> user_context);
 
   // Returns the `Data` struct used to populate the splash screen.
   AppLaunchSplashScreenView::Data GetSplashScreenAppData();
@@ -225,8 +221,10 @@
   // Whether the controller has already been cleaned-up.
   bool cleaned_up_ = false;
 
-  // Used to login into kiosk user profile.
-  std::unique_ptr<KioskProfileLoader> kiosk_profile_loader_;
+  // Handle to the job returned by `profile_loader_`.
+  std::unique_ptr<CancellableJob> profile_loader_handle_;
+  // The function used to load the Kiosk profile. Overridable in tests.
+  LoadProfileCallback profile_loader_;
 
   std::unique_ptr<app_mode::LacrosLauncher> lacros_launcher_;
 
diff --git a/chrome/browser/ash/login/app_mode/kiosk_launch_controller_unittest.cc b/chrome/browser/ash/login/app_mode/kiosk_launch_controller_unittest.cc
index 1db026eb..3f07881 100644
--- a/chrome/browser/ash/login/app_mode/kiosk_launch_controller_unittest.cc
+++ b/chrome/browser/ash/login/app_mode/kiosk_launch_controller_unittest.cc
@@ -16,6 +16,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/test/bind.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_command_line.h"
 #include "base/test/task_environment.h"
@@ -191,9 +192,6 @@
     keyboard_controller_client_ =
         ChromeKeyboardControllerClientTestHelper::InitializeWithFake();
 
-    disable_wait_timer_and_login_operations_for_testing_ =
-        KioskLaunchController::DisableLoginOperationsForTesting();
-
     can_configure_network_for_testing_ =
         NetworkUiController::SetCanConfigureNetworkForTesting(true);
 
@@ -204,7 +202,7 @@
         std::make_unique<FakeAcceleratorController>();
     accelerator_controller_ = fake_accelerator_controller.get();
     controller_ = std::make_unique<KioskLaunchController>(
-        /*host=*/nullptr, view_.get(),
+        /*host=*/nullptr, view_.get(), FakeLoadProfileCallback(),
         base::BindRepeating(
             &KioskLaunchControllerTest::BuildFakeKioskAppLauncher,
             base::Unretained(this)),
@@ -237,8 +235,6 @@
     return *controller_->GetNetworkUiControllerForTesting();
   }
 
-  KioskProfileLoader::Delegate& profile_controls() { return *controller_; }
-
   FakeKioskAppLauncher& launcher() { return *app_launcher_; }
 
   FakeAcceleratorController& accelerator_controller() {
@@ -280,9 +276,16 @@
 
   KioskAppId kiosk_app_id() { return kiosk_app_id_; }
 
+  void FinishLoadingProfile() {
+    std::move(on_profile_loaded_callback_).Run(profile());
+  }
+  void FinishLoadingProfileWithError(KioskAppLaunchError::Error error) {
+    std::move(on_profile_loaded_callback_).Run(base::unexpected(error));
+  }
+
   void RunUntilAppPrepared() {
     controller().Start(kiosk_app_id(), /*auto_launch=*/false);
-    profile_controls().OnProfileLoaded(profile());
+    FinishLoadingProfile();
     launcher().observers().NotifyAppInstalling();
     launcher().observers().NotifyAppPrepared();
   }
@@ -328,6 +331,15 @@
     return std::move(app_launcher);
   }
 
+  LoadProfileCallback FakeLoadProfileCallback() {
+    return base::BindLambdaForTesting(
+        [&](const AccountId& app_account_id, KioskAppType app_type,
+            KioskProfileLoader::ResultCallback on_done) {
+          on_profile_loaded_callback_ = std::move(on_done);
+          return std::unique_ptr<CancellableJob>{};
+        });
+  }
+
   TestingProfile profile_;
   session_manager::SessionManager session_manager_;
   std::unique_ptr<ChromeKeyboardControllerClientTestHelper>
@@ -340,8 +352,7 @@
   user_manager::TypedScopedUserManager<ash::FakeChromeUserManager>
       fake_user_manager_{std::make_unique<ash::FakeChromeUserManager>()};
 
-  std::unique_ptr<base::AutoReset<bool>>
-      disable_wait_timer_and_login_operations_for_testing_;
+  KioskProfileLoader::ResultCallback on_profile_loaded_callback_;
   std::unique_ptr<FakeAppLaunchSplashScreenHandler> view_;
   raw_ptr<FakeKioskAppLauncher, DanglingUntriaged> app_launcher_ =
       nullptr;  // owned by `controller_`.
@@ -375,20 +386,17 @@
   VerifyLaunchStateCrashKey(KioskLaunchState::kLauncherStarted);
   EXPECT_THAT(controller(), HasState(AppState::kCreatingProfile,
                                      NetworkUIState::kNotShowing));
-
-  profile_controls().OnProfileLoaded(profile());
+  FinishLoadingProfile();
   EXPECT_TRUE(launcher().IsInitialized());
 }
 
-// Late profile load should not launch kiosk session.
-// Covers b/304145218.
-TEST_F(KioskLaunchControllerTest, ProfileLoadedAfterCleanUp) {
+TEST_F(KioskLaunchControllerTest, ProfileLoadDoesNotLaunchAppAfterCleanUp) {
   controller().Start(kiosk_app_id(), /*auto_launch=*/false);
   EXPECT_THAT(controller(), HasState(AppState::kCreatingProfile,
                                      NetworkUIState::kNotShowing));
 
   CleanUpController();
-  profile_controls().OnProfileLoaded(profile());
+  FinishLoadingProfile();
 
   EXPECT_EQ(num_launchers_created(), 0);
 }
@@ -396,7 +404,7 @@
 TEST_F(KioskLaunchControllerTest, AppInstallingShouldUpdateSplashScreen) {
   controller().Start(kiosk_app_id(), /*auto_launch=*/false);
   VerifyLaunchStateCrashKey(KioskLaunchState::kLauncherStarted);
-  profile_controls().OnProfileLoaded(profile());
+  FinishLoadingProfile();
 
   launcher().observers().NotifyAppInstalling();
 
@@ -446,7 +454,7 @@
 TEST_F(KioskLaunchControllerTest,
        SplashScreenTimerShouldNotLaunchUnpreparedApp) {
   controller().Start(kiosk_app_id(), /*auto_launch=*/false);
-  profile_controls().OnProfileLoaded(profile());
+  FinishLoadingProfile();
   launcher().observers().NotifyAppInstalling();
 
   FireSplashScreenTimer();
@@ -474,7 +482,7 @@
 TEST_F(KioskLaunchControllerTest,
        NetworkPresentShouldInvokeContinueWithNetworkReady) {
   controller().Start(kiosk_app_id(), /*auto_launch=*/false);
-  profile_controls().OnProfileLoaded(profile());
+  FinishLoadingProfile();
 
   network_delegate().InitializeNetwork();
   EXPECT_THAT(controller(), HasState(AppState::kInitLauncher,
@@ -492,7 +500,7 @@
 TEST_F(KioskLaunchControllerTest,
        NetworkInitTimeoutShouldShowNetworkConfigureUI) {
   controller().Start(kiosk_app_id(), /*auto_launch=*/false);
-  profile_controls().OnProfileLoaded(profile());
+  FinishLoadingProfile();
 
   network_delegate().InitializeNetwork();
   EXPECT_THAT(controller(), HasState(AppState::kInitLauncher,
@@ -521,7 +529,7 @@
                                      NetworkUIState::kNeedToShow));
   VerifyLaunchStateCrashKey(KioskLaunchState::kLauncherStarted);
 
-  profile_controls().OnProfileLoaded(profile());
+  FinishLoadingProfile();
 
   EXPECT_THAT(controller(),
               HasState(AppState::kInitNetwork, NetworkUIState::kShowing));
@@ -535,7 +543,7 @@
   VerifyLaunchStateCrashKey(KioskLaunchState::kLauncherStarted);
   EXPECT_THAT(controller(), HasState(AppState::kCreatingProfile,
                                      NetworkUIState::kNotShowing));
-  profile_controls().OnProfileLoaded(profile());
+  FinishLoadingProfile();
 
   launcher().observers().NotifyAppInstalling();
 
@@ -568,8 +576,7 @@
 
   EXPECT_CALL(profile_load_failed_observer, OnKioskProfileLoadFailed())
       .Times(1);
-  profile_controls().OnProfileLoadFailed(
-      KioskAppLaunchError::Error::kUnableToMount);
+  FinishLoadingProfileWithError(KioskAppLaunchError::Error::kUnableToMount);
   VerifyLaunchStateCrashKey(KioskLaunchState::kLaunchFailed);
   EXPECT_EQ(num_launchers_created(), 0);
 
@@ -581,8 +588,7 @@
 TEST_F(KioskLaunchControllerTest, KioskProfileLoadErrorShouldBeStored) {
   controller().Start(kiosk_app_id(), /*auto_launch=*/false);
 
-  profile_controls().OnProfileLoadFailed(
-      KioskAppLaunchError::Error::kUnableToMount);
+  FinishLoadingProfileWithError(KioskAppLaunchError::Error::kUnableToMount);
   VerifyLaunchStateCrashKey(KioskLaunchState::kLaunchFailed);
 
   const base::Value::Dict& dict =
@@ -842,7 +848,7 @@
 
   EXPECT_EQ(num_launchers_created(), 0);
 
-  profile_controls().OnProfileLoaded(profile());
+  FinishLoadingProfile();
 
   EXPECT_EQ(launcher().initialize_called(), 1);
   EXPECT_FALSE(launcher().HasAppLaunched());
@@ -895,15 +901,12 @@
     keyboard_controller_client_ =
         ChromeKeyboardControllerClientTestHelper::InitializeWithFake();
 
-    disable_wait_timer_and_login_operations_for_testing_ =
-        KioskLaunchController::DisableLoginOperationsForTesting();
-
     can_configure_network_for_testing_ =
         NetworkUiController::SetCanConfigureNetworkForTesting(true);
 
     view_ = std::make_unique<FakeAppLaunchSplashScreenHandler>();
     controller_ = std::make_unique<KioskLaunchController>(
-        /*host=*/nullptr, view_.get(),
+        /*host=*/nullptr, view_.get(), FakeLoadProfileCallback(),
         base::BindRepeating(
             &KioskLaunchControllerUsingLacrosTest::BuildFakeKioskAppLauncher,
             base::Unretained(this)),
@@ -930,12 +933,16 @@
 
   void RunUntilAppPrepared() {
     controller().Start(kiosk_app_id(), /*auto_launch=*/false);
-    profile_controls().OnProfileLoaded(profile());
+    FinishLoadingProfile();
     EXPECT_TRUE(WaitForNextAppLauncherCreation());
     launcher().observers().NotifyAppInstalling();
     launcher().observers().NotifyAppPrepared();
   }
 
+  void FinishLoadingProfile() {
+    std::move(on_profile_loaded_callback_).Run(profile());
+  }
+
  protected:
   crosapi::FakeBrowserManager& fake_browser_manager() {
     return browser_manager_;
@@ -945,8 +952,6 @@
 
   KioskLaunchController& controller() { return *controller_; }
 
-  KioskProfileLoader::Delegate& profile_controls() { return *controller_; }
-
   FakeKioskAppLauncher& launcher() { return *app_launcher_; }
 
   Profile* profile() { return profile_; }
@@ -987,6 +992,17 @@
     return std::move(app_launcher);
   }
 
+  LoadProfileCallback FakeLoadProfileCallback() {
+    return base::BindLambdaForTesting(
+        [&](const AccountId& app_account_id, KioskAppType app_type,
+            KioskProfileLoader::ResultCallback on_done) {
+          on_profile_loaded_callback_ = std::move(on_done);
+          return std::unique_ptr<CancellableJob>{};
+        });
+  }
+
+  FakeChromeUserManager& fake_user_manager() { return *fake_user_manager_; }
+
   content::BrowserTaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
   ScopedTestingLocalState testing_local_state_{
@@ -1004,8 +1020,7 @@
 
   std::unique_ptr<base::AutoReset<std::optional<bool>>>
       can_configure_network_for_testing_;
-  std::unique_ptr<base::AutoReset<bool>>
-      disable_wait_timer_and_login_operations_for_testing_;
+  KioskProfileLoader::ResultCallback on_profile_loaded_callback_;
   std::unique_ptr<FakeAppLaunchSplashScreenHandler> view_;
   raw_ptr<FakeKioskAppLauncher, DanglingUntriaged> app_launcher_ =
       nullptr;  // owned by `controller_`.
@@ -1023,7 +1038,7 @@
   controller().Start(kiosk_app_id(), /*auto_launch=*/false);
 
   EXPECT_FALSE(fake_browser_manager().IsRunning());
-  profile_controls().OnProfileLoaded(profile());
+  FinishLoadingProfile();
 
   EXPECT_TRUE(fake_browser_manager().IsRunning());
 }
@@ -1033,7 +1048,7 @@
   controller().Start(kiosk_app_id(), /*auto_launch=*/false);
 
   EXPECT_EQ(num_launchers_created(), 0);
-  profile_controls().OnProfileLoaded(profile());
+  FinishLoadingProfile();
 
   EXPECT_TRUE(WaitForNextAppLauncherCreation());
   EXPECT_TRUE(launcher().initialize_called());
diff --git a/chrome/browser/ash/login/app_mode/test/web_kiosk_browsertest.cc b/chrome/browser/ash/login/app_mode/test/web_kiosk_browsertest.cc
index c1127cd..4f4377b 100644
--- a/chrome/browser/ash/login/app_mode/test/web_kiosk_browsertest.cc
+++ b/chrome/browser/ash/login/app_mode/test/web_kiosk_browsertest.cc
@@ -2,16 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <optional>
+
 #include "ash/public/cpp/keyboard/keyboard_controller.h"
 #include "ash/public/cpp/login_screen_test_api.h"
 #include "ash/public/cpp/shelf_config.h"
 #include "ash/public/cpp/shelf_test_api.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
+#include "base/check_deref.h"
 #include "base/feature_list.h"
-#include "base/run_loop.h"
-#include "base/test/bind.h"
 #include "base/test/gtest_tags.h"
+#include "base/test/test_future.h"
 #include "base/time/time.h"
 #include "chrome/browser/ash/app_mode/kiosk_app_types.h"
 #include "chrome/browser/ash/app_mode/kiosk_profile_loader.h"
@@ -32,12 +34,10 @@
 #include "chrome/browser/ui/webui/ash/login/gaia_screen_handler.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/mojom/user_display_mode.mojom.h"
 #include "chrome/browser/web_applications/web_app_constants.h"
 #include "chrome/browser/web_applications/web_app_install_info.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/common/chrome_features.h"
-#include "components/account_id/account_id.h"
 #include "components/webapps/browser/install_result_code.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/url_loader_interceptor.h"
@@ -47,17 +47,55 @@
 namespace ash {
 namespace {
 
+using ::base::test::TestFuture;
 using ::testing::_;
 
 const test::UIPath kNetworkConfigureScreenContinueButton = {"error-message",
                                                             "continueButton"};
 
-class FakeKioskProfileLoaderDelegate : public KioskProfileLoader::Delegate {
- public:
-  MOCK_METHOD1(OnProfileLoaded, void(Profile*));
-  MOCK_METHOD1(OnProfileLoadFailed, void(KioskAppLaunchError::Error));
-  MOCK_METHOD1(OnOldEncryptionDetected, void(std::unique_ptr<UserContext>));
-};
+std::optional<Profile*> LoadKioskProfile(const AccountId& account_id) {
+  TestFuture<absl::optional<Profile*>> profile_future;
+  auto profile_loader = LoadProfile(
+      account_id, KioskAppType::kWebApp,
+      base::BindOnce([](KioskProfileLoader::Result result) {
+        return result.has_value() ? absl::make_optional(result.value())
+                                  : absl::nullopt;
+      }).Then(profile_future.GetCallback()));
+  return profile_future.Take();
+}
+
+// TODO(b/322497609) Replace `URLLoaderInterceptor` with `EmbeddedTestServer`.
+content::URLLoaderInterceptor SimplePageInterceptor() {
+  return content::URLLoaderInterceptor(base::BindRepeating(
+      [](content::URLLoaderInterceptor::RequestParams* params) {
+        content::URLLoaderInterceptor::WriteResponse(
+            "content/test/data/simple_page.html", params->client.get());
+        return true;
+      }));
+}
+
+bool InstallKioskWebAppInProvider(Profile& profile) {
+  // Serve a real page to avoid installing a placeholder app.
+  auto url_interceptor = SimplePageInterceptor();
+
+  TestFuture<bool> success_future;
+
+  auto* provider = web_app::WebAppProvider::GetForLocalAppsUnchecked(&profile);
+
+  web_app::ExternalInstallOptions install_options(
+      GURL(kAppInstallUrl), web_app::mojom::UserDisplayMode::kStandalone,
+      web_app::ExternalInstallSource::kKiosk);
+  install_options.install_placeholder = true;
+
+  provider->externally_managed_app_manager().InstallNow(
+      install_options,
+      base::BindOnce([](const GURL& install_url,
+                        web_app::ExternallyManagedAppManager::InstallResult
+                            result) {
+        return webapps::IsSuccess(result.code);
+      }).Then(success_future.GetCallback()));
+  return success_future.Wait();
+}
 
 class WebKioskTest : public WebKioskBaseTest {
  public:
@@ -66,45 +104,12 @@
   WebKioskTest(const WebKioskTest&) = delete;
   WebKioskTest& operator=(const WebKioskTest&) = delete;
 
-  void MakeAppAlreadyInstalled() {
-    // Intercept URL loader to avoid installing a placeholder app.
-    content::URLLoaderInterceptor url_interceptor(base::BindRepeating(
-        [](content::URLLoaderInterceptor::RequestParams* params) {
-          content::URLLoaderInterceptor::WriteResponse(
-              "content/test/data/simple_page.html", params->client.get());
-          return true;
-        }));
-
-    FakeKioskProfileLoaderDelegate fake_delegate;
-    KioskProfileLoader profile_loader(account_id(), KioskAppType::kWebApp,
-                                      &fake_delegate);
-
-    base::RunLoop loop;
-    EXPECT_CALL(fake_delegate, OnProfileLoaded(_))
-        .WillOnce([&loop](Profile* profile) {
-          // When Kiosk profile is loaded, install Kiosk web app to
-          // WebAppProvider.
-          auto* provider =
-              web_app::WebAppProvider::GetForLocalAppsUnchecked(profile);
-          web_app::ExternalInstallOptions install_options(
-              GURL(kAppInstallUrl),
-              web_app::mojom::UserDisplayMode::kStandalone,
-              web_app::ExternalInstallSource::kKiosk);
-          install_options.install_placeholder = true;
-          provider->externally_managed_app_manager().InstallNow(
-              install_options,
-              base::BindLambdaForTesting(
-                  [&loop](const GURL& install_url,
-                          web_app::ExternallyManagedAppManager::InstallResult
-                              result) {
-                    ASSERT_TRUE(webapps::IsSuccess(result.code));
-                    Shell::Get()->session_controller()->RequestSignOut();
-                    loop.Quit();
-                  }));
-        });
-
-    profile_loader.Start();
-    loop.Run();
+  void EnsureAppIsInstalled() {
+    std::optional<Profile*> profile = LoadKioskProfile(account_id());
+    ASSERT_TRUE(profile.has_value());
+    ASSERT_TRUE(InstallKioskWebAppInProvider(CHECK_DEREF(*profile)))
+        << "App was not installed";
+    Shell::Get()->session_controller()->RequestSignOut();
   }
 
   void SetBlockAppLaunch(bool block) {
@@ -194,7 +199,7 @@
 // launching offline.
 IN_PROC_BROWSER_TEST_F(WebKioskTest, PRE_AlreadyInstalledOffline) {
   PrepareAppLaunch();
-  MakeAppAlreadyInstalled();
+  EnsureAppIsInstalled();
 }
 
 // Runs the kiosk app offline when it has been already installed.
@@ -233,7 +238,7 @@
 IN_PROC_BROWSER_TEST_F(WebKioskTest,
                        PRE_AlreadyInstalledWithConfigureAcceleratorPressed) {
   PrepareAppLaunch();
-  MakeAppAlreadyInstalled();
+  EnsureAppIsInstalled();
 }
 
 // In case when the app was already installed, we should expect to be able to
diff --git a/chrome/browser/ash/login/screens/user_creation_screen.cc b/chrome/browser/ash/login/screens/user_creation_screen.cc
index 1c520e8d..6838a64 100644
--- a/chrome/browser/ash/login/screens/user_creation_screen.cc
+++ b/chrome/browser/ash/login/screens/user_creation_screen.cc
@@ -171,6 +171,13 @@
   return false;
 }
 
+void UserCreationScreen::SetDefaultStep() {
+  if (!view_) {
+    return;
+  }
+  view_->SetDefaultStep();
+}
+
 void UserCreationScreen::UpdateState(NetworkError::ErrorReason reason) {
   NetworkStateInformer::State state = network_state_informer_->state();
   if (state != NetworkStateInformer::ONLINE ||
diff --git a/chrome/browser/ash/login/screens/user_creation_screen.h b/chrome/browser/ash/login/screens/user_creation_screen.h
index 8dc6fd50..f1b6abe 100644
--- a/chrome/browser/ash/login/screens/user_creation_screen.h
+++ b/chrome/browser/ash/login/screens/user_creation_screen.h
@@ -64,6 +64,7 @@
       UserCreationScreenExitTestDelegate* test_delegate);
 
   void SetChildSetupStep();
+  void SetDefaultStep();
 
  private:
   // BaseScreen:
diff --git a/chrome/browser/ash/login/screens/user_creation_screen_browsertest.cc b/chrome/browser/ash/login/screens/user_creation_screen_browsertest.cc
index 4c2f022..175df7d 100644
--- a/chrome/browser/ash/login/screens/user_creation_screen_browsertest.cc
+++ b/chrome/browser/ash/login/screens/user_creation_screen_browsertest.cc
@@ -292,6 +292,18 @@
   test::OobeJS().TapOnPath(kEnrollTriageNextButton);
   WaitForScreenExit();
   EXPECT_EQ(screen_result_.value(), UserCreationScreen::Result::SIGNIN_TRIAGE);
+
+  OobeScreenWaiter(GaiaView::kScreenId).Wait();
+  test::OobeJS()
+      .CreateVisibilityWaiter(
+          true, {"gaia-signin", "signin-frame-dialog", "signin-back-button"})
+      ->Wait();
+
+  test::OobeJS().ClickOnPath(
+      {"gaia-signin", "signin-frame-dialog", "signin-back-button"});
+
+  OobeScreenWaiter(UserCreationView::kScreenId).Wait();
+  test::OobeJS().ExpectVisiblePath(kUserCreationEnrollTriageDialog);
 }
 
 // Verify that enroll-device in the enorll triage step in user creation
@@ -304,6 +316,14 @@
   WaitForScreenExit();
   EXPECT_EQ(screen_result_.value(),
             UserCreationScreen::Result::ENTERPRISE_ENROLL_TRIAGE);
+
+  OobeScreenWaiter(EnrollmentScreenView::kScreenId).Wait();
+
+  LoginDisplayHost::default_host()->HandleAccelerator(
+      LoginAcceleratorAction::kCancelScreenAction);
+
+  OobeScreenWaiter(UserCreationView::kScreenId).Wait();
+  test::OobeJS().ExpectVisiblePath(kUserCreationDialog);
 }
 
 // Verify that back button display create step in the child setup step
diff --git a/chrome/browser/ash/login/wizard_controller.cc b/chrome/browser/ash/login/wizard_controller.cc
index 75f29426..5be880e 100644
--- a/chrome/browser/ash/login/wizard_controller.cc
+++ b/chrome/browser/ash/login/wizard_controller.cc
@@ -2111,6 +2111,9 @@
       PerformOOBECompletedActions(
           OobeMetricsHelper::CompletedPreLoginOobeFlowType::kAutoEnrollment);
       DCHECK(!prescribed_enrollment_config_.is_forced());
+      // set  the userCreationScreen with the default step creation and
+      // pre-select 'For personal use'.
+      GetScreen<UserCreationScreen>()->SetDefaultStep();
       ShowLoginScreen();
       break;
     case EnrollmentScreen::Result::TPM_ERROR:
diff --git a/chrome/browser/ash/policy/core/device_policy_decoder.cc b/chrome/browser/ash/policy/core/device_policy_decoder.cc
index c7cef61..e8d7691 100644
--- a/chrome/browser/ash/policy/core/device_policy_decoder.cc
+++ b/chrome/browser/ash/policy/core/device_policy_decoder.cc
@@ -2263,9 +2263,9 @@
   }
 
   if (policy.has_deviceloginscreentouchvirtualkeyboardenabled()) {
-    if (const em::BooleanPolicyProto &
-            container(policy.deviceloginscreentouchvirtualkeyboardenabled());
-        container.has_value()) {
+    const em::BooleanPolicyProto& container(
+        policy.deviceloginscreentouchvirtualkeyboardenabled());
+    if (container.has_value()) {
       policies->Set(key::kTouchVirtualKeyboardEnabled, POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD,
                     base::Value(container.value()), nullptr);
@@ -2273,6 +2273,19 @@
   }
 }
 
+// TODO(b/324221325): Move other Kiosk-related policies to this function.
+void DecodeKioskPolicies(const em::ChromeDeviceSettingsProto& policy,
+                         PolicyMap* policies) {
+  if (policy.has_deviceweeklyscheduledsuspend()) {
+    const em::StringPolicyProto& container(
+        policy.deviceweeklyscheduledsuspend());
+    if (container.has_value()) {
+      SetJsonDevicePolicy(key::kDeviceWeeklyScheduledSuspend, container.value(),
+                          policies);
+    }
+  }
+}
+
 }  // namespace
 
 std::optional<base::Value> DecodeJsonStringAndNormalize(
@@ -2328,6 +2341,7 @@
   DecodeAutoUpdatePolicies(policy, policies);
   DecodeAccessibilityPolicies(policy, policies);
   DecodeExternalDataPolicies(policy, external_data_manager, policies);
+  DecodeKioskPolicies(policy, policies);
   DecodeGenericPolicies(policy, policies);
 }
 
diff --git a/chrome/browser/ash/policy/core/device_policy_decoder_unittest.cc b/chrome/browser/ash/policy/core/device_policy_decoder_unittest.cc
index 15531344..917f0f1f 100644
--- a/chrome/browser/ash/policy/core/device_policy_decoder_unittest.cc
+++ b/chrome/browser/ash/policy/core/device_policy_decoder_unittest.cc
@@ -5,17 +5,22 @@
 #include "chrome/browser/ash/policy/core/device_policy_decoder.h"
 
 #include <memory>
+#include <vector>
 
 #include "base/functional/bind.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/browser/ash/policy/core/device_local_account.h"
+#include "chromeos/ash/components/policy/weekly_time/weekly_time.h"
+#include "chromeos/ash/components/policy/weekly_time/weekly_time_interval.h"
 #include "chromeos/ash/components/settings/cros_settings_names.h"
 #include "components/policy/core/common/policy_bundle.h"
 #include "components/policy/policy_constants.h"
 #include "components/policy/proto/chrome_device_policy.pb.h"
 #include "components/strings/grit/components_strings.h"
 #include "policy_common_definitions.pb.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -60,6 +65,29 @@
 
 constexpr char kDeviceLocalAccountKioskAccountId[] = "kiosk_account_id";
 
+constexpr char kValidDeviceWeeklyScheduledSuspendList[] = R"([
+    {
+      "start": {
+        "day_of_week": "MONDAY",
+        "time": 64800000
+      },
+      "end": {
+        "day_of_week": "TUESDAY",
+        "time": 28800000
+      }
+    },
+    {
+      "start": {
+        "day_of_week": "FRIDAY",
+        "time": 75600000
+      },
+      "end": {
+        "day_of_week": "MONDAY",
+        "time": 25200000
+      }
+    }
+])";
+
 }  // namespace
 
 class DevicePolicyDecoderTest : public testing::Test {
@@ -74,6 +102,7 @@
  protected:
   base::Value GetWallpaperDict() const;
   base::Value GetBluetoothServiceAllowedList() const;
+  std::vector<WeeklyTimeInterval> GetDeviceWeeklyScheduledSuspendList() const;
   void DecodeDevicePolicyTestHelper(
       const em::ChromeDeviceSettingsProto& device_policy,
       const std::string& policy_path,
@@ -97,6 +126,23 @@
                          .Append(kValidBluetoothServiceUUID32));
 }
 
+std::vector<WeeklyTimeInterval>
+DevicePolicyDecoderTest::GetDeviceWeeklyScheduledSuspendList() const {
+  using time_proto = em::WeeklyTimeProto;
+  std::vector<WeeklyTimeInterval> ret;
+  ret.emplace_back(
+      WeeklyTime(time_proto::MONDAY, base::Hours(18).InMilliseconds(),
+                 /*timezone_offset=*/std::nullopt),
+      WeeklyTime(time_proto::TUESDAY, base::Hours(8).InMilliseconds(),
+                 /*timezone_offset=*/std::nullopt));
+  ret.emplace_back(
+      WeeklyTime(time_proto::FRIDAY, base::Hours(21).InMilliseconds(),
+                 /*timezone_offset=*/std::nullopt),
+      WeeklyTime(time_proto::MONDAY, base::Hours(7).InMilliseconds(),
+                 /*timezone_offset=*/std::nullopt));
+  return ret;
+}
+
 void DevicePolicyDecoderTest::DecodeDevicePolicyTestHelper(
     const em::ChromeDeviceSettingsProto& device_policy,
     const std::string& policy_path,
@@ -736,4 +782,39 @@
                                std::move(deviceextendedautoupdateenabled));
 }
 
+TEST_F(DevicePolicyDecoderTest, DecodeDeviceWeeklyScheduledSuspendSuccess) {
+  std::string error;
+  std::optional<base::Value> decoded_json =
+      DecodeJsonStringAndNormalize(kValidDeviceWeeklyScheduledSuspendList,
+                                   key::kDeviceWeeklyScheduledSuspend, &error);
+  ASSERT_TRUE(decoded_json.has_value());
+  ASSERT_TRUE(decoded_json->is_list());
+
+  std::vector<WeeklyTimeInterval> actual_list;
+  for (const auto& item : decoded_json->GetList()) {
+    ASSERT_TRUE(item.is_dict());
+    std::unique_ptr<WeeklyTimeInterval> interval =
+        WeeklyTimeInterval::ExtractFromDict(item.GetDict(),
+                                            /*timezone_offset=*/std::nullopt);
+    ASSERT_TRUE(interval);
+    actual_list.emplace_back(std::move(*interval));
+  }
+
+  EXPECT_EQ(GetDeviceWeeklyScheduledSuspendList(), actual_list);
+  EXPECT_THAT(error, ::testing::IsEmpty());
+}
+
+TEST_F(DevicePolicyDecoderTest,
+       DecodeDeviceWeeklyScheduledSuspendInvalidJsonError) {
+  std::string error;
+  std::optional<base::Value> decoded_json = DecodeJsonStringAndNormalize(
+      kInvalidJson, key::kDeviceWeeklyScheduledSuspend, &error);
+  EXPECT_FALSE(decoded_json.has_value());
+  std::string localized_error = l10n_util::GetStringFUTF8(
+      IDS_POLICY_PROTO_PARSING_ERROR, base::UTF8ToUTF16(error));
+  EXPECT_THAT(
+      localized_error,
+      ::testing::HasSubstr("Policy parsing error: Invalid JSON string"));
+}
+
 }  // namespace policy
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
index 0fc387c0..5bcae82 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -949,16 +949,22 @@
         profile_, ServiceAccessType::EXPLICIT_ACCESS);
 
     if (account_store) {
-      // A sync completion callback is passed in for account
-      // passwords, in order to ensure that the passwords are cleared before the
-      // user is signed out via cookie deletion.
-      // TODO:(crbug.com/1167715) - Test that associated compromised credentials
-      // are removed.
+      // Desktop must wait for DATA_TYPE_ACCOUNT_PASSWORDS deletions to be
+      // uploaded to the sync server before deleting any other types (because
+      // deleting DATA_TYPE_COOKIES first would revoke the account storage
+      // opt-in and prevent the upload).
+      // On Android, the account storage doesn't depend on cookies, so there's
+      // no need to wait.
+      base::OnceCallback<void(bool)> sync_completion;
+#if !BUILDFLAG(IS_ANDROID)
+      sync_completion =
+          CreateTaskCompletionCallback(TracingDataType::kAccountPasswordsSynced,
+                                       constants::DATA_TYPE_ACCOUNT_PASSWORDS);
+#endif
       account_store->RemoveLoginsByURLAndTime(
           filter, delete_begin_, delete_end_,
           CreateTaskCompletionClosure(TracingDataType::kAccountPasswords),
-          CreateTaskCompletionCallback(TracingDataType::kAccountPasswordsSynced,
-                                       constants::DATA_TYPE_ACCOUNT_PASSWORDS));
+          std::move(sync_completion));
     }
   }
 
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
index f3cd8c9c..9bfdf526 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -3963,19 +3963,23 @@
   EXPECT_CALL(*profile_password_store(), RemoveLoginsByURLAndTime).Times(0);
   ExpectRemoveLoginsByURLAndTime(account_password_store());
 
-  BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(),
-                                constants::DATA_TYPE_ACCOUNT_PASSWORDS, false);
-}
-
-TEST_F(ChromeBrowsingDataRemoverDelegateWithAccountPasswordsTest,
-       RemoveAccountPasswordsByTimeOnly_WithAccountStore_Failure) {
-  EXPECT_CALL(*profile_password_store(), RemoveLoginsByURLAndTime).Times(0);
-  ExpectRemoveLoginsByURLAndTime(account_password_store());
-
   uint64_t failed_data_types = BlockUntilBrowsingDataRemoved(
       base::Time(), base::Time::Max(), constants::DATA_TYPE_ACCOUNT_PASSWORDS,
       false);
-  EXPECT_EQ(failed_data_types, constants::DATA_TYPE_ACCOUNT_PASSWORDS);
+  // Desktop waits for DATA_TYPE_ACCOUNT_PASSWORDS deletions to be uploaded to
+  // the sync server before deleting any other types (because deleting
+  // DATA_TYPE_COOKIES first would revoke the account storage opt-in and prevent
+  // the upload). In this test, deletions are never uploaded, so
+  // DATA_TYPE_ACCOUNT_PASSWORDS is reported as failed.
+  // On Android, the account storage doesn't depend on cookies, so there's no
+  // waiting logic and DATA_TYPE_ACCOUNT_PASSWORDS is reported as successful.
+  EXPECT_EQ(failed_data_types,
+#if BUILDFLAG(IS_ANDROID)
+            0u
+#else
+            constants::DATA_TYPE_ACCOUNT_PASSWORDS
+#endif
+  );
 }
 
 TEST_F(ChromeBrowsingDataRemoverDelegateTest,
diff --git a/chrome/browser/browsing_data/counters/browsing_data_counter_factory.cc b/chrome/browser/browsing_data/counters/browsing_data_counter_factory.cc
index f3ede720..41e179d 100644
--- a/chrome/browser/browsing_data/counters/browsing_data_counter_factory.cc
+++ b/chrome/browser/browsing_data/counters/browsing_data_counter_factory.cc
@@ -105,7 +105,7 @@
             profile, ServiceAccessType::EXPLICIT_ACCESS),
         AccountPasswordStoreFactory::GetForProfile(
             profile, ServiceAccessType::EXPLICIT_ACCESS),
-        SyncServiceFactory::GetForProfile(profile),
+        profile->GetPrefs(), SyncServiceFactory::GetForProfile(profile),
         std::move(credential_store));
   }
 
diff --git a/chrome/browser/browsing_data/counters/browsing_data_counter_utils_unittest.cc b/chrome/browser/browsing_data/counters/browsing_data_counter_utils_unittest.cc
index c49d2e87..ee78466 100644
--- a/chrome/browser/browsing_data/counters/browsing_data_counter_utils_unittest.cc
+++ b/chrome/browser/browsing_data/counters/browsing_data_counter_utils_unittest.cc
@@ -200,8 +200,9 @@
   // This counter does not really count anything; we just need a reference to
   // pass to the SigninDataResult ctor.
   browsing_data::SigninDataCounter counter(
-      password_store, nullptr, SyncServiceFactory::GetForProfile(GetProfile()),
-      nullptr);
+      /*profile_store=*/password_store, /*account_store=*/nullptr,
+      /*pref_service=*/nullptr, SyncServiceFactory::GetForProfile(GetProfile()),
+      /*opt_platform_credential_store=*/nullptr);
 
   // Use a separate struct for input to make test cases easier to read after
   // auto formatting.
diff --git a/chrome/browser/browsing_data/counters/passwords_counter_browsertest.cc b/chrome/browser/browsing_data/counters/passwords_counter_browsertest.cc
index 53f9bb0..4688248 100644
--- a/chrome/browser/browsing_data/counters/passwords_counter_browsertest.cc
+++ b/chrome/browser/browsing_data/counters/passwords_counter_browsertest.cc
@@ -175,7 +175,7 @@
           profile, ServiceAccessType::EXPLICIT_ACCESS),
       AccountPasswordStoreFactory::GetForProfile(
           profile, ServiceAccessType::EXPLICIT_ACCESS),
-      SyncServiceFactory::GetForProfile(profile));
+      profile->GetPrefs(), SyncServiceFactory::GetForProfile(profile));
   counter.Init(profile->GetPrefs(),
                browsing_data::ClearBrowsingDataTab::ADVANCED,
                base::BindRepeating(&PasswordsCounterTest::Callback,
@@ -198,7 +198,7 @@
           profile, ServiceAccessType::EXPLICIT_ACCESS),
       AccountPasswordStoreFactory::GetForProfile(
           profile, ServiceAccessType::EXPLICIT_ACCESS),
-      SyncServiceFactory::GetForProfile(profile));
+      profile->GetPrefs(), SyncServiceFactory::GetForProfile(profile));
 
   counter.Init(profile->GetPrefs(),
                browsing_data::ClearBrowsingDataTab::ADVANCED,
@@ -223,7 +223,7 @@
           profile, ServiceAccessType::EXPLICIT_ACCESS),
       AccountPasswordStoreFactory::GetForProfile(
           profile, ServiceAccessType::EXPLICIT_ACCESS),
-      SyncServiceFactory::GetForProfile(profile));
+      profile->GetPrefs(), SyncServiceFactory::GetForProfile(profile));
   counter.Init(profile->GetPrefs(),
                browsing_data::ClearBrowsingDataTab::ADVANCED,
                base::BindRepeating(&PasswordsCounterTest::Callback,
@@ -245,7 +245,7 @@
           profile, ServiceAccessType::EXPLICIT_ACCESS),
       AccountPasswordStoreFactory::GetForProfile(
           profile, ServiceAccessType::EXPLICIT_ACCESS),
-      SyncServiceFactory::GetForProfile(profile));
+      profile->GetPrefs(), SyncServiceFactory::GetForProfile(profile));
   counter.Init(profile->GetPrefs(),
                browsing_data::ClearBrowsingDataTab::ADVANCED,
                base::BindRepeating(&PasswordsCounterTest::Callback,
@@ -281,7 +281,7 @@
           profile, ServiceAccessType::EXPLICIT_ACCESS),
       AccountPasswordStoreFactory::GetForProfile(
           profile, ServiceAccessType::EXPLICIT_ACCESS),
-      SyncServiceFactory::GetForProfile(profile));
+      profile->GetPrefs(), SyncServiceFactory::GetForProfile(profile));
   counter.Init(profile->GetPrefs(),
                browsing_data::ClearBrowsingDataTab::ADVANCED,
                base::BindRepeating(&PasswordsCounterTest::Callback,
@@ -330,7 +330,7 @@
           profile, ServiceAccessType::EXPLICIT_ACCESS),
       AccountPasswordStoreFactory::GetForProfile(
           profile, ServiceAccessType::EXPLICIT_ACCESS),
-      SyncServiceFactory::GetForProfile(profile));
+      profile->GetPrefs(), SyncServiceFactory::GetForProfile(profile));
   counter.Init(profile->GetPrefs(),
                browsing_data::ClearBrowsingDataTab::ADVANCED,
                base::BindRepeating(&PasswordsCounterTest::Callback,
@@ -351,7 +351,7 @@
           profile, ServiceAccessType::EXPLICIT_ACCESS),
       AccountPasswordStoreFactory::GetForProfile(
           profile, ServiceAccessType::EXPLICIT_ACCESS),
-      SyncServiceFactory::GetForProfile(profile));
+      profile->GetPrefs(), SyncServiceFactory::GetForProfile(profile));
   counter.Init(profile->GetPrefs(),
                browsing_data::ClearBrowsingDataTab::ADVANCED,
                base::BindRepeating(&PasswordsCounterTest::Callback,
diff --git a/chrome/browser/browsing_data/counters/signin_data_counter.cc b/chrome/browser/browsing_data/counters/signin_data_counter.cc
index da3aef82..164f51d9 100644
--- a/chrome/browser/browsing_data/counters/signin_data_counter.cc
+++ b/chrome/browser/browsing_data/counters/signin_data_counter.cc
@@ -14,10 +14,14 @@
 SigninDataCounter::SigninDataCounter(
     scoped_refptr<password_manager::PasswordStoreInterface> profile_store,
     scoped_refptr<password_manager::PasswordStoreInterface> account_store,
+    PrefService* pref_service,
     syncer::SyncService* sync_service,
     std::unique_ptr<::device::fido::PlatformCredentialStore>
         opt_platform_credential_store)
-    : PasswordsCounter(profile_store, account_store, sync_service),
+    : PasswordsCounter(profile_store,
+                       account_store,
+                       pref_service,
+                       sync_service),
       credential_store_(std::move(opt_platform_credential_store)) {}
 
 SigninDataCounter::~SigninDataCounter() = default;
@@ -58,7 +62,6 @@
 
 std::unique_ptr<PasswordsCounter::PasswordsResult>
 SigninDataCounter::MakeResult() {
-  DCHECK(!(is_sync_active() && num_account_passwords() > 0));
   return std::make_unique<SigninDataResult>(
       this, num_passwords(), num_account_passwords(), num_webauthn_credentials_,
       is_sync_active(), domain_examples(), account_domain_examples());
diff --git a/chrome/browser/browsing_data/counters/signin_data_counter.h b/chrome/browser/browsing_data/counters/signin_data_counter.h
index 879348d..6b4d5fb 100644
--- a/chrome/browser/browsing_data/counters/signin_data_counter.h
+++ b/chrome/browser/browsing_data/counters/signin_data_counter.h
@@ -13,6 +13,8 @@
 #include "components/browsing_data/core/counters/passwords_counter.h"
 #include "device/fido/platform_credential_store.h"
 
+class PrefService;
+
 namespace browsing_data {
 
 class SigninDataCounter : public PasswordsCounter {
@@ -39,6 +41,7 @@
   SigninDataCounter(
       scoped_refptr<password_manager::PasswordStoreInterface> profile_store,
       scoped_refptr<password_manager::PasswordStoreInterface> account_store,
+      PrefService* pref_service,
       syncer::SyncService* sync_service,
       std::unique_ptr<::device::fido::PlatformCredentialStore>
           opt_platform_credential_store);
diff --git a/chrome/browser/browsing_data/counters/sync_aware_counter_browsertest.cc b/chrome/browser/browsing_data/counters/sync_aware_counter_browsertest.cc
index 3b24b7f..b66a0b4 100644
--- a/chrome/browser/browsing_data/counters/sync_aware_counter_browsertest.cc
+++ b/chrome/browser/browsing_data/counters/sync_aware_counter_browsertest.cc
@@ -179,7 +179,7 @@
           profile, ServiceAccessType::EXPLICIT_ACCESS),
       AccountPasswordStoreFactory::GetForProfile(
           profile, ServiceAccessType::EXPLICIT_ACCESS),
-      sync_service);
+      profile->GetPrefs(), sync_service);
 
   counter.Init(profile->GetPrefs(),
                browsing_data::ClearBrowsingDataTab::ADVANCED,
diff --git a/chrome/browser/chromeos/app_mode/kiosk_browser_session.cc b/chrome/browser/chromeos/app_mode/kiosk_browser_session.cc
index bce99ab0..b8032ef9 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_browser_session.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_browser_session.cc
@@ -247,11 +247,6 @@
   metrics_service_->RecordKioskSessionWebStarted();
 }
 
-void KioskBrowserSession::SetAttemptUserExitForTesting(
-    base::OnceClosure closure) {
-  attempt_user_exit_ = std::move(closure);
-}
-
 void KioskBrowserSession::SetOnHandleBrowserCallbackForTesting(
     base::RepeatingCallback<void(bool is_closing)> callback) {
   on_handle_browser_callback_ = std::move(callback);
diff --git a/chrome/browser/chromeos/app_mode/kiosk_browser_session.h b/chrome/browser/chromeos/app_mode/kiosk_browser_session.h
index 7f886fa..4841cc4d 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_browser_session.h
+++ b/chrome/browser/chromeos/app_mode/kiosk_browser_session.h
@@ -65,9 +65,6 @@
   // Invoked when GuestViewManager adds a guest web contents.
   void OnGuestAdded(content::WebContents* guest_web_contents);
 
-  // Replaces chrome::AttemptUserExit() by `closure`.
-  void SetAttemptUserExitForTesting(base::OnceClosure closure);
-
   Browser* GetSettingsBrowserForTesting();
   void SetOnHandleBrowserCallbackForTesting(
       base::RepeatingCallback<void(bool is_closing)> callback);
diff --git a/chrome/browser/chromeos/app_mode/kiosk_browser_session_unittest.cc b/chrome/browser/chromeos/app_mode/kiosk_browser_session_unittest.cc
index 1b894c0..0b6ac29 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_browser_session_unittest.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_browser_session_unittest.cc
@@ -328,14 +328,14 @@
   // `new_browser_window` and returns whether `new_browser_window` was asked to
   // close. In this case we will also ensure that `new_browser_window` was
   // automatically closed.
-  bool DidSessionCloseNewWindow(BrowserWindow* new_browser_window) {
+  bool DidSessionCloseNewWindow(const Browser& new_browser) {
     // Wait until the new window is handled by `kiosk_browser_session_`.
     base::test::TestFuture<bool> is_handled;
     kiosk_browser_session_->SetOnHandleBrowserCallbackForTesting(
         is_handled.GetRepeatingCallback());
     bool is_closed_by_kiosk_session = is_handled.Get();
 
-    EXPECT_EQ(IsClosed(*new_browser_window), is_closed_by_kiosk_session);
+    EXPECT_EQ(IsClosed(new_browser), is_closed_by_kiosk_session);
     return is_closed_by_kiosk_session;
   }
 
@@ -350,7 +350,7 @@
   }
 
   bool IsClosed(const Browser& browser) const {
-    return IsClosed(CHECK_DEREF(browser.window()));
+    return browser.tab_strip_model()->closing_all();
   }
 
   bool IsClosed(const BrowserWindow& browser_window) const {
@@ -407,8 +407,7 @@
                                  KioskSessionState::kWebStarted, 1);
   histogram()->ExpectTotalCount(kKioskSessionCountPerDayHistogram, 1);
 
-  EXPECT_TRUE(
-      DidSessionCloseNewWindow(CreateBrowserWithTestWindow()->window()));
+  EXPECT_TRUE(DidSessionCloseNewWindow(*CreateBrowserWithTestWindow()));
 
   // The main browser window still exists, the kiosk session should not
   // shutdown.
@@ -443,8 +442,7 @@
 TEST_F(KioskBrowserSessionTest, ChromeAppKioskTracksBrowserCreation) {
   StartChromeAppKioskSession();
 
-  EXPECT_TRUE(
-      DidSessionCloseNewWindow(CreateBrowserWithTestWindow()->window()));
+  EXPECT_TRUE(DidSessionCloseNewWindow(*CreateBrowserWithTestWindow()));
   // Closing the browser should not shutdown the ChromeApp kiosk session.
   EXPECT_FALSE(IsSessionShuttingDown());
   histogram()->ExpectBucketCount(kKioskNewBrowserWindowHistogram,
@@ -478,7 +476,7 @@
 
   StartChromeAppKioskSession();
 
-  ASSERT_TRUE(closed_future.IsReady());
+  ASSERT_TRUE(IsClosed(*preexisting_browser));
 }
 
 TEST_F(KioskBrowserSessionTest, WebKioskShouldClosePreexistingBrowsers) {
@@ -561,16 +559,16 @@
 TEST_F(KioskBrowserSessionTest, DoNotOpenSecondBrowserInWebKiosk) {
   StartWebKioskSession(kTestWebAppName1);
 
-  EXPECT_TRUE(DidSessionCloseNewWindow(
-      CreateBrowserForWebApp(kTestWebAppName1)->window()));
+  EXPECT_TRUE(
+      DidSessionCloseNewWindow(*CreateBrowserForWebApp(kTestWebAppName1)));
 }
 
 TEST_F(KioskBrowserSessionTest, OpenSecondBrowserInWebKioskIfAllowed) {
   GetPrefs()->SetBoolean(prefs::kNewWindowsInKioskAllowed, true);
   StartWebKioskSession(kTestWebAppName1);
 
-  EXPECT_FALSE(DidSessionCloseNewWindow(
-      CreateBrowserForWebApp(kTestWebAppName1)->window()));
+  EXPECT_FALSE(
+      DidSessionCloseNewWindow(*CreateBrowserForWebApp(kTestWebAppName1)));
 }
 
 TEST_F(KioskBrowserSessionTest, EnsureSecondBrowserIsFullscreenInWebKiosk) {
@@ -579,7 +577,7 @@
   EXPECT_TRUE(IsMainBrowserFullscreen());
 
   auto second_browser = CreateBrowserForWebApp(kTestWebAppName1);
-  DidSessionCloseNewWindow(second_browser->window());
+  DidSessionCloseNewWindow(*second_browser);
 
   EXPECT_TRUE(IsBrowserFullscreen(*second_browser));
 }
@@ -602,7 +600,7 @@
 
   for (auto browser_type : not_app_popup_browser_types) {
     EXPECT_TRUE(DidSessionCloseNewWindow(
-        CreateBrowserForWebApp(kTestWebAppName1, browser_type)->window()));
+        *CreateBrowserForWebApp(kTestWebAppName1, browser_type)));
   }
 }
 
@@ -611,8 +609,7 @@
   GetPrefs()->SetBoolean(prefs::kNewWindowsInKioskAllowed, true);
   StartWebKioskSession();
 
-  EXPECT_TRUE(
-      DidSessionCloseNewWindow(CreateBrowserWithTestWindow()->window()));
+  EXPECT_TRUE(DidSessionCloseNewWindow(*CreateBrowserWithTestWindow()));
 }
 
 TEST_F(KioskBrowserSessionTest,
@@ -620,8 +617,8 @@
   GetPrefs()->SetBoolean(prefs::kNewWindowsInKioskAllowed, true);
   StartWebKioskSession(kTestWebAppName1);
 
-  EXPECT_TRUE(DidSessionCloseNewWindow(
-      CreateBrowserForWebApp(kTestWebAppName2)->window()));
+  EXPECT_TRUE(
+      DidSessionCloseNewWindow(*CreateBrowserForWebApp(kTestWebAppName2)));
 }
 
 TEST_F(KioskBrowserSessionTest, DoNotOpenSecondBrowserInChromeAppKiosk) {
@@ -630,15 +627,15 @@
   GetPrefs()->SetBoolean(prefs::kNewWindowsInKioskAllowed, true);
   StartChromeAppKioskSession();
 
-  EXPECT_TRUE(DidSessionCloseNewWindow(
-      CreateBrowserForWebApp(kTestWebAppName2)->window()));
+  EXPECT_TRUE(
+      DidSessionCloseNewWindow(*CreateBrowserForWebApp(kTestWebAppName2)));
 }
 
 TEST_F(KioskBrowserSessionTest, NewOpenedRegularBrowserMetrics) {
   GetPrefs()->SetBoolean(prefs::kNewWindowsInKioskAllowed, true);
   StartWebKioskSession(kTestWebAppName1);
 
-  DidSessionCloseNewWindow(CreateBrowserForWebApp(kTestWebAppName1)->window());
+  DidSessionCloseNewWindow(*CreateBrowserForWebApp(kTestWebAppName1));
 
   histogram()->ExpectBucketCount(kKioskNewBrowserWindowHistogram,
                                  KioskBrowserWindowType::kOpenedRegularBrowser,
@@ -650,7 +647,7 @@
   GetPrefs()->SetBoolean(prefs::kNewWindowsInKioskAllowed, false);
   StartWebKioskSession(kTestWebAppName1);
 
-  DidSessionCloseNewWindow(CreateBrowserForWebApp(kTestWebAppName1)->window());
+  DidSessionCloseNewWindow(*CreateBrowserForWebApp(kTestWebAppName1));
 
   histogram()->ExpectBucketCount(kKioskNewBrowserWindowHistogram,
                                  KioskBrowserWindowType::kClosedRegularBrowser,
@@ -664,7 +661,7 @@
   StartWebKioskSession();
 
   auto second_browser = CreateBrowserForWebApp(kTestWebAppName1);
-  EXPECT_FALSE(DidSessionCloseNewWindow(second_browser->window()));
+  EXPECT_FALSE(DidSessionCloseNewWindow(*second_browser));
 
   CloseMainBrowser();
   EXPECT_FALSE(IsSessionShuttingDown());
@@ -679,7 +676,7 @@
   StartWebKioskSession();
 
   auto second_browser = CreateBrowserForWebApp(kTestWebAppName1);
-  EXPECT_FALSE(DidSessionCloseNewWindow(second_browser->window()));
+  EXPECT_FALSE(DidSessionCloseNewWindow(*second_browser));
 
   second_browser.reset();
   EXPECT_FALSE(IsSessionShuttingDown());
@@ -930,8 +927,8 @@
   SetUpKioskSession();
   UpdateTroubleshootingToolsPolicy(/*enable=*/true);
 
-  EXPECT_FALSE(DidSessionCloseNewWindow(
-      CreateDevToolsBrowserWithTestWindow()->window()));
+  EXPECT_FALSE(
+      DidSessionCloseNewWindow(*CreateDevToolsBrowserWithTestWindow()));
 
   histogram()->ExpectBucketCount(kKioskNewBrowserWindowHistogram,
                                  KioskBrowserWindowType::kOpenedDevToolsBrowser,
@@ -944,15 +941,13 @@
   SetUpKioskSession();
 
   // Kiosk troubleshooting tools are disabled by default.
-  EXPECT_TRUE(DidSessionCloseNewWindow(
-      CreateDevToolsBrowserWithTestWindow()->window()));
+  EXPECT_TRUE(DidSessionCloseNewWindow(*CreateDevToolsBrowserWithTestWindow()));
   histogram()->ExpectBucketCount(kKioskNewBrowserWindowHistogram,
                                  KioskBrowserWindowType::kClosedRegularBrowser,
                                  1);
   histogram()->ExpectTotalCount(kKioskNewBrowserWindowHistogram, 1);
 
-  EXPECT_TRUE(
-      DidSessionCloseNewWindow(CreateRegularBrowserWithTestWindow()->window()));
+  EXPECT_TRUE(DidSessionCloseNewWindow(*CreateRegularBrowserWithTestWindow()));
 
   histogram()->ExpectBucketCount(kKioskNewBrowserWindowHistogram,
                                  KioskBrowserWindowType::kClosedRegularBrowser,
@@ -968,8 +963,8 @@
   // Kiosk session should shoutdown only if policy is changed from enable to
   // disable.
   EXPECT_FALSE(IsSessionShuttingDown());
-  EXPECT_FALSE(DidSessionCloseNewWindow(
-      CreateDevToolsBrowserWithTestWindow()->window()));
+  EXPECT_FALSE(
+      DidSessionCloseNewWindow(*CreateDevToolsBrowserWithTestWindow()));
 
   histogram()->ExpectBucketCount(kKioskNewBrowserWindowHistogram,
                                  KioskBrowserWindowType::kOpenedDevToolsBrowser,
@@ -987,7 +982,7 @@
 
   std::unique_ptr<Browser> normal_browser =
       CreateRegularBrowserWithTestWindow();
-  EXPECT_FALSE(DidSessionCloseNewWindow(normal_browser->window()));
+  EXPECT_FALSE(DidSessionCloseNewWindow(*normal_browser));
 
   histogram()->ExpectBucketCount(
       kKioskNewBrowserWindowHistogram,
@@ -1000,8 +995,7 @@
   UpdateTroubleshootingToolsPolicy(/*enable=*/false);
   SetUpKioskSession();
 
-  EXPECT_TRUE(
-      DidSessionCloseNewWindow(CreateRegularBrowserWithTestWindow()->window()));
+  EXPECT_TRUE(DidSessionCloseNewWindow(*CreateRegularBrowserWithTestWindow()));
 
   histogram()->ExpectBucketCount(kKioskNewBrowserWindowHistogram,
                                  KioskBrowserWindowType::kClosedRegularBrowser,
@@ -1024,8 +1018,8 @@
   UpdateTroubleshootingToolsPolicy(/*enable=*/true);
 
   for (Browser::Type type : should_be_closed_browser_types) {
-    EXPECT_TRUE(DidSessionCloseNewWindow(
-        CreateBrowserWithTestWindowAndType(type)->window()));
+    EXPECT_TRUE(
+        DidSessionCloseNewWindow(*CreateBrowserWithTestWindowAndType(type)));
   }
 
   histogram()->ExpectBucketCount(kKioskNewBrowserWindowHistogram,
@@ -1322,7 +1316,7 @@
   system_web_app_manager()->SetSystemAppsForTesting(std::move(system_apps));
   StartAndWaitForAppsToSynchronize();
 
-  EXPECT_FALSE(DidSessionCloseNewWindow(CreateSwaTestWindow()->window()));
+  EXPECT_FALSE(DidSessionCloseNewWindow(*CreateSwaTestWindow()));
 
   histogram()->ExpectBucketCount(kKioskNewBrowserWindowHistogram,
                                  KioskBrowserWindowType::kOpenedSystemWebApp,
@@ -1458,7 +1452,7 @@
        AshBrowserShouldGetClosedIfLacrosIsEnabled) {
   StartWebKioskSession(kTestWebAppName1);
 
-  DidSessionCloseNewWindow(CreateBrowserForWebApp(kTestWebAppName1)->window());
+  DidSessionCloseNewWindow(*CreateBrowserForWebApp(kTestWebAppName1));
 
   histogram()->ExpectBucketCount(
       kKioskNewBrowserWindowHistogram,
diff --git a/chrome/browser/chromeos/app_mode/kiosk_browser_window_handler.cc b/chrome/browser/chromeos/app_mode/kiosk_browser_window_handler.cc
index 56ad270..a3fbe88 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_browser_window_handler.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_browser_window_handler.cc
@@ -6,7 +6,6 @@
 #include <memory>
 
 #include "base/check_deref.h"
-#include "base/feature_list.h"
 #include "base/functional/function_ref.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/task/single_thread_task_runner.h"
@@ -18,7 +17,6 @@
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_navigator.h"
 #include "chrome/browser/ui/browser_window.h"
-#include "chromeos/constants/chromeos_features.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_delegate.h"
 
@@ -56,14 +54,9 @@
 }
 
 void CloseBrowser(Browser* browser) {
-  // TODO(b/323129396) Remove feature flag once QA verifies it.
-  if (base::FeatureList::IsEnabled(chromeos::features::kKioskCloseAllTabs)) {
-    // Note we don't use `browser.window().Close()` because it can fail if a
-    // user drags the window.
-    browser->tab_strip_model()->CloseAllTabs();
-  } else {
-    browser->window()->Close();
-  }
+  // Note we don't use `browser.window().Close()` because it can fail if a
+  // user drags the window.
+  browser->tab_strip_model()->CloseAllTabs();
 }
 
 void CloseBrowserWindowsIf(base::FunctionRef<bool(const Browser&)> filter) {
diff --git a/chrome/browser/component_updater/first_party_sets_component_installer.cc b/chrome/browser/component_updater/first_party_sets_component_installer.cc
index ed00b8e..cff8f72 100644
--- a/chrome/browser/component_updater/first_party_sets_component_installer.cc
+++ b/chrome/browser/component_updater/first_party_sets_component_installer.cc
@@ -4,64 +4,19 @@
 
 #include "chrome/browser/component_updater/first_party_sets_component_installer.h"
 
-#include <optional>
-#include <utility>
+#include "components/component_updater/installer_policies/first_party_sets_component_installer_policy.h"
 
 #include "base/feature_list.h"
-#include "base/files/file.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/functional/bind.h"
-#include "base/functional/callback.h"
 #include "base/logging.h"
-#include "base/no_destructor.h"
-#include "base/path_service.h"
 #include "base/task/thread_pool.h"
-#include "base/version.h"
-#include "components/component_updater/component_installer.h"
-#include "components/component_updater/component_updater_paths.h"
 #include "content/public/browser/first_party_sets_handler.h"
 #include "content/public/common/content_features.h"
 #include "net/base/features.h"
-#include "net/cookies/cookie_util.h"
 
 using component_updater::ComponentUpdateService;
 
 namespace {
 
-using SetsReadyOnceCallback = component_updater::
-    FirstPartySetsComponentInstallerPolicy::SetsReadyOnceCallback;
-
-constexpr base::FilePath::CharType kFirstPartySetsSetsFileName[] =
-    FILE_PATH_LITERAL("sets.json");
-
-// The SHA256 of the SubjectPublicKeyInfo used to sign the extension.
-// The extension id is: gonpemdgkjcecdgbnaabipppbmgfggbe
-constexpr uint8_t kFirstPartySetsPublicKeySHA256[32] = {
-    0x6e, 0xdf, 0x4c, 0x36, 0xa9, 0x24, 0x23, 0x61, 0xd0, 0x01, 0x8f,
-    0xff, 0x1c, 0x65, 0x66, 0x14, 0xa8, 0x46, 0x37, 0xe6, 0xeb, 0x80,
-    0x8b, 0x8f, 0xb0, 0xb6, 0x18, 0xa7, 0xcd, 0x3d, 0xbb, 0xfb};
-
-constexpr char kFirstPartySetsManifestName[] = "Related Website Sets";
-
-constexpr base::FilePath::CharType kFirstPartySetsRelativeInstallDir[] =
-    FILE_PATH_LITERAL("FirstPartySetsPreloaded");
-
-base::File OpenFile(const base::FilePath& pb_path) {
-  return base::File(pb_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
-}
-
-std::optional<std::pair<base::FilePath, base::Version>>&
-GetConfigPathInstance() {
-  // Contains nullopt until registration is complete. Afterward, contains the
-  // FilePath and version for the component file, or empty FilePath and version
-  // if no component was installed at startup.
-  static base::NoDestructor<
-      std::optional<std::pair<base::FilePath, base::Version>>>
-      instance;
-  return *instance;
-}
-
 base::TaskPriority GetTaskPriority() {
   // We may use USER_BLOCKING here since First-Party Set initialization can
   // block network requests at startup.
@@ -72,136 +27,15 @@
              : base::TaskPriority::BEST_EFFORT;
 }
 
-// Invokes `on_sets_ready`, if:
-// * First-Party Sets is enabled; and
-// * `on_sets_ready` is not null.
-//
-// If the component has been installed and can be read, we pass the component
-// file; otherwise, we pass an invalid file.
-void SetFirstPartySetsConfig(SetsReadyOnceCallback on_sets_ready) {
-  if (!content::FirstPartySetsHandler::GetInstance()->IsEnabled() ||
-      on_sets_ready.is_null()) {
-    return;
-  }
-
-  const std::optional<std::pair<base::FilePath, base::Version>>& instance_path =
-      GetConfigPathInstance();
-  if (!instance_path.has_value()) {
-    // Registration not is complete yet. The policy's `on_sets_ready_` callback
-    // will still be invoked once registration is done, so we don't bother to
-    // save or invoke `on_sets_ready`.
-    return;
-  }
-
-  if (instance_path->first.empty()) {
-    // Registration is complete, but no component version exists on disk.
-    CHECK(!instance_path->second.IsValid());
-    std::move(on_sets_ready).Run(base::Version(), base::File());
-    return;
-  }
-
-  base::ThreadPool::PostTaskAndReplyWithResult(
-      FROM_HERE, {base::MayBlock(), GetTaskPriority()},
-      base::BindOnce(&OpenFile, instance_path->first),
-      base::BindOnce(std::move(on_sets_ready), instance_path->second));
-}
-
 }  // namespace
 
 namespace component_updater {
 
-void FirstPartySetsComponentInstallerPolicy::OnRegistrationComplete() {
-  if (!GetConfigPathInstance().has_value()) {
-    GetConfigPathInstance() = std::make_pair(base::FilePath(), base::Version());
-  }
-  SetFirstPartySetsConfig(std::move(on_sets_ready_));
-}
-
-FirstPartySetsComponentInstallerPolicy::FirstPartySetsComponentInstallerPolicy(
-    SetsReadyOnceCallback on_sets_ready)
-    : on_sets_ready_(std::move(on_sets_ready)) {}
-
-FirstPartySetsComponentInstallerPolicy::
-    ~FirstPartySetsComponentInstallerPolicy() = default;
-
-bool FirstPartySetsComponentInstallerPolicy::
-    SupportsGroupPolicyEnabledComponentUpdates() const {
-  return true;
-}
-
-bool FirstPartySetsComponentInstallerPolicy::RequiresNetworkEncryption() const {
-  // Update checks and pings associated with this component do not require
-  // confidentiality, since the component is identical for all users.
-  return false;
-}
-
-update_client::CrxInstaller::Result
-FirstPartySetsComponentInstallerPolicy::OnCustomInstall(
-    const base::Value::Dict& manifest,
-    const base::FilePath& install_dir) {
-  return update_client::CrxInstaller::Result(0);  // Nothing custom here.
-}
-
-void FirstPartySetsComponentInstallerPolicy::OnCustomUninstall() {}
-
-base::FilePath FirstPartySetsComponentInstallerPolicy::GetInstalledPath(
-    const base::FilePath& base) {
-  return base.Append(kFirstPartySetsSetsFileName);
-}
-
-void FirstPartySetsComponentInstallerPolicy::ComponentReady(
-    const base::Version& version,
-    const base::FilePath& install_dir,
-    base::Value::Dict manifest) {
-  if (install_dir.empty() || GetConfigPathInstance().has_value()) {
+void RegisterFirstPartySetsComponent(ComponentUpdateService* cus) {
+  if (!content::FirstPartySetsHandler::GetInstance()->IsEnabled()) {
     return;
   }
 
-  VLOG(1) << "Related Website Sets Component ready, version "
-          << version.GetString() << " in " << install_dir.value();
-
-  GetConfigPathInstance() =
-      std::make_pair(GetInstalledPath(install_dir), version);
-
-  SetFirstPartySetsConfig(std::move(on_sets_ready_));
-}
-
-// Called during startup and installation before ComponentReady().
-bool FirstPartySetsComponentInstallerPolicy::VerifyInstallation(
-    const base::Value::Dict& manifest,
-    const base::FilePath& install_dir) const {
-  // No need to actually validate the sets here, since we'll do the validation
-  // in the Network Service.
-  return base::PathExists(GetInstalledPath(install_dir));
-}
-
-base::FilePath FirstPartySetsComponentInstallerPolicy::GetRelativeInstallDir()
-    const {
-  return base::FilePath(kFirstPartySetsRelativeInstallDir);
-}
-
-void FirstPartySetsComponentInstallerPolicy::GetHash(
-    std::vector<uint8_t>* hash) const {
-  hash->assign(kFirstPartySetsPublicKeySHA256,
-               kFirstPartySetsPublicKeySHA256 +
-                   std::size(kFirstPartySetsPublicKeySHA256));
-}
-
-std::string FirstPartySetsComponentInstallerPolicy::GetName() const {
-  return kFirstPartySetsManifestName;
-}
-
-update_client::InstallerAttributes
-FirstPartySetsComponentInstallerPolicy::GetInstallerAttributes() const {
-  return {};
-}
-
-// static
-void FirstPartySetsComponentInstallerPolicy::ResetForTesting() {
-  GetConfigPathInstance().reset();
-}
-
-void RegisterFirstPartySetsComponent(ComponentUpdateService* cus) {
   VLOG(1) << "Registering Related Website Sets component.";
 
   auto policy = std::make_unique<FirstPartySetsComponentInstallerPolicy>(
@@ -210,7 +44,8 @@
         VLOG(1) << "Received Related Website Sets";
         content::FirstPartySetsHandler::GetInstance()->SetPublicFirstPartySets(
             version, std::move(sets_file));
-      }));
+      }),
+      GetTaskPriority());
 
   FirstPartySetsComponentInstallerPolicy* raw_policy = policy.get();
   // Dereferencing `raw_policy` this way is safe because the closure is invoked
@@ -226,15 +61,4 @@
                           raw_policy));
 }
 
-// static
-void FirstPartySetsComponentInstallerPolicy::WriteComponentForTesting(
-    base::Version version,
-    const base::FilePath& install_dir,
-    base::StringPiece contents) {
-  CHECK(base::WriteFile(GetInstalledPath(install_dir), contents));
-
-  GetConfigPathInstance() =
-      std::make_pair(GetInstalledPath(install_dir), std::move(version));
-}
-
 }  // namespace component_updater
diff --git a/chrome/browser/component_updater/first_party_sets_component_installer.h b/chrome/browser/component_updater/first_party_sets_component_installer.h
index 1db97cc..156711e6 100644
--- a/chrome/browser/component_updater/first_party_sets_component_installer.h
+++ b/chrome/browser/component_updater/first_party_sets_component_installer.h
@@ -5,98 +5,10 @@
 #ifndef CHROME_BROWSER_COMPONENT_UPDATER_FIRST_PARTY_SETS_COMPONENT_INSTALLER_H_
 #define CHROME_BROWSER_COMPONENT_UPDATER_FIRST_PARTY_SETS_COMPONENT_INSTALLER_H_
 
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/files/file.h"
-#include "base/functional/callback.h"
-#include "base/gtest_prod_util.h"
-#include "base/strings/string_piece.h"
-#include "base/values.h"
-#include "base/version.h"
-#include "components/component_updater/component_installer.h"
-
-namespace base {
-class FilePath;
-}  // namespace base
-
 namespace component_updater {
 
 class ComponentUpdateService;
 
-class FirstPartySetsComponentInstallerPolicy : public ComponentInstallerPolicy {
- public:
-  using SetsReadyOnceCallback =
-      base::OnceCallback<void(base::Version, base::File)>;
-
-  // |on_sets_ready| will be called on the UI thread when the sets are ready. It
-  // is exposed here for testing.
-  explicit FirstPartySetsComponentInstallerPolicy(
-      SetsReadyOnceCallback on_sets_ready);
-  ~FirstPartySetsComponentInstallerPolicy() override;
-
-  FirstPartySetsComponentInstallerPolicy(
-      const FirstPartySetsComponentInstallerPolicy&) = delete;
-  FirstPartySetsComponentInstallerPolicy operator=(
-      const FirstPartySetsComponentInstallerPolicy&) = delete;
-
-  void OnRegistrationComplete();
-
-  // Resets static state. Should only be used to clear state during testing.
-  static void ResetForTesting();
-
-  // Seeds a component at `install_dir` with the given `contents`. Only to be
-  // used in testing.
-  static void WriteComponentForTesting(base::Version version,
-                                       const base::FilePath& install_dir,
-                                       base::StringPiece contents);
-
-  static base::FilePath GetInstalledPathForTesting(const base::FilePath& base) {
-    return GetInstalledPath(base);
-  }
-
-  void ComponentReadyForTesting(const base::Version& version,
-                                const base::FilePath& install_dir,
-                                base::Value::Dict manifest) {
-    ComponentReady(version, install_dir, std::move(manifest));
-  }
-
-  update_client::InstallerAttributes GetInstallerAttributesForTesting() const {
-    return GetInstallerAttributes();
-  }
-
- private:
-  // The following methods override ComponentInstallerPolicy.
-  bool SupportsGroupPolicyEnabledComponentUpdates() const override;
-  bool RequiresNetworkEncryption() const override;
-  update_client::CrxInstaller::Result OnCustomInstall(
-      const base::Value::Dict& manifest,
-      const base::FilePath& install_dir) override;
-  void OnCustomUninstall() override;
-  bool VerifyInstallation(const base::Value::Dict& manifest,
-                          const base::FilePath& install_dir) const override;
-  // After the first call, ComponentReady will be no-op for new versions
-  // delivered from Component Updater, i.e. new components will be installed
-  // (kept on-disk) but not propagated to the NetworkService until next
-  // browser startup.
-  void ComponentReady(const base::Version& version,
-                      const base::FilePath& install_dir,
-                      base::Value::Dict manifest) override;
-  base::FilePath GetRelativeInstallDir() const override;
-  void GetHash(std::vector<uint8_t>* hash) const override;
-  std::string GetName() const override;
-  update_client::InstallerAttributes GetInstallerAttributes() const override;
-
-  static base::FilePath GetInstalledPath(const base::FilePath& base);
-
-  // We use a OnceCallback to ensure we only pass along the sets file once
-  // during Chrome's lifetime (modulo reconfiguring the network service).
-  SetsReadyOnceCallback on_sets_ready_;
-};
-
 // Call once during startup to make the component update service aware of
 // the First-Party Sets component.
 void RegisterFirstPartySetsComponent(ComponentUpdateService* cus);
diff --git a/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc b/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc
index 3adabf1..e02daa3 100644
--- a/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc
+++ b/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc
@@ -743,6 +743,16 @@
 }
 #endif
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest,
+                       GetDeviceStatesLacros) {
+  if (!SetUpAsh()) {
+    GTEST_SKIP() << "Unsupported ash version.";
+  }
+  EXPECT_TRUE(RunNetworkingSubtest("getDeviceStatesLacros")) << message_;
+}
+#endif
+
 IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest, RequestNetworkScan) {
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
   if (!SetUpAsh()) {
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index e676d6b..3e14b43c 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -314,6 +314,8 @@
     &password_manager::features::kRecoverFromNeverSaveAndroid,
     &password_manager::features::kSharedPasswordNotificationUI,
     &password_manager::features::
+        kUnifiedPasswordManagerLocalPasswordsAndroidNoMigration,
+    &password_manager::features::
         kUnifiedPasswordManagerLocalPasswordsMigrationWarning,
     &permissions::features::kPermissionsPromptSurvey,
     &privacy_sandbox::kPrivacySandboxAdsNoticeCCT,
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 6ec06b6..3ab31a2b 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
@@ -481,6 +481,8 @@
     public static final String TRANSLATE_MESSAGE_UI = "TranslateMessageUI";
     public static final String TRANSLATE_TFLITE = "TFLiteLanguageDetectionEnabled";
     public static final String SHARED_PASSWORD_NOTIFICATION_UI = "SharedPasswordNotificationUI";
+    public static final String UNIFIED_PASSWORD_MANAGER_LOCAL_PASSWORDS_ANDROID_NO_MIGRATION =
+            "UnifiedPasswordManagerLocalPasswordsAndroidNoMigration";
     public static final String UNIFIED_PASSWORD_MANAGER_LOCAL_PWD_MIGRATION_WARNING =
             "UnifiedPasswordManagerLocalPasswordsMigrationWarning";
     public static final String USE_CHIME_ANDROID_SDK = "UseChimeAndroidSdk";
diff --git a/chrome/browser/lacros/app_mode/kiosk_accelerator_browsertest.cc b/chrome/browser/lacros/app_mode/kiosk_accelerator_browsertest.cc
index 5bbe867..d7fce1b31 100644
--- a/chrome/browser/lacros/app_mode/kiosk_accelerator_browsertest.cc
+++ b/chrome/browser/lacros/app_mode/kiosk_accelerator_browsertest.cc
@@ -8,11 +8,12 @@
 #include "base/run_loop.h"
 #include "base/test/test_future.h"
 #include "chrome/browser/app_mode/test/accelerator_helpers.h"
-#include "chrome/browser/lacros/browser_service_lacros.h"
+#include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/test/test_browser_closed_waiter.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chromeos/crosapi/mojom/crosapi.mojom-shared.h"
@@ -28,38 +29,32 @@
 
 namespace {
 
-const char kNavigationUrl[] = "https://www.example.com/";
+const char kWebAppUrl[] = "https://www.example.com/";
 
 [[nodiscard]] bool WaitUntilBrowserClosed(Browser* browser) {
   TestBrowserClosedWaiter waiter(browser);
   return waiter.WaitUntilClosed();
 }
 
+void CreateKioskWindow() {
+  web_app::CreateWebApplicationWindow(ProfileManager::GetPrimaryUserProfile(),
+                                      kWebAppUrl,
+                                      WindowOpenDisposition::NEW_POPUP,
+                                      /*restore_id=*/0);
+}
+
+void SetBrowserInitParamsForWebKiosk() {
+  BrowserInitParamsPtr init_params =
+      chromeos::BrowserInitParams::GetForTests()->Clone();
+  init_params->session_type = SessionType::kWebKioskSession;
+  init_params->device_settings = crosapi::mojom::DeviceSettings::New();
+  chromeos::BrowserInitParams::SetInitParamsForTests(std::move(init_params));
+}
+
 }  // namespace
 
 // Tests browser view accelerators work normally in non kiosk session.
-class NonKioskAcceleratorTest : public InProcessBrowserTest {
- protected:
-  NonKioskAcceleratorTest() = default;
-  ~NonKioskAcceleratorTest() override = default;
-
-  void SetUpOnMainThread() override {
-    browser_service_ = std::make_unique<BrowserServiceLacros>();
-    InProcessBrowserTest::SetUpOnMainThread();
-  }
-
-  void TearDownOnMainThread() override {
-    InProcessBrowserTest::TearDownOnMainThread();
-    browser_service_.reset();
-  }
-
-  BrowserServiceLacros* browser_service() const {
-    return browser_service_.get();
-  }
-
- private:
-  std::unique_ptr<BrowserServiceLacros> browser_service_;
-};
+using NonKioskAcceleratorTest = InProcessBrowserTest;
 
 // Tests browser view accelerators do not work in kiosk session.
 class WebKioskAcceleratorTest : public InProcessBrowserTest {
@@ -67,10 +62,12 @@
   WebKioskAcceleratorTest() = default;
   ~WebKioskAcceleratorTest() override = default;
 
-  void SetUp() override { InProcessBrowserTest::SetUp(); }
+  void SetUp() override {
+    SetBrowserInitParamsForWebKiosk();
+    InProcessBrowserTest::SetUp();
+  }
 
   void SetUpOnMainThread() override {
-    browser_service_ = std::make_unique<BrowserServiceLacros>();
     InProcessBrowserTest::SetUpOnMainThread();
     SetKioskSessionType();
     CreateKioskWindow();
@@ -85,7 +82,6 @@
 
   void TearDownOnMainThread() override {
     InProcessBrowserTest::TearDownOnMainThread();
-    browser_service_.reset();
   }
 
  private:
@@ -96,19 +92,6 @@
     chromeos::BrowserInitParams::SetInitParamsForTests(std::move(init_params));
   }
 
-  void CreateKioskWindow() {
-    base::test::TestFuture<CreationResult> future;
-    browser_service()->NewFullscreenWindow(
-        GURL(kNavigationUrl),
-        display::Screen::GetScreen()->GetDisplayForNewWindows().id(),
-        future.GetCallback());
-    ASSERT_EQ(future.Take(), CreationResult::kSuccess);
-  }
-
-  BrowserServiceLacros* browser_service() const {
-    return browser_service_.get();
-  }
-
   void WaitForNonKioskWindowToClose() {
     // The test framework automatically spawns a separate, non-kiosk browser
     // window.
@@ -129,8 +112,6 @@
 
     ASSERT_EQ(BrowserList::GetInstance()->size(), 1u);
   }
-
-  std::unique_ptr<BrowserServiceLacros> browser_service_;
 };
 
 IN_PROC_BROWSER_TEST_F(NonKioskAcceleratorTest, CloseTabWorks) {
diff --git a/chrome/browser/lacros/app_mode/kiosk_session_service_browsertest.cc b/chrome/browser/lacros/app_mode/kiosk_session_service_browsertest.cc
index 6a0b8d96..5a7ecd1a 100644
--- a/chrome/browser/lacros/app_mode/kiosk_session_service_browsertest.cc
+++ b/chrome/browser/lacros/app_mode/kiosk_session_service_browsertest.cc
@@ -2,13 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <memory>
+
 #include "chrome/browser/lacros/app_mode/kiosk_session_service_lacros.h"
 
-#include "base/test/bind.h"
+#include "base/auto_reset.h"
+#include "base/functional/callback_forward.h"
+#include "base/functional/callback_helpers.h"
+#include "base/test/test_future.h"
 #include "chrome/browser/extensions/extension_special_storage_policy.h"
-#include "chrome/browser/lacros/browser_service_lacros.h"
+#include "chrome/browser/lacros/app_mode/web_kiosk_installer_lacros.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chromeos/crosapi/mojom/kiosk_session_service.mojom.h"
 #include "chromeos/lacros/lacros_service.h"
@@ -22,116 +28,152 @@
 using crosapi::mojom::KioskSessionService;
 using crosapi::mojom::SessionType;
 
-const char kNavigationUrl[] = "https://www.google.com/";
+namespace {
 
-class FakeKioskSessionServiceLacros : public KioskSessionServiceLacros {
+const char kWebAppUrl[] = "https://www.google.com/";
+
+// Runs the provided callback when the web kiosk is initialized.
+class KioskWebSessionInitializedWaiter
+    : public KioskSessionServiceLacros::Observer {
  public:
-  FakeKioskSessionServiceLacros() = default;
-  ~FakeKioskSessionServiceLacros() override = default;
-
-  // KioskSessionServiceLacros:
-  void AttemptUserExit() override {
-    if (after_attempt_user_exit_) {
-      std::move(after_attempt_user_exit_).Run();
-    }
+  explicit KioskWebSessionInitializedWaiter(
+      base::OnceClosure on_kiosk_web_session_initialized)
+      : on_kiosk_web_session_initialized_(
+            std::move(on_kiosk_web_session_initialized)) {
+    kiosk_session_observation_.Observe(KioskSessionServiceLacros::Get());
   }
 
-  void set_after_attempt_user_exit(base::OnceClosure closure) {
-    after_attempt_user_exit_ = std::move(closure);
+  ~KioskWebSessionInitializedWaiter() override = default;
+
+  // KioskSessionServiceLacros::Observer:
+  void KioskWebSessionInitialized() override {
+    std::move(on_kiosk_web_session_initialized_).Run();
   }
 
  private:
-  base::OnceClosure after_attempt_user_exit_;
+  base::OnceCallback<void()> on_kiosk_web_session_initialized_;
+  base::ScopedObservation<KioskSessionServiceLacros,
+                          KioskSessionServiceLacros::Observer>
+      kiosk_session_observation_{this};
 };
 
-class KioskSessionServiceBrowserTest : public InProcessBrowserTest {
+Profile& GetProfile() {
+  return CHECK_DEREF(ProfileManager::GetPrimaryUserProfile());
+}
+
+void SetBrowserInitParamsForWebKiosk() {
+  BrowserInitParamsPtr init_params =
+      chromeos::BrowserInitParams::GetForTests()->Clone();
+  init_params->session_type = SessionType::kWebKioskSession;
+  init_params->device_settings = crosapi::mojom::DeviceSettings::New();
+  chromeos::BrowserInitParams::SetInitParamsForTests(std::move(init_params));
+}
+
+void CreateKioskAppWindowAndWaitInitialized() {
+  base::test::TestFuture<void> kiosk_initialized;
+  KioskWebSessionInitializedWaiter waiter(kiosk_initialized.GetCallback());
+  web_app::CreateWebApplicationWindow(&GetProfile(), kWebAppUrl,
+                                      WindowOpenDisposition::NEW_POPUP,
+                                      /*restore_id=*/0);
+  EXPECT_TRUE(kiosk_initialized.Wait());
+}
+
+}  // namespace
+
+class WebKioskSessionServiceBrowserTest : public InProcessBrowserTest {
  protected:
-  KioskSessionServiceBrowserTest() = default;
-  ~KioskSessionServiceBrowserTest() override = default;
+  WebKioskSessionServiceBrowserTest() = default;
+  ~WebKioskSessionServiceBrowserTest() override = default;
+
+  void SetUp() override {
+    // `SetBrowserInitParamsForWebKiosk` must be called before
+    // `InProcessBrowserTest::SetUp` to configure `KioskSessionServiceLacros`
+    // correctly.
+    SetBrowserInitParamsForWebKiosk();
+    InProcessBrowserTest::SetUp();
+  }
 
   void SetUpOnMainThread() override {
-    // Initialize lacros browser service.
-    browser_service_ = std::make_unique<BrowserServiceLacros>();
-
-    // Set up the main thread.
     InProcessBrowserTest::SetUpOnMainThread();
 
-    // Initialize a fake kiosk session service for testing.
-    kiosk_session_service_lacros_ =
-        std::make_unique<FakeKioskSessionServiceLacros>();
+    kiosk_session_service_lacros_ = KioskSessionServiceLacros::Get();
+    attempt_user_exit_reset_ =
+        kiosk_session_service_lacros_->SetAttemptUserExitCallbackForTesting(
+            base::DoNothing());
+
+    installer_ = std::make_unique<WebKioskInstallerLacros>(GetProfile());
+    InstallWebKiosk(kWebAppUrl);
   }
 
   void TearDownOnMainThread() override {
-    kiosk_session_service_lacros_.reset();
+    attempt_user_exit_reset_.reset();
     InProcessBrowserTest::TearDownOnMainThread();
-    browser_service_.reset();
   }
 
-  bool IsServiceAvailable() const {
-    auto* lacros_chrome_service = chromeos::LacrosService::Get();
-    return lacros_chrome_service &&
-           lacros_chrome_service
-               ->IsAvailable<crosapi::mojom::KioskSessionService>();
+  std::optional<webapps::AppId> InstallWebKiosk(const std::string& url) {
+    base::test::TestFuture<crosapi::mojom::WebKioskInstallState,
+                           const std::optional<webapps::AppId>&>
+        install_state;
+    installer_->GetWebKioskInstallState(GURL(url), install_state.GetCallback());
+    if (install_state.Get<0>() ==
+        crosapi::mojom::WebKioskInstallState::kInstalled) {
+      return install_state.Get<1>();
+    }
+
+    base::test::TestFuture<const std::optional<webapps::AppId>&> install_result;
+    installer_->InstallWebKiosk(GURL(url), install_result.GetCallback());
+    return install_result.Get();
   }
 
-  void SetSessionType(SessionType type) {
-    BrowserInitParamsPtr init_params =
-        chromeos::BrowserInitParams::GetForTests()->Clone();
-    init_params->session_type = type;
-    chromeos::BrowserInitParams::SetInitParamsForTests(std::move(init_params));
-  }
-
-  void CreateKioskMainWindow() {
-    bool use_callback = false;
-    browser_service()->NewFullscreenWindow(
-        GURL(kNavigationUrl),
-        display::Screen::GetScreen()->GetDisplayForNewWindows().id(),
-        base::BindLambdaForTesting([&](CreationResult result) {
-          use_callback = true;
-          EXPECT_EQ(result, CreationResult::kSuccess);
-        }));
-    EXPECT_TRUE(use_callback);
-  }
-
-  BrowserServiceLacros* browser_service() const {
-    return browser_service_.get();
-  }
-
-  FakeKioskSessionServiceLacros* kiosk_session_service_lacros() const {
-    return kiosk_session_service_lacros_.get();
+  KioskSessionServiceLacros* kiosk_session_service_lacros() const {
+    return kiosk_session_service_lacros_;
   }
 
  private:
-  std::unique_ptr<BrowserServiceLacros> browser_service_;
-  std::unique_ptr<FakeKioskSessionServiceLacros> kiosk_session_service_lacros_;
+  std::unique_ptr<WebKioskInstallerLacros> installer_;
+  raw_ptr<KioskSessionServiceLacros> kiosk_session_service_lacros_;
+  std::unique_ptr<base::AutoReset<base::OnceClosure>> attempt_user_exit_reset_;
 };
 
-IN_PROC_BROWSER_TEST_F(KioskSessionServiceBrowserTest, AttemptUserExit) {
-  SetSessionType(SessionType::kWebKioskSession);
-  CreateKioskMainWindow();
+IN_PROC_BROWSER_TEST_F(WebKioskSessionServiceBrowserTest,
+                       BrowserKioskSessionIsCreated) {
+  EXPECT_EQ(kiosk_session_service_lacros()->GetKioskBrowserSessionForTesting(),
+            nullptr);
 
-  // Verify the install URL stored in the service.
-  EXPECT_EQ(kiosk_session_service_lacros()->GetInstallURL(),
-            GURL(kNavigationUrl));
+  CreateKioskAppWindowAndWaitInitialized();
 
-  // Close all browser windows, which should trigger `AttemptUserExit` API call.
-  base::RunLoop run_loop;
-  kiosk_session_service_lacros()->set_after_attempt_user_exit(
-      run_loop.QuitClosure());
+  EXPECT_NE(kiosk_session_service_lacros()->GetKioskBrowserSessionForTesting(),
+            nullptr);
+}
+
+IN_PROC_BROWSER_TEST_F(WebKioskSessionServiceBrowserTest, VerifyInstallUrl) {
+  CreateKioskAppWindowAndWaitInitialized();
+
+  EXPECT_EQ(kiosk_session_service_lacros()->GetInstallURL(), GURL(kWebAppUrl));
+}
+
+IN_PROC_BROWSER_TEST_F(WebKioskSessionServiceBrowserTest,
+                       ClosingAllWindowsTriggersAttemptUserExitCall) {
+  // Closing all browser windows should trigger `AttemptUserExit`.
+  base::test::TestFuture<void> did_attempt_user_exit;
+  auto auto_reset =
+      kiosk_session_service_lacros()->SetAttemptUserExitCallbackForTesting(
+          did_attempt_user_exit.GetCallback());
+
+  CreateKioskAppWindowAndWaitInitialized();
   CloseAllBrowsers();
-  run_loop.Run();
 
+  EXPECT_TRUE(did_attempt_user_exit.Wait());
   // Verify that all windows have been closed.
   EXPECT_TRUE(BrowserList::GetInstance()->empty());
 }
 
-IN_PROC_BROWSER_TEST_F(KioskSessionServiceBrowserTest,
+IN_PROC_BROWSER_TEST_F(WebKioskSessionServiceBrowserTest,
                        KioskOriginShouldGetUnlimitedStorage) {
-  SetSessionType(SessionType::kWebKioskSession);
-  CreateKioskMainWindow();
+  CreateKioskAppWindowAndWaitInitialized();
 
   // Verify the origin of the install URL has been granted unlimited storage
-  EXPECT_TRUE(ProfileManager::GetPrimaryUserProfile()
-                  ->GetExtensionSpecialStoragePolicy()
-                  ->IsStorageUnlimited(GURL(kNavigationUrl)));
+  EXPECT_TRUE(
+      GetProfile().GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
+          GURL(kWebAppUrl)));
 }
diff --git a/chrome/browser/lacros/app_mode/kiosk_session_service_lacros.cc b/chrome/browser/lacros/app_mode/kiosk_session_service_lacros.cc
index 02ea41e..2eb1c79 100644
--- a/chrome/browser/lacros/app_mode/kiosk_session_service_lacros.cc
+++ b/chrome/browser/lacros/app_mode/kiosk_session_service_lacros.cc
@@ -4,13 +4,20 @@
 
 #include "chrome/browser/lacros/app_mode/kiosk_session_service_lacros.h"
 
+#include <memory>
+
+#include "base/auto_reset.h"
 #include "base/check.h"
+#include "base/check_deref.h"
 #include "base/functional/bind.h"
+#include "base/functional/callback_forward.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_browser_session.h"
 #include "chrome/browser/extensions/extension_special_storage_policy.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
 #include "chromeos/lacros/lacros_service.h"
+#include "chromeos/startup/browser_params_proxy.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "url/origin.h"
 
@@ -18,8 +25,48 @@
 
 static KioskSessionServiceLacros* g_kiosk_session_service = nullptr;
 
+bool IsWebKioskSession() {
+  return chromeos::BrowserParamsProxy::Get()->SessionType() ==
+         crosapi::mojom::SessionType::kWebKioskSession;
+}
+
+void AttemptUserExit() {
+  chromeos::LacrosService* service = chromeos::LacrosService::Get();
+  CHECK(service);
+
+  if (!service->IsAvailable<crosapi::mojom::KioskSessionService>()) {
+    LOG(ERROR) << "Kiosk session service is not available.";
+    return;
+  }
+
+  service->GetRemote<crosapi::mojom::KioskSessionService>()->AttemptUserExit();
+}
+
 }  // namespace
 
+// Runs callback when a new browser is opened.
+class NewBrowserObserver : public BrowserListObserver {
+ public:
+  explicit NewBrowserObserver(
+      base::RepeatingCallback<void(Browser* browser)> on_browser_added)
+      : on_browser_added_(std::move(on_browser_added)) {
+    browser_list_observation_.Observe(BrowserList::GetInstance());
+  }
+  NewBrowserObserver(const NewBrowserObserver&) = delete;
+  NewBrowserObserver& operator=(const NewBrowserObserver&) = delete;
+  ~NewBrowserObserver() override = default;
+
+  // BrowserListObserver:
+  void OnBrowserAdded(Browser* browser) override {
+    on_browser_added_.Run(browser);
+  }
+
+ private:
+  base::ScopedObservation<BrowserList, NewBrowserObserver>
+      browser_list_observation_{this};
+  base::RepeatingCallback<void(Browser* browser)> on_browser_added_;
+};
+
 // static
 KioskSessionServiceLacros* KioskSessionServiceLacros::Get() {
   CHECK(g_kiosk_session_service);
@@ -38,8 +85,22 @@
   chromeos::KioskBrowserSession::RegisterProfilePrefs(registry);
 }
 
-KioskSessionServiceLacros::KioskSessionServiceLacros() {
+KioskSessionServiceLacros::KioskSessionServiceLacros()
+    : attempt_user_exit_(base::BindOnce(&AttemptUserExit)) {
+  // TODO(b/321669108): add CHECK(!g_kiosk_session_service)
+  DUMP_WILL_BE_CHECK(!g_kiosk_session_service);
   g_kiosk_session_service = this;
+
+  if (IsWebKioskSession()) {
+    new_browser_observer_ =
+        std::make_unique<NewBrowserObserver>(base::BindRepeating(
+            [](KioskSessionServiceLacros* kiosk_service, Browser* browser) {
+              kiosk_service->KioskSessionServiceLacros::InitWebKioskSession(
+                  CHECK_DEREF(browser));
+              kiosk_service->new_browser_observer_.reset();
+            },
+            weak_factory_.GetWeakPtr().get()));
+  }
 }
 
 KioskSessionServiceLacros::~KioskSessionServiceLacros() {
@@ -52,37 +113,49 @@
   LOG_IF(FATAL, kiosk_browser_session_)
       << "Kiosk browser session is already initialized.";
   kiosk_browser_session_ = std::make_unique<chromeos::KioskBrowserSession>(
-      profile,
-      base::BindOnce(&KioskSessionServiceLacros::AttemptUserExit,
-                     weak_factory_.GetWeakPtr()),
-      g_browser_process->local_state());
+      profile, std::move(attempt_user_exit_), g_browser_process->local_state());
   kiosk_browser_session_->InitForChromeAppKiosk(app_id);
 }
 
-void KioskSessionServiceLacros::InitWebKioskSession(Browser* browser,
-                                                    const GURL& install_url) {
+void KioskSessionServiceLacros::InitWebKioskSession(Browser& browser) {
   LOG_IF(FATAL, kiosk_browser_session_)
       << "Kiosk session is already initialized.";
+
   kiosk_browser_session_ = std::make_unique<chromeos::KioskBrowserSession>(
-      browser->profile(),
-      base::BindOnce(&KioskSessionServiceLacros::AttemptUserExit,
-                     weak_factory_.GetWeakPtr()),
+      browser.profile(), std::move(attempt_user_exit_),
       g_browser_process->local_state());
-  kiosk_browser_session_->InitForWebKiosk(browser->app_name());
-  browser->profile()
+  kiosk_browser_session_->InitForWebKiosk(browser.app_name());
+  browser.profile()
       ->GetExtensionSpecialStoragePolicy()
-      ->AddOriginWithUnlimitedStorage(url::Origin::Create(install_url));
+      ->AddOriginWithUnlimitedStorage(url::Origin::Create(install_url_));
+
+  for (auto& observer : observers_) {
+    observer.KioskWebSessionInitialized();
+  }
+}
+
+void KioskSessionServiceLacros::SetInstallUrl(const GURL install_url) {
+  // `SetInstallUrl` should be called once, but if it is called second time,
+  // the url should be the same.
+  CHECK(install_url_.is_empty() || install_url_ == install_url)
+      << "install_url_=" << install_url_ << ", install_url=" << install_url;
   install_url_ = install_url;
 }
 
-void KioskSessionServiceLacros::AttemptUserExit() {
-  chromeos::LacrosService* service = chromeos::LacrosService::Get();
-  CHECK(service);
+std::unique_ptr<base::AutoReset<base::OnceClosure>>
+KioskSessionServiceLacros::SetAttemptUserExitCallbackForTesting(
+    base::OnceClosure attempt_user_exit) {
+  return std::make_unique<base::AutoReset<base::OnceClosure>>(
+      base::AutoReset<base::OnceClosure>(&attempt_user_exit_,
+                                         std::move(attempt_user_exit)));
+}
 
-  if (!service->IsAvailable<crosapi::mojom::KioskSessionService>()) {
-    LOG(ERROR) << "Kiosk session service is not available.";
-    return;
-  }
+void KioskSessionServiceLacros::AddObserver(
+    KioskSessionServiceLacros::Observer* observer) {
+  observers_.AddObserver(observer);
+}
 
-  service->GetRemote<crosapi::mojom::KioskSessionService>()->AttemptUserExit();
+void KioskSessionServiceLacros::RemoveObserver(
+    KioskSessionServiceLacros::Observer* observer) {
+  observers_.RemoveObserver(observer);
 }
diff --git a/chrome/browser/lacros/app_mode/kiosk_session_service_lacros.h b/chrome/browser/lacros/app_mode/kiosk_session_service_lacros.h
index 6d5c37a..ab6d1c8 100644
--- a/chrome/browser/lacros/app_mode/kiosk_session_service_lacros.h
+++ b/chrome/browser/lacros/app_mode/kiosk_session_service_lacros.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include "base/functional/callback_forward.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chromeos/crosapi/mojom/kiosk_session_service.mojom.h"
 #include "components/prefs/pref_registry_simple.h"
@@ -17,10 +18,23 @@
 }
 
 class Browser;
+class NewBrowserObserver;
 
 // Manage the kiosk session and related resources at the lacros side.
 class KioskSessionServiceLacros {
  public:
+  class Observer : public base::CheckedObserver {
+   public:
+    Observer() = default;
+    Observer(const Observer&) = delete;
+    Observer& operator=(const Observer&) = delete;
+    ~Observer() override = default;
+
+    // Triggered when the web kiosk session is initialized.
+    // TODO(b/323475701): call it for all kiosk sessions (web and chrome app).
+    virtual void KioskWebSessionInitialized() {}
+  };
+
   // Get the global instance. This singleton instance should be initialized
   // first before using it.
   static KioskSessionServiceLacros* Get();
@@ -40,9 +54,7 @@
   // Initialize the current Chrome Kiosk session with the `app_id`.
   void InitChromeKioskSession(Profile* profile, const std::string& app_id);
 
-  // Initialize the current Web Kiosk session with the `install_url` and the
-  // browser that is running the app.
-  void InitWebKioskSession(Browser* browser, const GURL& install_url);
+  void SetInstallUrl(const GURL install_url);
 
   // Get install URL for Web Kiosk session.
   const GURL& GetInstallURL() const { return install_url_; }
@@ -52,11 +64,19 @@
     return kiosk_browser_session_.get();
   }
 
+  std::unique_ptr<base::AutoReset<base::OnceClosure>>
+  SetAttemptUserExitCallbackForTesting(base::OnceClosure attempt_user_exit);
+
+  void AddObserver(Observer* observer);
+  void RemoveObserver(Observer* observer);
+
  protected:
-  // Tell the ash-chrome to end the kiosk session and return the current user
-  // to the login screen by calling the API provided by
-  // `kiosk_session_service_`. Virtual for tesitng.
-  virtual void AttemptUserExit();
+  // Initialize the current Web Kiosk session with the browser that is running
+  // the app.
+  void InitWebKioskSession(Browser& browser);
+
+  // Not null only for web kiosk sessions.
+  std::unique_ptr<NewBrowserObserver> new_browser_observer_;
 
   // The install URL used to initialize Web Kiosk session.
   GURL install_url_;
@@ -65,6 +85,11 @@
   // necessary.
   std::unique_ptr<chromeos::KioskBrowserSession> kiosk_browser_session_;
 
+  // Callback to be run when lacros is shutting down. Overridable in tests.
+  base::OnceClosure attempt_user_exit_;
+
+  base::ObserverList<Observer> observers_;
+
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<KioskSessionServiceLacros> weak_factory_{this};
diff --git a/chrome/browser/lacros/app_mode/web_kiosk_installer_lacros.cc b/chrome/browser/lacros/app_mode/web_kiosk_installer_lacros.cc
index 159121a..9c240626 100644
--- a/chrome/browser/lacros/app_mode/web_kiosk_installer_lacros.cc
+++ b/chrome/browser/lacros/app_mode/web_kiosk_installer_lacros.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "chrome/browser/chromeos/app_mode/web_kiosk_app_installer.h"
+#include "chrome/browser/lacros/app_mode/kiosk_session_service_lacros.h"
 #include "chromeos/crosapi/mojom/web_kiosk_service.mojom.h"
 #include "chromeos/lacros/lacros_service.h"
 #include "url/gurl.h"
@@ -48,6 +49,8 @@
       std::make_unique<chromeos::WebKioskAppInstaller>(profile_.get(), url);
   web_installer->GetInstallState(std::move(callback).Then(
       GetDeletePointerCallback(std::move(web_installer))));
+
+  KioskSessionServiceLacros::Get()->SetInstallUrl(url);
 }
 
 void WebKioskInstallerLacros::InstallWebKiosk(
diff --git a/chrome/browser/lacros/app_mode/web_kiosk_installer_lacros.h b/chrome/browser/lacros/app_mode/web_kiosk_installer_lacros.h
index 9c0655d0..f242a193 100644
--- a/chrome/browser/lacros/app_mode/web_kiosk_installer_lacros.h
+++ b/chrome/browser/lacros/app_mode/web_kiosk_installer_lacros.h
@@ -23,7 +23,8 @@
   WebKioskInstallerLacros& operator=(const WebKioskInstallerLacros&) = delete;
   ~WebKioskInstallerLacros() override;
 
-  // crosapi::mojom::WebKioskInstaller
+  // crosapi::mojom::WebKioskInstaller:
+  // Ash calls this function before launching the web app.
   void GetWebKioskInstallState(
       const GURL& url,
       GetWebKioskInstallStateCallback callback) override;
diff --git a/chrome/browser/lacros/app_mode/web_kiosk_installer_lacros_unittest.cc b/chrome/browser/lacros/app_mode/web_kiosk_installer_lacros_unittest.cc
index 4faa6879..aafbdb6 100644
--- a/chrome/browser/lacros/app_mode/web_kiosk_installer_lacros_unittest.cc
+++ b/chrome/browser/lacros/app_mode/web_kiosk_installer_lacros_unittest.cc
@@ -10,6 +10,7 @@
 
 #include "base/test/test_future.h"
 #include "chrome/browser/apps/app_service/app_service_test.h"
+#include "chrome/browser/lacros/app_mode/kiosk_session_service_lacros.h"
 #include "chrome/browser/web_applications/test/fake_web_app_provider.h"
 #include "chrome/browser/web_applications/test/fake_web_contents_manager.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
@@ -198,6 +199,7 @@
   TestingProfileManager testing_profile_manager_{
       TestingBrowserProcess::GetGlobal()};
   raw_ptr<TestingProfile> profile_;
+  KioskSessionServiceLacros kiosk_session_service_lacros_;
 };
 
 TEST_F(WebKioskInstallerLacrosTest, CreatingUnboundInstallerShouldNotCrash) {
diff --git a/chrome/browser/lacros/browser_service_lacros.cc b/chrome/browser/lacros/browser_service_lacros.cc
index db1609f..fc6ecd9b2 100644
--- a/chrome/browser/lacros/browser_service_lacros.cc
+++ b/chrome/browser/lacros/browser_service_lacros.cc
@@ -666,11 +666,6 @@
 
   browser->window()->Show();
 
-  if (chromeos::BrowserParamsProxy::Get()->SessionType() ==
-      crosapi::mojom::SessionType::kWebKioskSession) {
-    KioskSessionServiceLacros::Get()->InitWebKioskSession(browser, url);
-  }
-
   // Report a success result to ash. Please note that showing Lacros window is
   // asynchronous. Ash-chrome should use the `exo::WMHelper` class rather than
   // this callback method call to track window creation status.
diff --git a/chrome/browser/lacros/browser_service_lacros_browsertest.cc b/chrome/browser/lacros/browser_service_lacros_browsertest.cc
index 3f1fa90..76a99df 100644
--- a/chrome/browser/lacros/browser_service_lacros_browsertest.cc
+++ b/chrome/browser/lacros/browser_service_lacros_browsertest.cc
@@ -3,8 +3,13 @@
 // found in the LICENSE file.
 
 #include <cstdint>
+#include <memory>
 #include <optional>
 
+#include "base/auto_reset.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback_forward.h"
+#include "base/functional/callback_helpers.h"
 #include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/test_future.h"
@@ -56,6 +61,15 @@
 
 namespace {
 constexpr char kNavigationUrl[] = "https://www.google.com/";
+
+// Disables `AttemptUserExit` to avoid stopping Ash when the kiosk session
+// is finished. Otherwise all the following tests would be broken because Ash
+// is not running.
+std::unique_ptr<base::AutoReset<base::OnceClosure>> DisableAttemptUserExit() {
+  return KioskSessionServiceLacros::Get()->SetAttemptUserExitCallbackForTesting(
+      base::DoNothing());
+}
+
 }  // namespace
 
 class BrowserServiceLacrosBrowserTest : public InProcessBrowserTest {
@@ -95,17 +109,6 @@
           EXPECT_EQ(result, CreationResult::kSuccess);
         }));
     EXPECT_TRUE(use_callback);
-
-    // Verify `KioskBrowserSession` object is created when `NewFullscreenWindow`
-    // is called in the Web Kiosk session. Then, disable the `AttemptUserExit`
-    // method to do nothing.
-    if (chromeos::BrowserParamsProxy::Get()->SessionType() ==
-        SessionType::kWebKioskSession) {
-      chromeos::KioskBrowserSession* session =
-          KioskSessionServiceLacros::Get()->GetKioskBrowserSessionForTesting();
-      EXPECT_TRUE(session);
-      session->SetAttemptUserExitForTesting(base::DoNothing());
-    }
   }
 
   void CreateNewWindow() {
@@ -281,6 +284,19 @@
   BrowserServiceLacrosKioskBrowserTest()
       : BrowserServiceLacrosBrowserTest(
             crosapi::mojom::SessionType::kWebKioskSession) {}
+
+  void SetUpOnMainThread() override {
+    BrowserServiceLacrosBrowserTest::SetUpOnMainThread();
+    attempt_user_exit_reset_ = DisableAttemptUserExit();
+  }
+
+  void TearDownOnMainThread() override {
+    attempt_user_exit_reset_.reset();
+    BrowserServiceLacrosBrowserTest::TearDownOnMainThread();
+  }
+
+ private:
+  std::unique_ptr<base::AutoReset<base::OnceClosure>> attempt_user_exit_reset_;
 };
 
 IN_PROC_BROWSER_TEST_F(BrowserServiceLacrosKioskBrowserTest,
@@ -763,6 +779,19 @@
   BrowserServiceLacrosNonSyncingProfilesWebKioskBrowserTest()
       : BrowserServiceLacrosNonSyncingProfilesBrowserTest(
             crosapi::mojom::SessionType::kWebKioskSession) {}
+
+  void SetUpOnMainThread() override {
+    BrowserServiceLacrosNonSyncingProfilesBrowserTest::SetUpOnMainThread();
+    attempt_user_exit_reset_ = DisableAttemptUserExit();
+  }
+
+  void TearDownOnMainThread() override {
+    attempt_user_exit_reset_.reset();
+    BrowserServiceLacrosNonSyncingProfilesBrowserTest::TearDownOnMainThread();
+  }
+
+ private:
+  std::unique_ptr<base::AutoReset<base::OnceClosure>> attempt_user_exit_reset_;
 };
 
 IN_PROC_BROWSER_TEST_F(
diff --git a/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface.cc b/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface.cc
index 68068026..9a2a29e 100644
--- a/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface.cc
+++ b/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface.cc
@@ -258,7 +258,7 @@
   std::vector<std::string> discovery_scopes;
   discovery_scopes.push_back(kDiscoveryOAuth2Scope);
 
-  // TODO(crbug.com/1466447): ConsentLevel::kSync is deprecated and should be
+  // TODO(crbug.com/40067771): ConsentLevel::kSync is deprecated and should be
   //     removed. See ConsentLevel::kSync documentation for details.
   return std::make_unique<EndpointFetcher>(
       profile_->GetDefaultStoragePartition()
diff --git a/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface_unittest.cc b/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface_unittest.cc
index 70af5bf..4c70be48 100644
--- a/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface_unittest.cc
+++ b/chrome/browser/media/router/discovery/access_code/access_code_cast_discovery_interface_unittest.cc
@@ -190,7 +190,7 @@
         base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
             &test_url_loader_factory_);
 
-    // TODO(crbug.com/1466447): ConsentLevel::kSync is deprecated and should be
+    // TODO(crbug.com/40067771): ConsentLevel::kSync is deprecated and should be
     //     removed. See ConsentLevel::kSync documentation for details.
     endpoint_fetcher_ = std::make_unique<EndpointFetcher>(
         kMockOAuthConsumerName, GURL(kMockEndpoint), kHttpMethod,
diff --git a/chrome/browser/net/chrome_shared_dictionary_browsertest.cc b/chrome/browser/net/chrome_shared_dictionary_browsertest.cc
index 405203c..a12af6d 100644
--- a/chrome/browser/net/chrome_shared_dictionary_browsertest.cc
+++ b/chrome/browser/net/chrome_shared_dictionary_browsertest.cc
@@ -107,19 +107,9 @@
 
 std::optional<std::string> GetAvailableDictionary(
     const net::test_server::HttpRequest::HeaderMap& headers) {
-  switch (
-      network::features::kCompressionDictionaryTransportBackendVersion.Get()) {
-    case network::features::CompressionDictionaryTransportBackendVersion::kV1: {
-      auto it = headers.find("sec-available-dictionary");
-      return it == headers.end() ? std::nullopt
-                                 : std::make_optional(it->second);
-    }
-    case network::features::CompressionDictionaryTransportBackendVersion::kV2: {
       auto it = headers.find("available-dictionary");
       return it == headers.end() ? std::nullopt
                                  : std::make_optional(it->second);
-    }
-  }
 }
 
 void CheckSharedDictionaryUseCounter(
@@ -165,23 +155,14 @@
 // `ChromeSharedDictionaryBrowserTest` is required to test Chrome
 // specific code such as Site Settings.
 // See `SharedDictionaryBrowserTest` for content's version of tests.
-class ChromeSharedDictionaryBrowserTest
-    : public InProcessBrowserTest,
-      public ::testing::WithParamInterface<
-          network::features::CompressionDictionaryTransportBackendVersion> {
+class ChromeSharedDictionaryBrowserTest : public InProcessBrowserTest {
  public:
   ChromeSharedDictionaryBrowserTest() {
-    scoped_feature_list_.InitWithFeaturesAndParameters(
+    scoped_feature_list_.InitWithFeatures(
         /*enabled_features=*/
-        {base::test::FeatureRefAndParams(
-             network::features::kCompressionDictionaryTransportBackend,
-             {{network::features::kCompressionDictionaryTransportBackendVersion
-                   .name,
-               network::features::kCompressionDictionaryTransportBackendVersion
-                   .GetName(GetVersion())}}),
-         base::test::FeatureRefAndParams(
-             network::features::kCompressionDictionaryTransport, {}),
-         base::test::FeatureRefAndParams(network::features::kSharedZstd, {})},
+        {network::features::kCompressionDictionaryTransportBackend,
+         network::features::kCompressionDictionaryTransport,
+         network::features::kSharedZstd},
         /*disabled_features=*/{});
 
     embedded_test_server()->RegisterRequestHandler(
@@ -202,9 +183,6 @@
       const ChromeSharedDictionaryBrowserTest&) = delete;
 
  protected:
-  network::features::CompressionDictionaryTransportBackendVersion GetVersion() {
-    return GetParam();
-  }
   net::EmbeddedTestServer* cross_origin_server() {
     return cross_origin_server_.get();
   }
@@ -379,26 +357,7 @@
   base::test::ScopedFeatureList scoped_feature_list_;
 };
 
-INSTANTIATE_TEST_SUITE_P(
-    All,
-    ChromeSharedDictionaryBrowserTest,
-    testing::Values(
-        network::features::CompressionDictionaryTransportBackendVersion::kV1,
-        network::features::CompressionDictionaryTransportBackendVersion::kV2),
-    [](const testing::TestParamInfo<
-        network::features::CompressionDictionaryTransportBackendVersion>&
-           info) {
-      switch (info.param) {
-        case network::features::CompressionDictionaryTransportBackendVersion::
-            kV1:
-          return "V1";
-        case network::features::CompressionDictionaryTransportBackendVersion::
-            kV2:
-          return "V2";
-      }
-    });
-
-IN_PROC_BROWSER_TEST_P(ChromeSharedDictionaryBrowserTest, BlockWriting) {
+IN_PROC_BROWSER_TEST_F(ChromeSharedDictionaryBrowserTest, BlockWriting) {
   content_settings::CookieSettings* settings =
       CookieSettingsFactory::GetForProfile(browser()->profile()).get();
   settings->SetCookieSetting(embedded_test_server()->GetURL("/"),
@@ -409,7 +368,7 @@
   EXPECT_FALSE(TryRegisterDictionary(*embedded_test_server()));
 }
 
-IN_PROC_BROWSER_TEST_P(ChromeSharedDictionaryBrowserTest,
+IN_PROC_BROWSER_TEST_F(ChromeSharedDictionaryBrowserTest,
                        BlockWritingCrossOrigin) {
   content_settings::CookieSettings* settings =
       CookieSettingsFactory::GetForProfile(browser()->profile()).get();
@@ -421,7 +380,7 @@
   EXPECT_FALSE(TryRegisterDictionary(*cross_origin_server()));
 }
 
-IN_PROC_BROWSER_TEST_P(ChromeSharedDictionaryBrowserTest, BlockReading) {
+IN_PROC_BROWSER_TEST_F(ChromeSharedDictionaryBrowserTest, BlockReading) {
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL("/title1.html")));
   EXPECT_TRUE(TryRegisterDictionary(*embedded_test_server()));
@@ -438,7 +397,7 @@
       CheckDictionaryHeader(*embedded_test_server(), /*expect_blocked=*/true));
 }
 
-IN_PROC_BROWSER_TEST_P(ChromeSharedDictionaryBrowserTest,
+IN_PROC_BROWSER_TEST_F(ChromeSharedDictionaryBrowserTest,
                        BlockReadingCrossOrigin) {
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL("/title1.html")));
@@ -456,7 +415,7 @@
       CheckDictionaryHeader(*cross_origin_server(), /*expect_blocked=*/true));
 }
 
-IN_PROC_BROWSER_TEST_P(ChromeSharedDictionaryBrowserTest,
+IN_PROC_BROWSER_TEST_F(ChromeSharedDictionaryBrowserTest,
                        BlockReadingWhileNavigation) {
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL("/title1.html")));
@@ -477,7 +436,7 @@
       /*expect_blocked=*/true));
 }
 
-IN_PROC_BROWSER_TEST_P(ChromeSharedDictionaryBrowserTest,
+IN_PROC_BROWSER_TEST_F(ChromeSharedDictionaryBrowserTest,
                        BlockReadingWhileIframeNavigation) {
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL("/title1.html")));
@@ -498,7 +457,7 @@
       /*expect_blocked=*/true));
 }
 
-IN_PROC_BROWSER_TEST_P(ChromeSharedDictionaryBrowserTest,
+IN_PROC_BROWSER_TEST_F(ChromeSharedDictionaryBrowserTest,
                        UseCounterMainFrameNavigation) {
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL("/title1.html")));
@@ -532,7 +491,7 @@
       /*expected_used_for_subresource_count=*/0);
 }
 
-IN_PROC_BROWSER_TEST_P(ChromeSharedDictionaryBrowserTest,
+IN_PROC_BROWSER_TEST_F(ChromeSharedDictionaryBrowserTest,
                        UseCounterSubFrameNavigation) {
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL("/title1.html")));
@@ -577,7 +536,7 @@
       /*expected_used_for_subresource_count=*/0);
 }
 
-IN_PROC_BROWSER_TEST_P(ChromeSharedDictionaryBrowserTest,
+IN_PROC_BROWSER_TEST_F(ChromeSharedDictionaryBrowserTest,
                        UseCounterSubresource) {
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL("/title1.html")));
@@ -616,7 +575,7 @@
       /*expected_used_for_subresource_count=*/1);
 }
 
-IN_PROC_BROWSER_TEST_P(ChromeSharedDictionaryBrowserTest,
+IN_PROC_BROWSER_TEST_F(ChromeSharedDictionaryBrowserTest,
                        UseCounterZstdMainFrameNavigation) {
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL("/title1.html")));
@@ -650,7 +609,7 @@
       /*expected_used_for_subresource_count=*/0);
 }
 
-IN_PROC_BROWSER_TEST_P(ChromeSharedDictionaryBrowserTest,
+IN_PROC_BROWSER_TEST_F(ChromeSharedDictionaryBrowserTest,
                        UseCounterZstdSubresource) {
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL("/title1.html")));
@@ -695,7 +654,7 @@
 #else
 #define MAYBE_SiteDataCount SiteDataCount
 #endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
-IN_PROC_BROWSER_TEST_P(ChromeSharedDictionaryBrowserTest, MAYBE_SiteDataCount) {
+IN_PROC_BROWSER_TEST_F(ChromeSharedDictionaryBrowserTest, MAYBE_SiteDataCount) {
   base::Time time1 = base::Time::Now();
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL("/title1.html")));
diff --git a/chrome/browser/net/system_network_context_manager_browsertest.cc b/chrome/browser/net/system_network_context_manager_browsertest.cc
index f9ad7fb..dfd0738 100644
--- a/chrome/browser/net/system_network_context_manager_browsertest.cc
+++ b/chrome/browser/net/system_network_context_manager_browsertest.cc
@@ -18,7 +18,6 @@
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/component_updater/first_party_sets_component_installer.h"
 #include "chrome/browser/net/stub_resolver_config_reader.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
@@ -28,6 +27,7 @@
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/test_launcher_utils.h"
+#include "components/component_updater/installer_policies/first_party_sets_component_installer_policy.h"
 #include "components/prefs/pref_service.h"
 #include "components/version_info/version_info.h"
 #include "content/public/browser/network_service_instance.h"
diff --git a/chrome/browser/password_manager/android/built_in_backend_to_android_backend_migrator.cc b/chrome/browser/password_manager/android/built_in_backend_to_android_backend_migrator.cc
index 26ad06c..6258d78c 100644
--- a/chrome/browser/password_manager/android/built_in_backend_to_android_backend_migrator.cc
+++ b/chrome/browser/password_manager/android/built_in_backend_to_android_backend_migrator.cc
@@ -23,7 +23,7 @@
 
 namespace {
 
-// TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on Android.
+// TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on Android.
 using sync_util::IsSyncFeatureEnabledIncludingPasswords;
 
 // Threshold for the next migration attempt. This is needed in order to prevent
@@ -187,7 +187,7 @@
 }
 
 void BuiltInBackendToAndroidBackendMigrator::UpdateMigrationVersionInPref() {
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   if (!HasMigratedToTheAndroidBackend(prefs_) &&
       IsSyncFeatureEnabledIncludingPasswords(sync_service_)) {
@@ -206,7 +206,7 @@
 
   // Checks that pref and sync state indicate that the user needs an initial
   // migration to the android backend after enrolling into the UPM experiment.
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   if (!HasMigratedToTheAndroidBackend(prefs_) &&
       IsSyncFeatureEnabledIncludingPasswords(sync_service_)) {
@@ -219,7 +219,7 @@
   // Once the local storage is supported, android backend becomes the only
   // active backend and there is no need to do this migration.
   if (prefs_->GetBoolean(prefs::kRequiresMigrationAfterSyncStatusChange)) {
-    // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+    // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
     // Android.
     return IsSyncFeatureEnabledIncludingPasswords(sync_service_)
                ? MigrationType::kNonSyncableToAndroidBackend
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordStoreBridge.java b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordStoreBridge.java
index dab2938f..44216fc 100644
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordStoreBridge.java
+++ b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/PasswordStoreBridge.java
@@ -79,7 +79,24 @@
     @VisibleForTesting
     public void insertPasswordCredential(PasswordStoreCredential credential) {
         PasswordStoreBridgeJni.get()
-                .insertPasswordCredentialForTesting(mNativePasswordStoreBridge, credential);
+                .insertPasswordCredentialInProfileStoreForTesting(
+                        mNativePasswordStoreBridge, credential);
+    }
+
+    /** Inserts new credential into the profile password store. */
+    @VisibleForTesting
+    public void insertPasswordCredentialInProfileStore(PasswordStoreCredential credential) {
+        PasswordStoreBridgeJni.get()
+                .insertPasswordCredentialInProfileStoreForTesting(
+                        mNativePasswordStoreBridge, credential);
+    }
+
+    /** Inserts new credential into the account password store. */
+    @VisibleForTesting
+    public void insertPasswordCredentialInAccountStore(PasswordStoreCredential credential) {
+        PasswordStoreBridgeJni.get()
+                .insertPasswordCredentialInAccountStoreForTesting(
+                        mNativePasswordStoreBridge, credential);
     }
 
     public void blocklistForTesting(String url) {
@@ -167,7 +184,10 @@
     public interface Natives {
         long init(PasswordStoreBridge passwordStoreBridge);
 
-        void insertPasswordCredentialForTesting(
+        void insertPasswordCredentialInProfileStoreForTesting(
+                long nativePasswordStoreBridge, PasswordStoreCredential credential);
+
+        void insertPasswordCredentialInAccountStoreForTesting(
                 long nativePasswordStoreBridge, PasswordStoreCredential credential);
 
         void blocklistForTesting(long nativePasswordStoreBridge, String url);
diff --git a/chrome/browser/password_manager/android/local_passwords_migration_warning_util.cc b/chrome/browser/password_manager/android/local_passwords_migration_warning_util.cc
index b419c30..babe7af 100644
--- a/chrome/browser/password_manager/android/local_passwords_migration_warning_util.cc
+++ b/chrome/browser/password_manager/android/local_passwords_migration_warning_util.cc
@@ -101,7 +101,7 @@
     return false;
   }
 
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   if (password_manager::sync_util::IsSyncFeatureEnabledIncludingPasswords(
           SyncServiceFactory::GetForProfile(profile))) {
diff --git a/chrome/browser/password_manager/android/password_infobar_utils.cc b/chrome/browser/password_manager/android/password_infobar_utils.cc
index 82ce9eb89..45c4894f 100644
--- a/chrome/browser/password_manager/android/password_infobar_utils.cc
+++ b/chrome/browser/password_manager/android/password_infobar_utils.cc
@@ -18,7 +18,7 @@
 std::optional<AccountInfo> GetAccountInfoForPasswordMessages(Profile* profile) {
   DCHECK(profile);
 
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   if (!sync_util::IsSyncFeatureEnabledIncludingPasswords(
           SyncServiceFactory::GetForProfile(profile))) {
diff --git a/chrome/browser/password_manager/android/password_manager_settings_service_android_impl.cc b/chrome/browser/password_manager/android/password_manager_settings_service_android_impl.cc
index 17797c5..f1b76c1 100644
--- a/chrome/browser/password_manager/android/password_manager_settings_service_android_impl.cc
+++ b/chrome/browser/password_manager/android/password_manager_settings_service_android_impl.cc
@@ -152,7 +152,7 @@
 }
 
 void PasswordManagerSettingsServiceAndroidImpl::TurnOffAutoSignIn() {
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   if (!UsesUPMBackend()) {
     pref_service_->SetBoolean(
@@ -167,7 +167,7 @@
   pref_service_->SetBoolean(password_manager::prefs::kAutoSignInEnabledGMS,
                             false);
   std::optional<SyncingAccount> account = std::nullopt;
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   if (is_password_sync_enabled_) {
     account = SyncingAccount(sync_service_->GetAccountInfo().email);
@@ -185,7 +185,7 @@
   lifecycle_helper_->RegisterObserver(base::BindRepeating(
       &PasswordManagerSettingsServiceAndroidImpl::OnChromeForegrounded,
       weak_ptr_factory_.GetWeakPtr()));
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   is_password_sync_enabled_ =
       IsSyncFeatureEnabledIncludingPasswords(sync_service_);
@@ -268,14 +268,14 @@
 void PasswordManagerSettingsServiceAndroidImpl::OnStateChanged(
     syncer::SyncService* sync) {
   // Return early if the setting didn't change and no sync errors were resolved.
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   if (IsSyncFeatureEnabledIncludingPasswords(sync) ==
       is_password_sync_enabled_) {
     return;
   }
 
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   is_password_sync_enabled_ = IsSyncFeatureEnabledIncludingPasswords(sync);
 
diff --git a/chrome/browser/password_manager/android/password_store_android_account_backend.cc b/chrome/browser/password_manager/android/password_store_android_account_backend.cc
index 2780e86..9e8b80c 100644
--- a/chrome/browser/password_manager/android/password_store_android_account_backend.cc
+++ b/chrome/browser/password_manager/android/password_store_android_account_backend.cc
@@ -31,14 +31,14 @@
 
 std::string GetSyncingAccount(const syncer::SyncService* sync_service) {
   CHECK(sync_service);
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   return sync_util::GetAccountEmailIfSyncFeatureEnabledIncludingPasswords(
       sync_service);
 }
 
 void LogUPMActiveStatus(syncer::SyncService* sync_service, PrefService* prefs) {
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   if (!sync_util::IsSyncFeatureEnabledIncludingPasswords(sync_service)) {
     base::UmaHistogramEnumeration(
@@ -130,12 +130,13 @@
       affiliations_prefetcher_(affiliations_prefetcher) {
   sync_controller_delegate_ =
       std::make_unique<PasswordSyncControllerDelegateAndroid>(
-          std::make_unique<PasswordSyncControllerDelegateBridgeImpl>(),
-          base::BindOnce(&PasswordStoreAndroidAccountBackend::SyncShutdown,
-                         weak_ptr_factory_.GetWeakPtr()));
-  sync_controller_delegate_->SetPwdSyncStateChangedCallback(base::BindRepeating(
-      &PasswordStoreAndroidAccountBackend::OnPasswordsSyncStateChanged,
-      weak_ptr_factory_.GetWeakPtr()));
+          std::make_unique<PasswordSyncControllerDelegateBridgeImpl>());
+  sync_controller_delegate_->SetSyncObserverCallbacks(
+      base::BindRepeating(
+          &PasswordStoreAndroidAccountBackend::OnPasswordsSyncStateChanged,
+          weak_ptr_factory_.GetWeakPtr()),
+      base::BindOnce(&PasswordStoreAndroidAccountBackend::SyncShutdown,
+                     weak_ptr_factory_.GetWeakPtr()));
 }
 
 PasswordStoreAndroidAccountBackend::PasswordStoreAndroidAccountBackend(
@@ -151,9 +152,12 @@
                                   prefs),
       affiliations_prefetcher_(affiliations_prefetcher) {
   sync_controller_delegate_ = std::move(sync_controller_delegate);
-  sync_controller_delegate_->SetPwdSyncStateChangedCallback(base::BindRepeating(
-      &PasswordStoreAndroidAccountBackend::OnPasswordsSyncStateChanged,
-      weak_ptr_factory_.GetWeakPtr()));
+  sync_controller_delegate_->SetSyncObserverCallbacks(
+      base::BindRepeating(
+          &PasswordStoreAndroidAccountBackend::OnPasswordsSyncStateChanged,
+          weak_ptr_factory_.GetWeakPtr()),
+      base::BindOnce(&PasswordStoreAndroidAccountBackend::SyncShutdown,
+                     weak_ptr_factory_.GetWeakPtr()));
 }
 
 PasswordStoreAndroidAccountBackend::~PasswordStoreAndroidAccountBackend() =
@@ -432,6 +436,12 @@
 }
 
 void PasswordStoreAndroidAccountBackend::SyncShutdown() {
+  ClearAllTasksAndReplyWithReason(
+      AndroidBackendError(
+          AndroidBackendErrorType::kCancelledPwdSyncStateChanged),
+      PasswordStoreBackendError(
+          PasswordStoreBackendErrorType::kUncategorized,
+          PasswordStoreBackendErrorRecoveryType::kRecoverable));
   sync_service_ = nullptr;
 }
 
diff --git a/chrome/browser/password_manager/android/password_store_android_account_backend_unittest.cc b/chrome/browser/password_manager/android/password_store_android_account_backend_unittest.cc
index 6fbc952..8bd9ebe 100644
--- a/chrome/browser/password_manager/android/password_store_android_account_backend_unittest.cc
+++ b/chrome/browser/password_manager/android/password_store_android_account_backend_unittest.cc
@@ -254,8 +254,7 @@
   CreatePasswordSyncControllerDelegate() {
     auto unique_delegate = std::make_unique<
         PasswordSyncControllerDelegateAndroid>(
-        std::make_unique<NiceMock<MockPasswordSyncControllerDelegateBridge>>(),
-        base::DoNothing());
+        std::make_unique<NiceMock<MockPasswordSyncControllerDelegateBridge>>());
     sync_controller_delegate_ = unique_delegate.get();
     return unique_delegate;
   }
@@ -1116,6 +1115,72 @@
 }
 
 TEST_F(PasswordStoreAndroidAccountBackendTest,
+       PostedDelayedRetryCancelledOnSyncShutdown) {
+  base::HistogramTester histogram_tester;
+  backend().InitBackend(
+      /*affiliated_match_helper=*/nullptr,
+      PasswordStoreAndroidAccountBackend::RemoteChangesReceived(),
+      base::NullCallback(), base::DoNothing());
+  backend().OnSyncServiceInitialized(sync_service());
+  EnableSyncForTestAccount();
+
+  base::MockCallback<LoginsOrErrorReply> mock_reply;
+
+  // GetAllLogins will be called once with a retriable error.
+  const JobId kFailedJobId{1};
+  EXPECT_CALL(*bridge_helper(), GetAllLogins).WillOnce(Return(kFailedJobId));
+
+  base::Time before_call_time = task_environment_.GetMockClock()->Now();
+
+  // Initiating the first call.
+  backend().GetAllLoginsAsync(mock_reply.Get());
+
+  // Answering the call with an error.
+  consumer().OnError(kFailedJobId, CreateNetworkError());
+  RunUntilIdle();
+
+  sync_service()->Shutdown();
+  PasswordStoreBackendError expected_error{
+      PasswordStoreBackendErrorType::kUncategorized,
+      PasswordStoreBackendErrorRecoveryType::kRecoverable};
+  EXPECT_CALL(mock_reply,
+              Run(VariantWith<PasswordStoreBackendError>(expected_error)));
+  RunUntilIdle();
+
+  // Since the retry was cancelled, nothing should happen after the retry
+  // timeout
+  EXPECT_CALL(*bridge_helper(), GetAllLogins).Times(0);
+  task_environment_.FastForwardUntilNoTasksRemain();
+  base::Time after_retry_time = task_environment_.GetMockClock()->Now();
+  EXPECT_GE(after_retry_time - before_call_time, base::Seconds(1));
+
+  // Per-operation retry histograms
+  histogram_tester.ExpectBucketCount(
+      base::StrCat({kRetryHistogramBase, ".GetAllLoginsAsync.APIError"}),
+      static_cast<int>(AndroidBackendAPIErrorCode::kNetworkError), 1);
+
+  // "Attempt" is recorder when the method call attempt ends.
+  histogram_tester.ExpectUniqueSample(
+      base::StrCat({kRetryHistogramBase, ".GetAllLoginsAsync.Attempt"}), 1, 1);
+  // "CancelledAtAttempt", records the attempt that was ongoing when the
+  // sync status changes.
+  histogram_tester.ExpectUniqueSample(
+      base::StrCat(
+          {kRetryHistogramBase, ".GetAllLoginsAsync.CancelledAtAttempt"}),
+      2, 1);
+
+  // Aggregated retry histograms
+  histogram_tester.ExpectBucketCount(
+      base::StrCat({kRetryHistogramBase, ".APIError"}),
+      static_cast<int>(AndroidBackendAPIErrorCode::kNetworkError), 1);
+
+  histogram_tester.ExpectUniqueSample(
+      base::StrCat({kRetryHistogramBase, ".Attempt"}), 1, 1);
+  histogram_tester.ExpectUniqueSample(
+      base::StrCat({kRetryHistogramBase, ".CancelledAtAttempt"}), 2, 1);
+}
+
+TEST_F(PasswordStoreAndroidAccountBackendTest,
        OnExternalAuthErrorNotCausingExperimentUnenrollmentButSuspendsSaving) {
   base::HistogramTester histogram_tester;
   backend().InitBackend(/*affiliated_match_helper=*/nullptr,
@@ -1465,6 +1530,38 @@
 }
 
 TEST_F(PasswordStoreAndroidAccountBackendTest,
+       CancelPendingJobsOnSyncShutdown) {
+  const std::string kSuccessMetric = SuccessMetricName("GetAllLoginsAsync");
+  const std::string kDurationMetric = DurationMetricName("GetAllLoginsAsync");
+  base::HistogramTester histogram_tester;
+  backend().InitBackend(/*affiliated_match_helper=*/nullptr,
+                        /*remote_form_changes_received=*/base::DoNothing(),
+                        /*sync_enabled_or_disabled_cb=*/base::NullCallback(),
+                        /*completion=*/base::DoNothing());
+  backend().OnSyncServiceInitialized(sync_service());
+  EnableSyncForTestAccount();
+
+  base::MockCallback<LoginsOrErrorReply> mock_reply;
+  EXPECT_CALL(*bridge_helper(), GetAllLogins).WillOnce(Return(kJobId));
+
+  // This call will queue the job.
+  backend().GetAllLoginsAsync(mock_reply.Get());
+
+  sync_service()->Shutdown();
+  PasswordStoreBackendError expected_error{
+      PasswordStoreBackendErrorType::kUncategorized,
+      PasswordStoreBackendErrorRecoveryType::kRecoverable};
+  EXPECT_CALL(mock_reply,
+              Run(VariantWith<PasswordStoreBackendError>(expected_error)));
+  RunUntilIdle();
+  histogram_tester.ExpectUniqueSample(kSuccessMetric, false, 1);
+  histogram_tester.ExpectUniqueSample(
+      kBackendErrorCodeMetric,
+      AndroidBackendErrorType::kCancelledPwdSyncStateChanged, 1);
+  histogram_tester.ExpectTotalCount(kDurationMetric, 0);
+}
+
+TEST_F(PasswordStoreAndroidAccountBackendTest,
        RecordClearedZombieTaskWithoutLatency) {
   const char kStartedMetric[] =
       "PasswordManager.PasswordStoreAndroidBackend.AddLoginAsync";
diff --git a/chrome/browser/password_manager/android/password_store_backend_migration_decorator.cc b/chrome/browser/password_manager/android/password_store_backend_migration_decorator.cc
index ffbdabb..6ac7ce14 100644
--- a/chrome/browser/password_manager/android/password_store_backend_migration_decorator.cc
+++ b/chrome/browser/password_manager/android/password_store_backend_migration_decorator.cc
@@ -22,7 +22,7 @@
 
 namespace {
 
-// TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on Android.
+// TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on Android.
 using sync_util::IsSyncFeatureEnabledIncludingPasswords;
 
 // Time in seconds by which the passwords migration from the built-in backend to
@@ -64,7 +64,7 @@
 void PasswordStoreBackendMigrationDecorator::PasswordSyncSettingsHelper::
     CachePasswordSyncSettingOnStartup(syncer::SyncService* sync) {
   sync_service_ = sync;
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   password_sync_configured_setting_ =
       sync_util::IsSyncFeatureEnabledIncludingPasswords(sync);
@@ -74,7 +74,7 @@
 void PasswordStoreBackendMigrationDecorator::PasswordSyncSettingsHelper::
     SyncStatusChangeApplied() {
   DCHECK(sync_service_);
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   password_sync_applied_setting_ =
       sync_util::IsSyncFeatureEnabledIncludingPasswords(sync_service_);
@@ -85,13 +85,13 @@
   DCHECK(sync_service_ == sync);
 
   // Return early if the setting didn't change.
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   if (sync_util::IsSyncFeatureEnabledIncludingPasswords(sync) ==
       password_sync_configured_setting_) {
     return;
   }
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   password_sync_configured_setting_ =
       sync_util::IsSyncFeatureEnabledIncludingPasswords(sync);
@@ -113,7 +113,7 @@
     OnSyncCycleCompleted(syncer::SyncService* sync) {
   // Reenrollment check is made on the first sync cycle when password sync is
   // active.
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   if (!sync_util::IsSyncFeatureActiveIncludingPasswords(sync) ||
       !is_waiting_for_the_first_sync_cycle_) {
@@ -130,7 +130,7 @@
     return;
   }
 
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   if (sync_util::IsSyncFeatureActiveIncludingPasswords(sync)) {
     int reenrollment_attempts = prefs_->GetInteger(
@@ -338,7 +338,7 @@
   if (!ShouldAttemptMigration(prefs_))
     return;
 
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   if (prefs_->GetBoolean(prefs::kRequiresMigrationAfterSyncStatusChange) &&
       !IsSyncFeatureEnabledIncludingPasswords(sync_service_)) {
diff --git a/chrome/browser/password_manager/android/password_store_bridge.cc b/chrome/browser/password_manager/android/password_store_bridge.cc
index e01878d..4941c4d 100644
--- a/chrome/browser/password_manager/android/password_store_bridge.cc
+++ b/chrome/browser/password_manager/android/password_store_bridge.cc
@@ -65,12 +65,19 @@
 
 PasswordStoreBridge::~PasswordStoreBridge() = default;
 
-void PasswordStoreBridge::InsertPasswordCredentialForTesting(
+void PasswordStoreBridge::InsertPasswordCredentialInProfileStoreForTesting(
     JNIEnv* env,
     const base::android::JavaParamRef<jobject>& credential) {
   profile_store_->AddLogin(ConvertJavaObjectToPasswordForm(env, credential));
 }
 
+void PasswordStoreBridge::InsertPasswordCredentialInAccountStoreForTesting(
+    JNIEnv* env,
+    const base::android::JavaParamRef<jobject>& credential) {
+  CHECK(account_store_);
+  account_store_->AddLogin(ConvertJavaObjectToPasswordForm(env, credential));
+}
+
 void PasswordStoreBridge::BlocklistForTesting(
     JNIEnv* env,
     const base::android::JavaParamRef<jstring>& jurl) {
@@ -132,6 +139,9 @@
 
 void PasswordStoreBridge::ClearAllPasswords(JNIEnv* env) {
   profile_store_->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max());
+  if (account_store_) {
+    account_store_->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max());
+  }
 }
 
 void PasswordStoreBridge::Destroy(JNIEnv* env) {
diff --git a/chrome/browser/password_manager/android/password_store_bridge.h b/chrome/browser/password_manager/android/password_store_bridge.h
index 078b6cdf..046b9b8 100644
--- a/chrome/browser/password_manager/android/password_store_bridge.h
+++ b/chrome/browser/password_manager/android/password_store_bridge.h
@@ -28,8 +28,13 @@
   PasswordStoreBridge(const PasswordStoreBridge&) = delete;
   PasswordStoreBridge& operator=(const PasswordStoreBridge&) = delete;
 
-  // Called by Java to store a new credential into the password store.
-  void InsertPasswordCredentialForTesting(
+  // Called by Java to store a new credential into the profile password store.
+  void InsertPasswordCredentialInProfileStoreForTesting(
+      JNIEnv* env,
+      const base::android::JavaParamRef<jobject>& credential);
+
+  // Called by Java to store a new credential into the account password store.
+  void InsertPasswordCredentialInAccountStoreForTesting(
       JNIEnv* env,
       const base::android::JavaParamRef<jobject>& credential);
 
@@ -74,20 +79,21 @@
   // The corresponding java object.
   base::android::ScopedJavaGlobalRef<jobject> java_bridge_;
 
-  scoped_refptr<password_manager::PasswordStoreInterface> profile_store_ =
+  const scoped_refptr<password_manager::PasswordStoreInterface> profile_store_ =
       ProfilePasswordStoreFactory::GetForProfile(
           ProfileManager::GetLastUsedProfile(),
           ServiceAccessType::EXPLICIT_ACCESS);
+  const scoped_refptr<password_manager::PasswordStoreInterface> account_store_ =
+      AccountPasswordStoreFactory::GetForProfile(
+          ProfileManager::GetLastUsedProfile(),
+          ServiceAccessType::EXPLICIT_ACCESS);
 
   // Used to fetch and edit passwords.
   // TODO(crbug.com/1442826): Use PasswordStore directly.
   password_manager::SavedPasswordsPresenter saved_passwords_presenter_{
       AffiliationServiceFactory::GetForProfile(
           ProfileManager::GetLastUsedProfile()),
-      profile_store_,
-      AccountPasswordStoreFactory::GetForProfile(
-          ProfileManager::GetLastUsedProfile(),
-          ServiceAccessType::EXPLICIT_ACCESS)};
+      profile_store_, account_store_};
 
   // A scoped observer for `saved_passwords_presenter_`.
   base::ScopedObservation<password_manager::SavedPasswordsPresenter,
diff --git a/chrome/browser/password_manager/android/password_sync_controller_delegate_android.cc b/chrome/browser/password_manager/android/password_sync_controller_delegate_android.cc
index fd1ecb96..3053717 100644
--- a/chrome/browser/password_manager/android/password_sync_controller_delegate_android.cc
+++ b/chrome/browser/password_manager/android/password_sync_controller_delegate_android.cc
@@ -21,7 +21,7 @@
 
 namespace {
 
-// TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on Android.
+// TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on Android.
 using sync_util::IsSyncFeatureEnabledIncludingPasswords;
 
 std::string BuildCredentialManagerNotificationMetricName(
@@ -33,10 +33,8 @@
 }  // namespace
 
 PasswordSyncControllerDelegateAndroid::PasswordSyncControllerDelegateAndroid(
-    std::unique_ptr<PasswordSyncControllerDelegateBridge> bridge,
-    base::OnceClosure on_sync_shutdown)
-    : bridge_(std::move(bridge)),
-      on_sync_shutdown_(std::move(on_sync_shutdown)) {
+    std::unique_ptr<PasswordSyncControllerDelegateBridge> bridge)
+    : bridge_(std::move(bridge)) {
   DCHECK(bridge_);
   bridge_->SetConsumer(weak_ptr_factory_.GetWeakPtr());
 }
@@ -44,9 +42,11 @@
 PasswordSyncControllerDelegateAndroid::
     ~PasswordSyncControllerDelegateAndroid() = default;
 
-void PasswordSyncControllerDelegateAndroid::SetPwdSyncStateChangedCallback(
-    base::RepeatingClosure on_pwd_sync_state_changed) {
+void PasswordSyncControllerDelegateAndroid::SetSyncObserverCallbacks(
+    base::RepeatingClosure on_pwd_sync_state_changed,
+    base::OnceClosure on_sync_shutdown) {
   on_pwd_sync_state_changed_ = std::move(on_pwd_sync_state_changed);
+  on_sync_shutdown_ = std::move(on_sync_shutdown);
 }
 
 std::unique_ptr<syncer::ProxyModelTypeControllerDelegate>
@@ -61,7 +61,7 @@
 void PasswordSyncControllerDelegateAndroid::OnSyncServiceInitialized(
     syncer::SyncService* sync_service) {
   sync_observation_.Observe(sync_service);
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   is_sync_enabled_ =
       IsPwdSyncEnabled(IsSyncFeatureEnabledIncludingPasswords(sync_service));
@@ -172,7 +172,7 @@
 
 void PasswordSyncControllerDelegateAndroid::UpdateCredentialManagerSyncStatus(
     syncer::SyncService* sync_service) {
-  // TODO(crbug.com/1466445): Migrate away from `ConsentLevel::kSync` on
+  // TODO(crbug.com/40067770): Migrate away from `ConsentLevel::kSync` on
   // Android.
   IsPwdSyncEnabled is_enabled =
       IsPwdSyncEnabled(IsSyncFeatureEnabledIncludingPasswords(sync_service));
diff --git a/chrome/browser/password_manager/android/password_sync_controller_delegate_android.h b/chrome/browser/password_manager/android/password_sync_controller_delegate_android.h
index ae037cf4..9af9a5f 100644
--- a/chrome/browser/password_manager/android/password_sync_controller_delegate_android.h
+++ b/chrome/browser/password_manager/android/password_sync_controller_delegate_android.h
@@ -33,9 +33,9 @@
  public:
   using IsPwdSyncEnabled = base::StrongAlias<struct IsPwdSyncEnabledTag, bool>;
 
-  PasswordSyncControllerDelegateAndroid(
-      std::unique_ptr<PasswordSyncControllerDelegateBridge> bridge,
-      base::OnceClosure on_sync_shutdown);
+  explicit PasswordSyncControllerDelegateAndroid(
+      std::unique_ptr<PasswordSyncControllerDelegateBridge> bridge);
+
   PasswordSyncControllerDelegateAndroid(
       const PasswordSyncControllerDelegateAndroid&) = delete;
   PasswordSyncControllerDelegateAndroid(
@@ -46,9 +46,14 @@
       PasswordSyncControllerDelegateAndroid&&) = delete;
   ~PasswordSyncControllerDelegateAndroid() override;
 
-  // Sets a callback to be called when password sync turns on or off.
-  void SetPwdSyncStateChangedCallback(
-      base::RepeatingClosure on_pwd_sync_state_changed);
+  // Sets callbacks to be called when the passwords sync state changes or the
+  // service is being shut down.
+  void SetSyncObserverCallbacks(
+      base::RepeatingClosure on_pwd_sync_state_changed,
+      base::OnceClosure on_sync_shutdown);
+
+  // Sets a callback to be called when the sync service is being shut down.
+  void SetSyncShutdownCallback(base::OnceClosure(on_sync_shutdown));
 
   // syncer::ModelTypeControllerDelegate implementation
   void OnSyncStarting(const syncer::DataTypeActivationRequest& request,
diff --git a/chrome/browser/password_manager/android/password_sync_controller_delegate_android_unittest.cc b/chrome/browser/password_manager/android/password_sync_controller_delegate_android_unittest.cc
index 065e3884..33e0afb 100644
--- a/chrome/browser/password_manager/android/password_sync_controller_delegate_android_unittest.cc
+++ b/chrome/browser/password_manager/android/password_sync_controller_delegate_android_unittest.cc
@@ -35,10 +35,9 @@
  protected:
   PasswordSyncControllerDelegateAndroidTest() {
     sync_controller_delegate_ =
-        std::make_unique<PasswordSyncControllerDelegateAndroid>(
-            CreateBridge(), base::DoNothing());
-    sync_controller_delegate_->SetPwdSyncStateChangedCallback(
-        mock_sync_state_changed_callback_.Get());
+        std::make_unique<PasswordSyncControllerDelegateAndroid>(CreateBridge());
+    sync_controller_delegate_->SetSyncObserverCallbacks(
+        mock_sync_state_changed_callback_.Get(), base::DoNothing());
   }
 
   ~PasswordSyncControllerDelegateAndroidTest() override {
@@ -267,8 +266,9 @@
 TEST_F(PasswordSyncControllerDelegateAndroidTest, OnSyncShutdown) {
   base::MockCallback<base::OnceClosure> mock_shutdown_callback;
   auto sync_controller =
-      std::make_unique<PasswordSyncControllerDelegateAndroid>(
-          CreateBridge(), mock_shutdown_callback.Get());
+      std::make_unique<PasswordSyncControllerDelegateAndroid>(CreateBridge());
+  sync_controller->SetSyncObserverCallbacks(base::DoNothing(),
+                                            mock_shutdown_callback.Get());
   syncer::TestSyncService sync_service;
 
   EXPECT_CALL(mock_shutdown_callback, Run);
diff --git a/chrome/browser/password_manager/password_reuse_manager_factory.cc b/chrome/browser/password_manager/password_reuse_manager_factory.cc
index 5cb37e8..afcdd42 100644
--- a/chrome/browser/password_manager/password_reuse_manager_factory.cc
+++ b/chrome/browser/password_manager/password_reuse_manager_factory.cc
@@ -39,7 +39,7 @@
     return SignInState::kSignedOut;
   }
 
-  // TODO(crbug.com/1462552): Simplify once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Simplify once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   const std::string sync_username =
diff --git a/chrome/browser/profiles/profile_keyed_service_browsertest.cc b/chrome/browser/profiles/profile_keyed_service_browsertest.cc
index 411b93b1..490fca6 100644
--- a/chrome/browser/profiles/profile_keyed_service_browsertest.cc
+++ b/chrome/browser/profiles/profile_keyed_service_browsertest.cc
@@ -21,8 +21,8 @@
 #include "components/keyed_service/core/keyed_service_base_factory.h"
 #include "components/omnibox/common/omnibox_features.h"
 #include "components/optimization_guide/machine_learning_tflite_buildflags.h"
-#include "components/search/ntp_features.h"
 #include "components/services/screen_ai/buildflags/buildflags.h"
+#include "components/signin/public/base/signin_switches.h"
 #include "components/supervised_user/core/common/buildflags.h"
 #include "content/public/common/content_features.h"
 #include "content/public/test/browser_test.h"
@@ -179,6 +179,9 @@
           features::kTrustSafetySentimentSurvey,
           companion::visual_query::features::kVisualQuerySuggestions,
 #endif  // !BUILDFLAG(IS_ANDROID)
+#if BUILDFLAG(IS_WIN)
+          switches::kEnableBoundSessionCredentials,
+#endif  // BUILDFLAG(IS_WIN)
           blink::features::kBrowsingTopics,
           net::features::kTpcdMetadataGrants,
           net::features::kTpcdTrialSettings,
@@ -192,9 +195,6 @@
           omnibox::kOnDeviceTailModel,
           omnibox::kOnDeviceHeadProviderNonIncognito,
 #endif  // BUILDFLAG(BUILD_WITH_TFLITE_LIB)
-#if !BUILDFLAG(IS_ANDROID)
-          ntp_features::kCustomizeChromeWallpaperSearch
-#endif  // !BUILDFLAG(IS_ANDROID)
         },
         {});
     // clang-format on
@@ -248,6 +248,9 @@
     "BluetoothSocketEventDispatcher",
     "BrowsingDataLifetimeManager",
     "CookieSettings",
+#if BUILDFLAG(IS_WIN)
+    "BoundSessionCookieRefreshService",
+#endif  // BUILDFLAG(IS_WIN)
     "ExtensionSystem",
     "ExtensionURLLoaderFactory::BrowserContextShutdownNotifierFactory",
     "FederatedIdentityPermissionContext",
@@ -302,6 +305,9 @@
     "TrackingProtectionSettings",
     "UDPSocketEventDispatcher",
     "UkmBackgroundRecorderService",
+#if BUILDFLAG(IS_WIN)
+    "UnexportableKeyService",
+#endif  // BUILDFLAG(IS_WIN)
     "UpdaterService",
     "UsbDeviceManager",
     "UsbDeviceResourceManager",
@@ -554,7 +560,6 @@
     "UserPolicySigninService",
 #if !BUILDFLAG(IS_ANDROID)
     "VisualQuerySuggestionsService",
-    "WallpaperSearchService",
 #endif  // !BUILDFLAG(IS_ANDROID)
     "WarningBadgeService",
     "WarningService",
diff --git a/chrome/browser/profiles/profile_statistics_aggregator.cc b/chrome/browser/profiles/profile_statistics_aggregator.cc
index e8d8b2a9..abbce1c 100644
--- a/chrome/browser/profiles/profile_statistics_aggregator.cc
+++ b/chrome/browser/profiles/profile_statistics_aggregator.cc
@@ -95,10 +95,11 @@
 #else
       nullptr;
 #endif
+  // Only count local passwords.
   AddCounter(std::make_unique<browsing_data::SigninDataCounter>(
       ProfilePasswordStoreFactory::GetForProfile(
           profile_, ServiceAccessType::EXPLICIT_ACCESS),
-      /*account_store=*/nullptr, /*sync_service=*/nullptr,
+      /*account_store=*/nullptr, profile_->GetPrefs(), /*sync_service=*/nullptr,
       std::move(credential_store)));
 
   // Initiate autofill counting.
diff --git a/chrome/browser/resources/chromeos/login/BUILD.gn b/chrome/browser/resources/chromeos/login/BUILD.gn
index eb5fc36..2b7af9a 100644
--- a/chrome/browser/resources/chromeos/login/BUILD.gn
+++ b/chrome/browser/resources/chromeos/login/BUILD.gn
@@ -201,7 +201,6 @@
   deps = [
     ":closure_compile_local",
     "components:closure_compile",
-    "screens/common:closure_compile",
     "screens/oobe:closure_compile",
     "test_api:closure_compile",
 
diff --git a/chrome/browser/resources/chromeos/login/login.gni b/chrome/browser/resources/chromeos/login/login.gni
index e61b975..82674ce 100644
--- a/chrome/browser/resources/chromeos/login/login.gni
+++ b/chrome/browser/resources/chromeos/login/login.gni
@@ -117,7 +117,7 @@
   "screens/common/marketing_opt_in.ts",
   "screens/common/multidevice_setup.ts",
   "screens/common/offline_ad_login.ts",
-  "screens/common/online_authentication_screen.js",
+  "screens/common/online_authentication_screen.ts",
   "screens/common/oobe_reset.ts",
   "screens/common/os_install.ts",
   "screens/common/os_trial.ts",
@@ -129,7 +129,7 @@
   "screens/common/placeholder.ts",
   "screens/common/recommend_apps.ts",
   "screens/common/saml_confirm_password.ts",
-  "screens/common/signin_fatal_error.js",
+  "screens/common/signin_fatal_error.ts",
   "screens/common/smart_privacy_protection.ts",
   "screens/common/sync_consent.ts",
   "screens/common/theme_selection.ts",
diff --git a/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn b/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn
index b6aba99..80a51e6 100644
--- a/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn
+++ b/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn
@@ -2,49 +2,11 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//third_party/closure_compiler/compile_js.gni")
-import("//tools/grit/grit_rule.gni")
 import("//tools/polymer/html_to_wrapper.gni")
 import("../../login.gni")
 
 assert(is_chromeos, "OOBE UI is only available on ChromeOS builds")
 
-group("closure_compile") {
-  deps = [ ":closure_compile_local" ]
-}
-
-js_type_check("closure_compile_local") {
-  is_polymer3 = true
-  closure_flags =
-      default_closure_args + mojom_js_args + [
-        "js_module_root=" +
-            rebase_path("//chrome/browser/resources/gaia_auth_host/",
-                        root_build_dir),
-        "js_module_root=./gen/chrome/browser/resources/gaia_auth_host",
-      ]
-  deps = [ ":signin_fatal_error" ]
-}
-
-###############################
-# Closure compiler libraries below
-
-# Template used by the `tools/oobe/generate_screen_template.py` script.
-
-js_library("signin_fatal_error") {
-  sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/screens/common/signin_fatal_error.js" ]
-  deps = [
-    "../../components:display_manager_types",
-    "../../components:oobe_types",
-    "../../components/behaviors:login_screen_behavior",
-    "../../components/behaviors:multi_step_behavior",
-    "../../components/behaviors:oobe_dialog_host_behavior",
-    "../../components/behaviors:oobe_i18n_behavior",
-    "../../components/dialogs:oobe_adaptive_dialog",
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-  ]
-  extra_deps = [ ":web_components" ]
-}
-
 group("web_components") {
   public_deps = [
     ":copy_js",
diff --git a/chrome/browser/resources/chromeos/login/screens/common/online_authentication_screen.js b/chrome/browser/resources/chromeos/login/screens/common/online_authentication_screen.js
deleted file mode 100644
index 956a68ed..0000000
--- a/chrome/browser/resources/chromeos/login/screens/common/online_authentication_screen.js
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Oobe signin screen implementation.
- */
-
-import '//resources/polymer/v3_0/iron-icon/iron-icon.js';
-import '../../components/dialogs/oobe_loading_dialog.js';
-
-import {assert} from '//resources/ash/common/assert.js';
-import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import {LoginScreenBehavior, LoginScreenBehaviorInterface} from '../../components/behaviors/login_screen_behavior.js';
-import {MultiStepBehavior, MultiStepBehaviorInterface} from '../../components/behaviors/multi_step_behavior.js';
-import {OobeI18nBehavior, OobeI18nBehaviorInterface} from '../../components/behaviors/oobe_i18n_behavior.js';
-
-import {getTemplate} from './online_authentication_screen.html.js';
-
-
-
-/**
- * UI mode for the dialog.
- * @enum {string}
- */
-const DialogMode = {
-  LOADING: 'loading',
-};
-
-
-/**
- * @constructor
- * @extends {PolymerElement}
- * @implements {LoginScreenBehaviorInterface}
- * @implements {MultiStepBehaviorInterface}
- * @implements {OobeI18nBehaviorInterface}
- */
-const OnlineAuthenticationScreenElementBase = mixinBehaviors(
-  [OobeI18nBehavior, LoginScreenBehavior, MultiStepBehavior], PolymerElement);
-
-
-/**
- * @polymer
- */
-class OnlineAuthenticationScreenElement extends OnlineAuthenticationScreenElementBase {
-  static get is() {
-    return 'online-authentication-screen-element';
-  }
-
-  static get template() {
-    return getTemplate();
-  }
-
-  static get properties() {
-    return {
-    };
-  }
-
-  get EXTERNAL_API() {
-    return [];
-  }
-
-  defaultUIStep() {
-    return DialogMode.LOADING;
-  }
-
-  get UI_STEPS() {
-    return DialogMode;
-  }
-
-  /** @override */
-  ready() {
-    super.ready();
-    this.initializeLoginScreen('OnlineAuthenticationScreen');
-  }
-
-  /**
-   * Event handler that is invoked just before the frame is shown.
-   * @param {Object} data Screen init payload
-   */
-  onBeforeShow() {
-  }
-}
-
-customElements.define(OnlineAuthenticationScreenElement.is, OnlineAuthenticationScreenElement);
diff --git a/chrome/browser/resources/chromeos/login/screens/common/online_authentication_screen.ts b/chrome/browser/resources/chromeos/login/screens/common/online_authentication_screen.ts
new file mode 100644
index 0000000..a702c00
--- /dev/null
+++ b/chrome/browser/resources/chromeos/login/screens/common/online_authentication_screen.ts
@@ -0,0 +1,70 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Oobe signin screen implementation.
+ */
+
+import '//resources/polymer/v3_0/iron-icon/iron-icon.js';
+import '../../components/dialogs/oobe_loading_dialog.js';
+
+import {PolymerElementProperties} from '//resources/polymer/v3_0/polymer/interfaces.js';
+import {mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {LoginScreenBehavior, LoginScreenBehaviorInterface} from '../../components/behaviors/login_screen_behavior.js';
+import {MultiStepBehavior, MultiStepBehaviorInterface} from '../../components/behaviors/multi_step_behavior.js';
+import {OobeI18nBehavior, OobeI18nBehaviorInterface} from '../../components/behaviors/oobe_i18n_behavior.js';
+
+import {getTemplate} from './online_authentication_screen.html.js';
+
+/**
+ * UI mode for the dialog.
+ */
+enum DialogMode {
+  LOADING = 'loading',
+}
+
+const OnlineAuthenticationScreenElementBase = mixinBehaviors(
+  [LoginScreenBehavior, MultiStepBehavior, OobeI18nBehavior],
+  PolymerElement) as { new (): PolymerElement
+    & LoginScreenBehaviorInterface
+    & MultiStepBehaviorInterface
+    & OobeI18nBehaviorInterface,
+  };
+
+export class OnlineAuthenticationScreenElement extends OnlineAuthenticationScreenElementBase {
+  static get is() {
+    return 'online-authentication-screen-element' as const;
+  }
+
+  static get template(): HTMLTemplateElement {
+    return getTemplate();
+  }
+
+  static get properties(): PolymerElementProperties {
+    return {};
+  }
+
+  // eslint-disable-next-line @typescript-eslint/naming-convention
+  override defaultUIStep() {
+    return DialogMode.LOADING;
+  }
+
+  override get UI_STEPS() {
+    return DialogMode;
+  }
+
+  override ready() {
+    super.ready();
+    this.initializeLoginScreen('OnlineAuthenticationScreen');
+  }
+}
+
+declare global {
+  interface HTMLElementTagNameMap {
+    [OnlineAuthenticationScreenElement.is]: OnlineAuthenticationScreenElement;
+  }
+}
+
+customElements.define(OnlineAuthenticationScreenElement.is, OnlineAuthenticationScreenElement);
diff --git a/chrome/browser/resources/chromeos/login/screens/common/signin_fatal_error.html b/chrome/browser/resources/chromeos/login/screens/common/signin_fatal_error.html
index 20e4f51..ea088a97 100644
--- a/chrome/browser/resources/chromeos/login/screens/common/signin_fatal_error.html
+++ b/chrome/browser/resources/chromeos/login/screens/common/signin_fatal_error.html
@@ -12,17 +12,17 @@
     [[i18nDynamic(locale, 'errorGenericFatalErrorTitle')]]
   </h1>
   <p id="subtitle" slot="subtitle">
-    [[errorSubtitle_]]
+    [[errorSubtitle]]
   </p>
-  <div slot="subtitle" hidden="[[!keyboardHint_]]">[[keyboardHint_]]</div>
-  <div slot="subtitle" hidden="[[!details_]]">[[details_]]</div>
-  <a slot="subtitle" on-click="onHelpLinkClicked_"
-      hidden="[[!helpLinkText_]]" class="oobe-local-link" is="action-link">
-    [[helpLinkText_]]
+  <div slot="subtitle" hidden="[[!keyboardHint]]">[[keyboardHint]]</div>
+  <div slot="subtitle" hidden="[[!details]]">[[details]]</div>
+  <a slot="subtitle" on-click="onHelpLinkClicked"
+      hidden="[[!helpLinkText]]" class="oobe-local-link" is="action-link">
+    [[helpLinkText]]
   </a>
   <div slot="bottom-buttons">
     <oobe-text-button id="actionButton" inverse class="focus-on-show"
-        text-key="[[computeButtonKey_(errorState_)]]" on-tap="onClick_">
+        text-key="[[computeButtonKey(errorState)]]" on-tap="onClick">
     </oobe-text-button>
   </div>
 </oobe-adaptive-dialog>
diff --git a/chrome/browser/resources/chromeos/login/screens/common/signin_fatal_error.js b/chrome/browser/resources/chromeos/login/screens/common/signin_fatal_error.js
deleted file mode 100644
index 23840748..0000000
--- a/chrome/browser/resources/chromeos/login/screens/common/signin_fatal_error.js
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Polymer element for signin fatal error.
- */
-
-import '//resources/js/action_link.js';
-import '//resources/polymer/v3_0/iron-icon/iron-icon.js';
-import '../../components/oobe_icons.html.js';
-import '../../components/common_styles/oobe_common_styles.css.js';
-import '../../components/common_styles/oobe_dialog_host_styles.css.js';
-import '../../components/dialogs/oobe_adaptive_dialog.js';
-import '../../components/buttons/oobe_text_button.js';
-
-import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import {LoginScreenBehavior, LoginScreenBehaviorInterface} from '../../components/behaviors/login_screen_behavior.js';
-import {OobeDialogHostBehavior} from '../../components/behaviors/oobe_dialog_host_behavior.js';
-import {OobeI18nBehavior, OobeI18nBehaviorInterface} from '../../components/behaviors/oobe_i18n_behavior.js';
-import {OOBE_UI_STATE, SCREEN_GAIA_SIGNIN} from '../../components/display_manager_types.js';
-import {OobeTypes} from '../../components/oobe_types.js';
-
-import {getTemplate} from './signin_fatal_error.html.js';
-
-
-/**
- * @constructor
- * @extends {PolymerElement}
- * @implements {LoginScreenBehaviorInterface}
- * @implements {OobeI18nBehaviorInterface}
- */
-const SigninFatalErrorBase = mixinBehaviors(
-    [OobeI18nBehavior, OobeDialogHostBehavior, LoginScreenBehavior],
-    PolymerElement);
-
-/**
- * Data that is passed to the screen during onBeforeShow.
- * @typedef {{
- *   errorState: OobeTypes.FatalErrorCode,
- *   errorText: (string|undefined),
- *   keyboardHint: (string|undefined),
- *   details: (string|undefined),
- *   helpLinkText: (string|undefined),
- *   url: (string|undefined),
- * }}
- */
-let SigninFatalErrorScreenData;
-
-/**
- * @polymer
- */
-class SigninFatalScreen extends SigninFatalErrorBase {
-  static get is() {
-    return 'signin-fatal-error-element';
-  }
-
-  static get template() {
-    return getTemplate();
-  }
-
-
-  static get properties() {
-    return {
-      /**
-       * Subtitle that will be shown to the user describing the error
-       * @private
-       */
-      errorSubtitle_: {
-        type: String,
-        computed: 'computeSubtitle_(locale, errorState_, params_)',
-      },
-
-      /**
-       * Error state from the screen
-       * @type {OobeTypes.FatalErrorCode}
-       * @private
-       */
-      errorState_: {
-        type: Number,
-        value: OobeTypes.FatalErrorCode.UNKNOWN,
-      },
-
-      /**
-       * Additional information that will be used when creating the subtitle.
-       * @type {SigninFatalErrorScreenData}
-       * @private
-       */
-      params_: {
-        type: Object,
-        value: {},
-      },
-
-      /**
-       * @type {(string|undefined)}
-       * @private
-       */
-      keyboardHint_: {
-        type: String,
-      },
-
-      /**
-       * @type {(string|undefined)}
-       * @private
-       */
-      details_: {
-        type: String,
-      },
-
-      /**
-       * @type {(string|undefined)}
-       * @private
-       */
-      helpLinkText_: {
-        type: String,
-      },
-    };
-  }
-
-  ready() {
-    super.ready();
-    this.initializeLoginScreen('SignInFatalErrorScreen');
-  }
-
-  /** Initial UI State for screen */
-  getOobeUIInitialState() {
-    return OOBE_UI_STATE.BLOCKING;
-  }
-
-  /**
-   * Returns the control which should receive initial focus.
-   */
-  get defaultControl() {
-    return /** @type {HTMLElement} */ (this.$.actionButton);
-  }
-
-  /**
-   * Invoked just before being shown. Contains all the data for the screen.
-   * @param {SigninFatalErrorScreenData} data Screen init payload.
-   */
-  onBeforeShow(data) {
-    this.errorState_ = data?.errorState;
-    this.params_ = data;
-    this.keyboardHint_ = this.params_.keyboardHint;
-    this.details_ = this.params_.details;
-    this.helpLinkText_ = this.params_.helpLinkText;
-  }
-
-  onClick_() {
-    this.userActed('screen-dismissed');
-  }
-
-  /**
-   * Generates the key for the button that is shown to the
-   * user based on the error
-   * @param {number} error_state
-   * @private
-   * @suppress {missingProperties} OobeTypes
-   */
-  computeButtonKey_(error_state) {
-    if (this.errorState_ == OobeTypes.FatalErrorCode.INSECURE_CONTENT_BLOCKED) {
-      return 'fatalErrorDoneButton';
-    }
-
-    return 'fatalErrorTryAgainButton';
-  }
-
-  /**
-   * Generates the subtitle that is shown to the
-   * user based on the error
-   * @param {string} locale
-   * @param {OobeTypes.FatalErrorCode} error_state
-   * @param {string} params
-   * @private
-   */
-  computeSubtitle_(locale, error_state, params) {
-    switch (this.errorState_) {
-      case OobeTypes.FatalErrorCode.SCRAPED_PASSWORD_VERIFICATION_FAILURE:
-        return this.i18n('fatalErrorMessageVerificationFailed');
-      case OobeTypes.FatalErrorCode.MISSING_GAIA_INFO:
-        return this.i18n('fatalErrorMessageNoAccountDetails');
-      case OobeTypes.FatalErrorCode.INSECURE_CONTENT_BLOCKED:
-        /**
-         * @suppress {checkTypes} We know that url is already a valid string.
-         * @type {string}
-         */
-        const url = this.params_?.url;
-        return this.i18n('fatalErrorMessageInsecureURL', url);
-      case OobeTypes.FatalErrorCode.CUSTOM:
-        return this.params_.errorText;
-      case OobeTypes.FatalErrorCode.UNKNOWN:
-        return '';
-    }
-  }
-
-  onHelpLinkClicked_() {
-    this.userActed('learn-more');
-  }
-}
-
-customElements.define(SigninFatalScreen.is, SigninFatalScreen);
diff --git a/chrome/browser/resources/chromeos/login/screens/common/signin_fatal_error.ts b/chrome/browser/resources/chromeos/login/screens/common/signin_fatal_error.ts
new file mode 100644
index 0000000..6ae8dbd
--- /dev/null
+++ b/chrome/browser/resources/chromeos/login/screens/common/signin_fatal_error.ts
@@ -0,0 +1,185 @@
+// Copyright 2020 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview Polymer element for signin fatal error.
+ */
+
+import '//resources/js/action_link.js';
+import '//resources/polymer/v3_0/iron-icon/iron-icon.js';
+import '../../components/oobe_icons.html.js';
+import '../../components/common_styles/oobe_common_styles.css.js';
+import '../../components/common_styles/oobe_dialog_host_styles.css.js';
+import '../../components/dialogs/oobe_adaptive_dialog.js';
+import '../../components/buttons/oobe_text_button.js';
+
+import {assert} from '//resources/js/assert.js';
+import {PolymerElementProperties} from '//resources/polymer/v3_0/polymer/interfaces.js';
+import {mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {LoginScreenBehavior, LoginScreenBehaviorInterface} from '../../components/behaviors/login_screen_behavior.js';
+import {OobeDialogHostBehavior, OobeDialogHostBehaviorInterface} from '../../components/behaviors/oobe_dialog_host_behavior.js';
+import {OobeI18nBehavior, OobeI18nBehaviorInterface} from '../../components/behaviors/oobe_i18n_behavior.js';
+import {OOBE_UI_STATE} from '../../components/display_manager_types.js';
+import {OobeTypes} from '../../components/oobe_types.js';
+
+import {getTemplate} from './signin_fatal_error.html.js';
+
+const SigninFatalErrorBase =
+    mixinBehaviors(
+        [OobeI18nBehavior, OobeDialogHostBehavior, LoginScreenBehavior],
+        PolymerElement) as {
+      new (): PolymerElement & OobeI18nBehaviorInterface &
+          OobeDialogHostBehaviorInterface & LoginScreenBehaviorInterface,
+    };
+
+interface SigninFatalErrorScreenData {
+  errorState: OobeTypes.FatalErrorCode;
+  errorText: string|undefined;
+  keyboardHint: string|undefined;
+  details: string|undefined;
+  helpLinkText: string|undefined;
+  url: string|undefined;
+}
+
+export class SigninFatalScreen extends SigninFatalErrorBase {
+  static get is() {
+    return 'signin-fatal-error-element' as const;
+  }
+
+  static get template(): HTMLTemplateElement {
+    return getTemplate();
+  }
+
+  static get properties(): PolymerElementProperties {
+    return {
+      /**
+       * Subtitle that will be shown to the user describing the error
+       */
+      errorSubtitle: {
+        type: String,
+        computed: 'computeSubtitle(locale, errorState, params)',
+      },
+
+      /**
+       * Error state from the screen
+       */
+      errorState: {
+        type: Number,
+        value: OobeTypes.FatalErrorCode.UNKNOWN,
+      },
+
+      /**
+       * Additional information that will be used when creating the subtitle.
+       */
+      params: {
+        type: Object,
+        value: {},
+      },
+
+      keyboardHint: {
+        type: String,
+      },
+
+      details: {
+        type: String,
+      },
+
+      helpLinkText: {
+        type: String,
+      },
+    };
+  }
+
+  private errorSubtitle: string;
+  private errorState: number;
+  private params: SigninFatalErrorScreenData;
+  private keyboardHint: string|undefined;
+  private details: string|undefined;
+  private helpLinkText: string|undefined;
+
+  override ready() {
+    super.ready();
+    this.initializeLoginScreen('SignInFatalErrorScreen');
+  }
+
+  /** Initial UI State for screen */
+  // eslint-disable-next-line @typescript-eslint/naming-convention
+  override getOobeUIInitialState(): OOBE_UI_STATE {
+    return OOBE_UI_STATE.BLOCKING;
+  }
+
+  /**
+   * Returns the control which should receive initial focus.
+   */
+  override get defaultControl(): HTMLElement|null {
+    const actionButton =
+        this.shadowRoot?.querySelector<HTMLElement>('#actionButton');
+    return actionButton ? actionButton : null;
+  }
+
+  /**
+   * Invoked just before being shown. Contains all the data for the screen.
+   * @param data Screen init payload.
+   */
+  override onBeforeShow(data: SigninFatalErrorScreenData) {
+    this.params = data;
+    this.errorState = data.errorState;
+    this.keyboardHint = data.keyboardHint;
+    this.details = data.details;
+    this.helpLinkText = data.helpLinkText;
+  }
+
+  private onClick() {
+    this.userActed('screen-dismissed');
+  }
+
+  /**
+   * Generates the key for the button that is shown to the
+   * user based on the error
+   */
+  private computeButtonKey(errorState: OobeTypes.FatalErrorCode) {
+    if (errorState == OobeTypes.FatalErrorCode.INSECURE_CONTENT_BLOCKED) {
+      return 'fatalErrorDoneButton';
+    }
+
+    return 'fatalErrorTryAgainButton';
+  }
+
+  /**
+   * Generates the subtitle that is shown to the
+   * user based on the error
+   */
+  private computeSubtitle(
+      locale: string, errorState: OobeTypes.FatalErrorCode,
+      params: SigninFatalErrorScreenData): string {
+    switch (errorState) {
+      case OobeTypes.FatalErrorCode.SCRAPED_PASSWORD_VERIFICATION_FAILURE:
+        return this.i18nDynamic(locale, 'fatalErrorMessageVerificationFailed');
+      case OobeTypes.FatalErrorCode.MISSING_GAIA_INFO:
+        return this.i18nDynamic(locale, 'fatalErrorMessageNoAccountDetails');
+      case OobeTypes.FatalErrorCode.INSECURE_CONTENT_BLOCKED:
+        const url = params.url;
+        assert(url);
+        return this.i18nDynamic(locale, 'fatalErrorMessageInsecureURL', url);
+      case OobeTypes.FatalErrorCode.CUSTOM:
+        assert(params.errorText);
+        return params.errorText;
+      default:
+        return '';
+    }
+  }
+
+  private onHelpLinkClicked() {
+    this.userActed('learn-more');
+  }
+}
+
+declare global {
+  interface HTMLElementTagNameMap {
+    [SigninFatalScreen.is]: SigninFatalScreen;
+  }
+}
+
+customElements.define(SigninFatalScreen.is, SigninFatalScreen);
diff --git a/chrome/browser/resources/chromeos/login/screens/common/user_creation.ts b/chrome/browser/resources/chromeos/login/screens/common/user_creation.ts
index 9811b678..216e97e 100644
--- a/chrome/browser/resources/chromeos/login/screens/common/user_creation.ts
+++ b/chrome/browser/resources/chromeos/login/screens/common/user_creation.ts
@@ -194,6 +194,7 @@
       'setIsBackButtonVisible',
       'setTriageStep',
       'setChildSetupStep',
+      'setDefaultStep',
     ];
   }
 
@@ -208,7 +209,6 @@
   onBeforeShow(): void {
     if (this.isOobeSoftwareUpdateEnabled_) {
       this.restoreOobeUIState();
-      this.selectedUserType = '';
       if (!loadTimeData.getBoolean('isOobeFlow')) {
         this.titleKey_ = 'userCreationAddPersonUpdatedTitle';
         this.subtitleKey_ = 'userCreationAddPersonUpdatedSubtitle';
@@ -216,8 +216,6 @@
         this.titleKey_ = 'userCreationUpdatedTitle';
         this.subtitleKey_ = 'userCreationUpdatedSubtitle';
       }
-      this.selectedEnrollTriageMethod = '';
-      this.selectedChildSetupMethod = '';
 
       return;
     }
@@ -232,6 +230,14 @@
     }
   }
 
+  setDefaultStep(): void {
+    Oobe.getInstance().setOobeUIState(OOBE_UI_STATE.USER_CREATION);
+    this.setUIStep(UserCreationUIState.CREATE);
+    this.selectedUserType = UserCreationUserType.SELF;
+    this.selectedEnrollTriageMethod = '';
+    this.selectedChildSetupMethod = '';
+  }
+
   override ready(): void {
     super.ready();
     this.initializeLoginScreen('UserCreationScreen');
diff --git a/chrome/browser/resources/settings/people_page/OWNERS b/chrome/browser/resources/settings/people_page/OWNERS
new file mode 100644
index 0000000..0edfe1c
--- /dev/null
+++ b/chrome/browser/resources/settings/people_page/OWNERS
@@ -0,0 +1,2 @@
+file://components/signin/OWNERS
+file://components/sync/OWNERS
diff --git a/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_app.ts b/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_app.ts
index be8b853..12ea4878 100644
--- a/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_app.ts
+++ b/chrome/browser/resources/signin/sync_confirmation/sync_confirmation_app.ts
@@ -43,10 +43,8 @@
 interface AccountInfo {
   src: string;
   showEnterpriseBadge: boolean;
-  screenMode: ScreenMode;
 }
 
-
 const SyncConfirmationAppElementBase =
     WebUiListenerMixin(I18nMixin(PolymerElement));
 
@@ -106,9 +104,7 @@
       /** Determines the screen mode. */
       screenMode_: {
         type: ScreenMode,
-        value() {
-          return loadTimeData.getInteger('screenMode') as ScreenMode;
-        },
+        value: ScreenMode.PENDING,
       },
     };
   }
@@ -129,11 +125,9 @@
 
     this.addWebUiListener(
         'account-info-changed', this.handleAccountInfoChanged_.bind(this));
+    this.addWebUiListener(
+        'screen-mode-changed', this.handleScreenModeChanged_.bind(this));
     this.syncConfirmationBrowserProxy_.requestAccountInfo();
-
-    setTimeout(() => {
-      this.defaultToRestrictedModeIfStillPending();
-    }, /*delay in ms=*/ 2000);
   }
 
   private onConfirm_(e: Event) {
@@ -193,17 +187,10 @@
   private handleAccountInfoChanged_(accountInfo: AccountInfo) {
     this.accountImageSrc_ = accountInfo.src;
     this.showEnterpriseBadge_ = accountInfo.showEnterpriseBadge;
-
-    // Only allow this change once, from PENDING mode to (UN)RESTRICTED.
-    if (this.screenMode_ === ScreenMode.PENDING) {
-      this.screenMode_ = accountInfo.screenMode as ScreenMode;
-    }
   }
 
-  private defaultToRestrictedModeIfStillPending() {
-    if (this.screenMode_ === ScreenMode.PENDING) {
-      this.screenMode_ = ScreenMode.RESTRICTED;
-    }
+  private handleScreenModeChanged_(screenMode: ScreenMode) {
+    this.screenMode_ = screenMode;
   }
 
   private getConfirmButtonClass_(screenMode: ScreenMode) {
diff --git a/chrome/browser/safe_browsing/tailored_security/chrome_tailored_security_service_unittest.cc b/chrome/browser/safe_browsing/tailored_security/chrome_tailored_security_service_unittest.cc
index f0a846d..70b0bb8 100644
--- a/chrome/browser/safe_browsing/tailored_security/chrome_tailored_security_service_unittest.cc
+++ b/chrome/browser/safe_browsing/tailored_security/chrome_tailored_security_service_unittest.cc
@@ -153,7 +153,7 @@
     identity_test_env_adaptor_ =
         std::make_unique<IdentityTestEnvironmentProfileAdaptor>(profile_);
     GetIdentityTestEnv()->SetTestURLLoaderFactory(&test_url_loader_factory_);
-    // TODO(crbug.com/1466447): `ConsentLevel::kSync` is deprecated and should
+    // TODO(crbug.com/40067771): `ConsentLevel::kSync` is deprecated and should
     // be removed. See `ConsentLevel::kSync` documentation for details.
     GetIdentityTestEnv()->MakePrimaryAccountAvailable(
         "test@foo.com", signin::ConsentLevel::kSync);
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.cc b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.cc
index 9a5f4e3..5e12c924 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.cc
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.cc
@@ -40,11 +40,13 @@
     content::StoragePartition* storage_partition,
     network::NetworkConnectionTracker* network_connection_tracker,
     const bound_session_credentials::BoundSessionParams& bound_session_params,
-    Delegate* delegate)
+    Delegate* delegate,
+    bool is_off_the_record_profile)
     : BoundSessionCookieController(bound_session_params, delegate),
       key_service_(key_service),
       storage_partition_(storage_partition),
-      network_connection_tracker_(network_connection_tracker) {
+      network_connection_tracker_(network_connection_tracker),
+      is_off_the_record_profile_(is_off_the_record_profile) {
   CHECK(!bound_session_params.wrapped_key().empty());
   base::span<const uint8_t> wrapped_key =
       base::as_bytes(base::make_span(bound_session_params.wrapped_key()));
@@ -176,7 +178,8 @@
   return refresh_cookie_fetcher_factory_for_testing_.is_null()
              ? std::make_unique<BoundSessionRefreshCookieFetcherImpl>(
                    storage_partition_->GetURLLoaderFactoryForBrowserProcess(),
-                   *session_binding_helper_, url_, std::move(cookie_names))
+                   *session_binding_helper_, url_, std::move(cookie_names),
+                   is_off_the_record_profile_)
              : refresh_cookie_fetcher_factory_for_testing_.Run(
                    storage_partition_->GetCookieManagerForBrowserProcess(),
                    url_, std::move(cookie_names));
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.h b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.h
index a12a4c2b..9acfa94 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.h
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.h
@@ -39,7 +39,8 @@
       content::StoragePartition* storage_partition,
       network::NetworkConnectionTracker* network_connection_tracker,
       const bound_session_credentials::BoundSessionParams& bound_session_params,
-      Delegate* delegate);
+      Delegate* delegate,
+      bool is_off_the_record_profile);
 
   ~BoundSessionCookieControllerImpl() override;
 
@@ -97,6 +98,8 @@
   const raw_ref<unexportable_keys::UnexportableKeyService> key_service_;
   const raw_ptr<content::StoragePartition> storage_partition_;
   const raw_ptr<network::NetworkConnectionTracker> network_connection_tracker_;
+  const bool is_off_the_record_profile_;
+
   std::vector<std::unique_ptr<BoundSessionCookieObserver>>
       bound_cookies_observers_;
 
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl_unittest.cc b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl_unittest.cc
index 8637068..1aa861d 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl_unittest.cc
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl_unittest.cc
@@ -244,7 +244,8 @@
     bound_session_cookie_controller_ =
         std::make_unique<BoundSessionCookieControllerImpl>(
             unexportable_key_service_, &storage_partition_,
-            content::GetNetworkConnectionTracker(), bound_session_params, this);
+            content::GetNetworkConnectionTracker(), bound_session_params, this,
+            /*is_off_the_record_profile=*/false);
     bound_session_cookie_controller_
         ->set_refresh_cookie_fetcher_factory_for_testing(
             base::BindRepeating(&BoundSessionCookieControllerImplTest::
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_factory.cc b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_factory.cc
index 0024a6e..a5d1f38 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_factory.cc
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_factory.cc
@@ -41,7 +41,8 @@
           "BoundSessionCookieRefreshService",
           ProfileSelections::Builder()
               .WithRegular(ProfileSelection::kOwnInstance)
-              .WithGuest(ProfileSelection::kOwnInstance)
+              // Only an OTR profile is used for browsing in the Guest Session.
+              .WithGuest(ProfileSelection::kOffTheRecordOnly)
               .Build()) {
   DependsOn(UnexportableKeyServiceFactory::GetInstance());
   DependsOn(AccountConsistencyModeManagerFactory::GetInstance());
@@ -85,7 +86,8 @@
               *key_service,
               BoundSessionParamsStorage::CreateForProfile(*profile),
               profile->GetDefaultStoragePartition(),
-              content::GetNetworkConnectionTracker());
+              content::GetNetworkConnectionTracker(),
+              profile->IsOffTheRecord());
   bound_session_cookie_refresh_service->Initialize();
   return bound_session_cookie_refresh_service;
 }
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl.cc b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl.cc
index c5ea0f8..42e5aaa 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl.cc
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl.cc
@@ -30,11 +30,13 @@
     unexportable_keys::UnexportableKeyService& key_service,
     std::unique_ptr<BoundSessionParamsStorage> session_params_storage,
     content::StoragePartition* storage_partition,
-    network::NetworkConnectionTracker* network_connection_tracker)
+    network::NetworkConnectionTracker* network_connection_tracker,
+    bool is_off_the_record_profile)
     : key_service_(key_service),
       session_params_storage_(std::move(session_params_storage)),
       storage_partition_(storage_partition),
-      network_connection_tracker_(network_connection_tracker) {
+      network_connection_tracker_(network_connection_tracker),
+      is_off_the_record_profile_(is_off_the_record_profile) {
   CHECK(session_params_storage_);
   CHECK(storage_partition_);
   data_removal_observation_.Observe(storage_partition_);
@@ -148,7 +150,7 @@
       std::make_unique<BoundSessionRegistrationFetcherImpl>(
           std::move(registration_params),
           storage_partition_->GetURLLoaderFactoryForBrowserProcess(),
-          key_service_.get());
+          key_service_.get(), is_off_the_record_profile_);
   // `base::Unretained(this)` is safe here because `this` owns the fetcher via
   // `active_registration_requests_`
   active_registration_request_->Start(base::BindOnce(
@@ -226,18 +228,21 @@
 
 std::unique_ptr<BoundSessionCookieController>
 BoundSessionCookieRefreshServiceImpl::CreateBoundSessionCookieController(
-    const bound_session_credentials::BoundSessionParams& bound_session_params) {
+    const bound_session_credentials::BoundSessionParams& bound_session_params,
+    bool is_off_the_record_profile) {
   return controller_factory_for_testing_.is_null()
              ? std::make_unique<BoundSessionCookieControllerImpl>(
                    key_service_.get(), storage_partition_,
-                   network_connection_tracker_, bound_session_params, this)
+                   network_connection_tracker_, bound_session_params, this,
+                   is_off_the_record_profile)
              : controller_factory_for_testing_.Run(bound_session_params, this);
 }
 
 void BoundSessionCookieRefreshServiceImpl::InitializeBoundSession(
     const bound_session_credentials::BoundSessionParams& bound_session_params) {
   CHECK(!cookie_controller_);
-  cookie_controller_ = CreateBoundSessionCookieController(bound_session_params);
+  cookie_controller_ = CreateBoundSessionCookieController(
+      bound_session_params, is_off_the_record_profile_);
   cookie_controller_->Initialize();
   UpdateAllRenderers();
 }
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl.h b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl.h
index d6c6198..e88da70 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl.h
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl.h
@@ -51,7 +51,8 @@
       unexportable_keys::UnexportableKeyService& key_service,
       std::unique_ptr<BoundSessionParamsStorage> session_params_storage,
       content::StoragePartition* storage_partition,
-      network::NetworkConnectionTracker* network_connection_tracker);
+      network::NetworkConnectionTracker* network_connection_tracker,
+      bool is_off_the_record_profile);
 
   ~BoundSessionCookieRefreshServiceImpl() override;
 
@@ -118,8 +119,8 @@
 
   std::unique_ptr<BoundSessionCookieController>
   CreateBoundSessionCookieController(
-      const bound_session_credentials::BoundSessionParams&
-          bound_session_params);
+      const bound_session_credentials::BoundSessionParams& bound_session_params,
+      bool is_off_the_record_profile);
   void InitializeBoundSession(
       const bound_session_credentials::BoundSessionParams&
           bound_session_params);
@@ -139,6 +140,9 @@
   const std::unique_ptr<BoundSessionParamsStorage> session_params_storage_;
   const raw_ptr<content::StoragePartition> storage_partition_;
   const raw_ptr<network::NetworkConnectionTracker> network_connection_tracker_;
+  // Required to attach X-Client-Data header to session registration and cookie
+  // rotation requests for GWS-visible Finch experiment.
+  const bool is_off_the_record_profile_;
   BoundSessionCookieControllerFactoryForTesting controller_factory_for_testing_;
   RendererBoundSessionThrottlerParamsUpdaterDelegate renderer_updater_;
   base::RepeatingClosure session_updated_callback_for_testing_;
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl_unittest.cc b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl_unittest.cc
index 42e15b9..2510c2ab 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl_unittest.cc
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl_unittest.cc
@@ -296,7 +296,8 @@
         std::make_unique<BoundSessionCookieRefreshServiceImpl>(
             fake_unexportable_key_service_,
             BoundSessionParamsStorage::CreatePrefsStorageForTesting(prefs_),
-            &storage_partition_, content::GetNetworkConnectionTracker());
+            &storage_partition_, content::GetNetworkConnectionTracker(),
+            /*is_off_the_record_profile=*/false);
     cookie_refresh_service->set_controller_factory_for_testing(
         base::BindRepeating(&BoundSessionCookieRefreshServiceImplTest::
                                 CreateBoundSessionCookieController,
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher_impl.cc b/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher_impl.cc
index 2568166..445eda28 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher_impl.cc
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher_impl.cc
@@ -16,6 +16,7 @@
 #include "base/timer/elapsed_timer.h"
 #include "base/trace_event/typed_macros.h"
 #include "chrome/browser/signin/bound_session_credentials/session_binding_helper.h"
+#include "components/variations/net/variations_http_headers.h"
 #include "google_apis/gaia/gaia_urls.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "net/cookies/canonical_cookie.h"
@@ -52,11 +53,13 @@
     scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
     SessionBindingHelper& session_binding_helper,
     const GURL& cookie_url,
-    base::flat_set<std::string> cookie_names)
+    base::flat_set<std::string> cookie_names,
+    bool is_off_the_record_profile)
     : url_loader_factory_(std::move(url_loader_factory)),
       session_binding_helper_(session_binding_helper),
       expected_cookie_domain_(cookie_url),
-      expected_cookie_names_(std::move(cookie_names)) {}
+      expected_cookie_names_(std::move(cookie_names)),
+      is_off_the_record_profile_(is_off_the_record_profile) {}
 
 BoundSessionRefreshCookieFetcherImpl::~BoundSessionRefreshCookieFetcherImpl() =
     default;
@@ -144,7 +147,11 @@
   request->trusted_params->cookie_observer = std::move(remote);
 
   url_loader_ =
-      network::SimpleURLLoader::Create(std::move(request), traffic_annotation);
+      variations::CreateSimpleURLLoaderWithVariationsHeaderUnknownSignedIn(
+          std::move(request),
+          is_off_the_record_profile_ ? variations::InIncognito::kYes
+                                     : variations::InIncognito::kNo,
+          traffic_annotation);
   url_loader_->SetRetryOptions(
       3, network::SimpleURLLoader::RETRY_ON_NETWORK_CHANGE);
   // TODO(b/273920907): Download the response body to support in refresh DBSC
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher_impl.h b/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher_impl.h
index bfbf97f..3a3b5d58a 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher_impl.h
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher_impl.h
@@ -33,7 +33,8 @@
       scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
       SessionBindingHelper& session_binding_helper,
       const GURL& cookie_url,
-      base::flat_set<std::string> cookie_names);
+      base::flat_set<std::string> cookie_names,
+      bool is_off_the_record_profile);
   ~BoundSessionRefreshCookieFetcherImpl() override;
 
   // BoundSessionRefreshCookieFetcher:
@@ -88,6 +89,10 @@
   const GURL expected_cookie_domain_;
   const base::flat_set<std::string> expected_cookie_names_;
 
+  // Required to attach X-Client-Data header to cookie rotation request for
+  // GWS-visible Finch experiment.
+  const bool is_off_the_record_profile_;
+
   RefreshCookieCompleteCallback callback_;
 
   bool expected_cookies_set_ = false;
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher_impl_unittest.cc b/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher_impl_unittest.cc
index 7f6fac3..f3722fb 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher_impl_unittest.cc
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_refresh_cookie_fetcher_impl_unittest.cc
@@ -28,6 +28,7 @@
 #include "components/unexportable_keys/unexportable_key_id.h"
 #include "components/unexportable_keys/unexportable_key_service_impl.h"
 #include "components/unexportable_keys/unexportable_key_task_manager.h"
+#include "components/variations/scoped_variations_ids_provider.h"
 #include "crypto/scoped_mock_unexportable_key_provider.h"
 #include "net/base/net_errors.h"
 #include "net/cookies/canonical_cookie.h"
@@ -103,7 +104,8 @@
     fetcher_ = std::make_unique<BoundSessionRefreshCookieFetcherImpl>(
         test_url_loader_factory_.GetSafeWeakWrapper(), *session_binding_helper_,
         kGairaUrl,
-        base::flat_set<std::string>{k1PSIDTSCookieName, k3PSIDTSCookieName});
+        base::flat_set<std::string>{k1PSIDTSCookieName, k3PSIDTSCookieName},
+        /*is_off_the_record_profile=*/false);
     UpdateCookieList();
   }
 
@@ -187,6 +189,8 @@
 
   base::test::TaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+  variations::ScopedVariationsIdsProvider scoped_variations_ids_provider_{
+      variations::VariationsIdsProvider::Mode::kUseSignedInState};
   crypto::ScopedMockUnexportableKeyProvider scoped_key_provider_;
   unexportable_keys::UnexportableKeyTaskManager unexportable_key_task_manager_;
   unexportable_keys::UnexportableKeyServiceImpl unexportable_key_service_;
@@ -484,7 +488,8 @@
   fetcher_ = std::make_unique<BoundSessionRefreshCookieFetcherImpl>(
       test_url_loader_factory_.GetSafeWeakWrapper(), *session_binding_helper_,
       kGairaUrl,
-      base::flat_set<std::string>{k1PSIDTSCookieName, k3PSIDTSCookieName});
+      base::flat_set<std::string>{k1PSIDTSCookieName, k3PSIDTSCookieName},
+      /*is_off_the_record_profile_=*/false);
   RefreshTestFuture future;
   fetcher_->Start(future.GetCallback());
 
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.cc b/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.cc
index cf80ae2..1646329 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.cc
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.cc
@@ -18,6 +18,7 @@
 #include "components/unexportable_keys/service_error.h"
 #include "components/unexportable_keys/unexportable_key_id.h"
 #include "components/unexportable_keys/unexportable_key_service.h"
+#include "components/variations/net/variations_http_headers.h"
 #include "google_apis/gaia/gaia_urls.h"
 #include "net/base/schemeful_site.h"
 #include "net/http/http_response_headers.h"
@@ -49,9 +50,11 @@
 BoundSessionRegistrationFetcherImpl::BoundSessionRegistrationFetcherImpl(
     BoundSessionRegistrationFetcherParam registration_params,
     scoped_refptr<network::SharedURLLoaderFactory> loader_factory,
-    unexportable_keys::UnexportableKeyService& key_service)
+    unexportable_keys::UnexportableKeyService& key_service,
+    bool is_off_the_record_profile)
     : registration_params_(std::move(registration_params)),
       key_service_(key_service),
+      is_off_the_record_profile_(is_off_the_record_profile),
       url_loader_factory_(std::move(loader_factory)) {}
 
 BoundSessionRegistrationFetcherImpl::~BoundSessionRegistrationFetcherImpl() =
@@ -216,8 +219,11 @@
 
   std::string content_type = "application/jwt";
 
-  url_loader_ =
-      network::SimpleURLLoader::Create(std::move(request), traffic_annotation);
+  url_loader_ = CreateSimpleURLLoaderWithVariationsHeaderUnknownSignedIn(
+      std::move(request),
+      is_off_the_record_profile_ ? variations::InIncognito::kYes
+                                 : variations::InIncognito::kNo,
+      traffic_annotation);
   url_loader_->AttachStringForUpload(registration_token, content_type);
   url_loader_->SetRetryOptions(
       3, network::SimpleURLLoader::RETRY_ON_NETWORK_CHANGE);
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.h b/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.h
index 191c79a..97a508c 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.h
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl.h
@@ -53,7 +53,8 @@
   BoundSessionRegistrationFetcherImpl(
       BoundSessionRegistrationFetcherParam registration_params,
       scoped_refptr<network::SharedURLLoaderFactory> loader_factory,
-      unexportable_keys::UnexportableKeyService& key_service);
+      unexportable_keys::UnexportableKeyService& key_service,
+      bool is_off_the_record_profile);
 
   BoundSessionRegistrationFetcherImpl(
       BoundSessionRegistrationFetcherImpl&& other) = delete;
@@ -99,6 +100,7 @@
 
   BoundSessionRegistrationFetcherParam registration_params_;
   const raw_ref<unexportable_keys::UnexportableKeyService> key_service_;
+  const bool is_off_the_record_profile_;
   std::string wrapped_key_str_;
 
   // Non-null after a fetch has started.
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl_unittest.cc b/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl_unittest.cc
index 0719658..2fd7140 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl_unittest.cc
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_registration_fetcher_impl_unittest.cc
@@ -23,6 +23,7 @@
 #include "components/unexportable_keys/unexportable_key_service.h"
 #include "components/unexportable_keys/unexportable_key_service_impl.h"
 #include "components/unexportable_keys/unexportable_key_task_manager.h"
+#include "components/variations/scoped_variations_ids_provider.h"
 #include "crypto/scoped_mock_unexportable_key_provider.h"
 #include "crypto/signature_verifier.h"
 #include "net/http/http_response_headers.h"
@@ -184,7 +185,7 @@
             kRegistrationUrl, CreateAlgArray(), std::string(kChallenge));
     return std::make_unique<BoundSessionRegistrationFetcherImpl>(
         std::move(params), url_loader_factory_.GetSafeWeakWrapper(),
-        unexportable_key_service());
+        unexportable_key_service(), /*is_off_the_record_profile=*/false);
   }
 
   void DisableKeyProvider() {
@@ -224,6 +225,8 @@
       base::test::TaskEnvironment::ThreadPoolExecutionMode::
           QUEUED};  // QUEUED - tasks don't run until `RunUntilIdle()` is
                     // called.
+  variations::ScopedVariationsIdsProvider scoped_variations_ids_provider_{
+      variations::VariationsIdsProvider::Mode::kUseSignedInState};
   unexportable_keys::UnexportableKeyTaskManager task_manager_;
   unexportable_keys::UnexportableKeyServiceImpl unexportable_key_service_;
   // Provides a mock key provider by default.
diff --git a/chrome/browser/signin/bound_session_credentials/unexportable_key_service_factory.cc b/chrome/browser/signin/bound_session_credentials/unexportable_key_service_factory.cc
index 7567023e..9ed6703 100644
--- a/chrome/browser/signin/bound_session_credentials/unexportable_key_service_factory.cc
+++ b/chrome/browser/signin/bound_session_credentials/unexportable_key_service_factory.cc
@@ -46,7 +46,8 @@
           "UnexportableKeyService",
           ProfileSelections::Builder()
               .WithRegular(ProfileSelection::kOwnInstance)
-              .WithGuest(ProfileSelection::kOwnInstance)
+              // Only an OTR profile is used for browsing in the Guest Session.
+              .WithGuest(ProfileSelection::kOffTheRecordOnly)
               .WithSystem(ProfileSelection::kNone)
               .Build()) {}
 
diff --git a/chrome/browser/supervised_user/extensions_interactive_uitest.cc b/chrome/browser/supervised_user/extensions_interactive_uitest.cc
new file mode 100644
index 0000000..559a129
--- /dev/null
+++ b/chrome/browser/supervised_user/extensions_interactive_uitest.cc
@@ -0,0 +1,247 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+#include <string_view>
+#include <tuple>
+
+#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/types/strong_alias.h"
+#include "chrome/browser/extensions/chrome_test_extension_loader.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/supervised_user/supervised_user_test_util.h"
+#include "chrome/browser/ui/extensions/extensions_dialogs.h"
+#include "chrome/browser/ui/supervised_user/parent_permission_dialog.h"
+#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
+#include "chrome/test/interaction/interactive_browser_test.h"
+#include "chrome/test/supervised_user/family_live_test.h"
+#include "chrome/test/supervised_user/family_member.h"
+#include "components/prefs/pref_service.h"
+#include "components/supervised_user/core/common/pref_names.h"
+#include "content/public/test/browser_test.h"
+#include "extensions/test/test_extension_dir.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/interaction/element_identifier.h"
+
+namespace supervised_user {
+namespace {
+
+static constexpr std::string_view kChromeManageExternsionsUrl =
+    "chrome://extensions/";
+
+// State of a Family Link switch
+enum class FamilyLinkSwitchState : int {
+  kEnabled = 0,
+  kDisabled,
+};
+
+constexpr const char* kFamilyLinkSwitchStateToString[2] = {"true", "false"};
+
+using BoolPermissionsStateObserver = ui::test::PollingStateObserver<bool>;
+
+DEFINE_LOCAL_STATE_IDENTIFIER_VALUE(BoolPermissionsStateObserver,
+                                    kBoolPermissionsPreferenceObserver);
+
+// TODO(b/321242366): Consider moving to helper class.
+// Checks if a page title matches the given regexp in ecma script dialect.
+InteractiveBrowserTestApi::StateChange PageWithMatchingTitle(
+    std::string_view title_regexp) {
+  DEFINE_LOCAL_CUSTOM_ELEMENT_EVENT_TYPE(kStateChange);
+  InteractiveBrowserTestApi::StateChange state_change;
+  state_change.type =
+      InteractiveBrowserTestApi::StateChange::Type::kConditionTrue;
+  state_change.event = kStateChange;
+  state_change.test_function = base::StringPrintf(R"js(
+    () => /%s/.test(document.title)
+  )js",
+                                                  title_regexp.data());
+  state_change.continue_across_navigation = true;
+  return state_change;
+}
+
+// Test the behavior of handling extensions for supervised users when parental
+// controls apply on extensions (by default on Chrome OS, depending on the
+// kEnableExtensionsPermissionsForSupervisedUsersOnDesktop feature on
+// Win/Mac/Linux).
+class SupervisedUserExtensionsParentalControlsUiTest
+    : public InteractiveBrowserTestT<FamilyLiveTest>,
+      public testing::WithParamInterface<
+          std::tuple<supervised_user::FamilyIdentifier,
+                     FamilyLinkSwitchState>> {
+ public:
+  SupervisedUserExtensionsParentalControlsUiTest()
+      : InteractiveBrowserTestT<FamilyLiveTest>(
+            /*family_identifier=*/std::get<0>(GetParam()),
+            /*extra_enabled_hosts=*/std::vector<std::string>()) {
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
+    // Enable extensions parental controls.
+    feature_list_.InitAndEnableFeature(
+        supervised_user::
+            kEnableExtensionsPermissionsForSupervisedUsersOnDesktop);
+#endif
+  }
+
+ protected:
+  // Parenr navigates to FL control page and waits for it to load.
+  auto ParentOpensControlPage(ui::ElementIdentifier kParentTab,
+                              const GURL& gurl) {
+    return Steps(NavigateWebContents(kParentTab, gurl),
+                 WaitForWebContentsReady(kParentTab, gurl));
+  }
+
+  // Child tries to enable a disabled extension (which is pending parent
+  // approval) by clicking at the extension's toggle.
+  auto ChildClicksEnableExtension(ui::ElementIdentifier kChildTab) {
+    return Steps(ExecuteJs(kChildTab,
+                           R"js(
+                () => {
+                  const view_manager =
+                    document.querySelector("extensions-manager").shadowRoot
+                      .querySelector("#container").querySelector("#viewManager");
+                  if (!view_manager) {
+                    throw Error("Path to view_manager element is invalid.");
+                  }
+                  const container = view_manager.querySelector("#items-list")
+                    .shadowRoot.querySelector("#container");
+                  if (!container) {
+                    throw Error("Path to container element is invalid.");
+                  }
+                  const extn = container.querySelectorAll("extensions-item")[0];
+                  if (!extn) {
+                    throw Error("Path to extension element is invalid.");
+                  }
+                  const toggle = extn.shadowRoot.querySelector("#enableToggle");
+                  if (!toggle) {
+                    throw Error("Path to extension toggle is invalid.");
+                  }
+                  toggle.click();
+                }
+              )js"));
+  }
+
+  // Installs programmatically (not through the UI) an extension for the given
+  // user.
+  void InstallExtension(const std::string_view& name, Profile* profile) {
+    extensions::TestExtensionDir extension_dir;
+    extension_dir.WriteManifest(base::StringPrintf(
+        R"({
+            "name": "%s",
+            "manifest_version": 3,
+            "version": "0.1"
+          })",
+        name.data()));
+
+    extensions::ChromeTestExtensionLoader extension_loader(profile);
+    extension_loader.set_ignore_manifest_warnings(true);
+    extension_loader.LoadExtension(extension_dir.Pack());
+  }
+
+  // Parent toggles the "Permissions" switch in FL, if it does not have
+  // the desired value.
+  auto ParentSetsPermissionsSwitch(ui::ElementIdentifier kParentTab,
+                                   FamilyLinkSwitchState target_state) {
+    return Steps(ExecuteJs(
+        kParentTab,
+        base::StringPrintf(
+            R"js(
+          () => {
+            const button = document.querySelector('[aria-label="Toggle permissions for sites, apps and extensions"]')
+            if (!button) {
+              throw Error("'Permissions' toggle not found.");
+            }
+            if (button.ariaChecked != "%s") {
+              button.click();
+            }
+          }
+        )js",
+            kFamilyLinkSwitchStateToString[static_cast<int>(target_state)])));
+  }
+
+  // Polls the Permissions preference value in Chrome.
+  auto PollPermissionsPreference(
+      ui::test::StateIdentifier<BoolPermissionsStateObserver>
+          permission_preference_observer) {
+    return Steps(PollState(permission_preference_observer, [this]() {
+      return child().browser()->profile()->GetPrefs()->GetBoolean(
+          prefs::kSupervisedUserExtensionsMayRequestPermissions);
+    }));
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_P(SupervisedUserExtensionsParentalControlsUiTest,
+                       ChildTogglesExtensionMissingParentApproval) {
+  DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kChildElementId);
+  DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kParentControlsTab);
+  int child_tab_index = 0;
+  int parent_tab_index = 0;
+  auto switch_target_state = std::get<1>(GetParam());
+  TurnOnSyncFor(head_of_household());
+  TurnOnSyncFor(child());
+
+  // Depending on the "Permissions" switch's value either the "Parent Approval
+  // Dialog" (switch ON) or the "Extensions Blocked by Parent" error message
+  // will appear at the end.
+  auto target_ui_element_id =
+      switch_target_state == FamilyLinkSwitchState::kEnabled
+          ? ParentPermissionDialog::kDialogViewIdForTesting
+          : extensions::kParentBlockedDialogMessage;
+
+  RunTestSequence(Steps(
+      // Parent sets the FL switch "Permissions" to ON.
+      // TODO(b/303401498): Use chrome test state seeding rpc.
+      InstrumentTab(kParentControlsTab, parent_tab_index,
+                    head_of_household().browser()),
+
+      ParentOpensControlPage(kParentControlsTab,
+                             head_of_household().GetPermissionsUrlFor(child())),
+      PollPermissionsPreference(kBoolPermissionsPreferenceObserver),
+      ParentSetsPermissionsSwitch(kParentControlsTab,
+                                  FamilyLinkSwitchState::kEnabled),
+      WaitForState(kBoolPermissionsPreferenceObserver, true)));
+
+  RunTestSequence(InAnyContext(Steps(
+      // Install programmatically an extension. It is pending parent approval.
+      Do([this]() -> void {
+        InstallExtension("A Extension", child().browser()->profile());
+      }),
+      // Parent sets the FL Permissions switch.
+      ParentSetsPermissionsSwitch(kParentControlsTab, switch_target_state),
+      WaitForState(kBoolPermissionsPreferenceObserver,
+                   switch_target_state == FamilyLinkSwitchState::kEnabled
+                       ? true
+                       : false),
+
+      // Child navigates to the extensions page and tries to enable the
+      // extension.
+      InstrumentTab(kChildElementId, child_tab_index, child().browser()),
+      NavigateWebContents(kChildElementId, GURL(kChromeManageExternsionsUrl)),
+      WaitForStateChange(kChildElementId, PageWithMatchingTitle("Extensions")),
+      ChildClicksEnableExtension(kChildElementId),
+      // The parent approval dialog or the Blocked extensions error message
+      // appears.
+      WaitForShow(target_ui_element_id))));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    All,
+    SupervisedUserExtensionsParentalControlsUiTest,
+    testing::Combine(
+        testing::Values(supervised_user::FamilyIdentifier("FAMILY_DMA_ALL")),
+        testing::Values(FamilyLinkSwitchState::kEnabled,
+                        FamilyLinkSwitchState::kDisabled)),
+    [](const auto& info) {
+      return std::string(std::get<0>(info.param)->data()) +
+             std::string(
+                 (std::get<1>(info.param) == FamilyLinkSwitchState::kEnabled
+                      ? "WithPermissionsSwitchOn"
+                      : "WithPermissionsSwitchOff"));
+    });
+}  // namespace
+}  // namespace supervised_user
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SyncConsentFragmentBase.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SyncConsentFragmentBase.java
index 7ba3b70..03a90a7f6 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SyncConsentFragmentBase.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SyncConsentFragmentBase.java
@@ -500,8 +500,6 @@
      * "Add account" button in this case.
      */
     private void setHasAccounts(boolean hasAccounts) {
-        assert mSigninView != null;
-
         if (hasAccounts) {
             final boolean hideAccountPicker =
                     mIsSignedInWithoutSync
@@ -805,7 +803,7 @@
                 AccountUtils.getCoreAccountInfosIfFulfilledOrEmpty(
                         mAccountManagerFacade.getCoreAccountInfos()));
 
-        if (mSigninView != null) mSigninView.startAnimations();
+        mSigninView.startAnimations();
         if (mDeviceLockReady) {
             mDeviceLockPageCallback.run();
         }
@@ -816,7 +814,7 @@
         super.onPause();
         mAccountManagerFacade.removeObserver(this);
 
-        if (mSigninView != null) mSigninView.stopAnimations();
+        mSigninView.stopAnimations();
     }
 
     private void selectAccount(String accountEmail) {
diff --git a/chrome/browser/ui/extensions/extensions_dialogs.h b/chrome/browser/ui/extensions/extensions_dialogs.h
index 88db1915..296f8ba 100644
--- a/chrome/browser/ui/extensions/extensions_dialogs.h
+++ b/chrome/browser/ui/extensions/extensions_dialogs.h
@@ -14,6 +14,7 @@
 #include "components/supervised_user/core/common/buildflags.h"
 #include "extensions/buildflags/buildflags.h"
 #include "extensions/common/extension_id.h"
+#include "ui/base/interaction/element_identifier.h"
 #include "ui/base/ui_base_types.h"
 #include "ui/gfx/native_widget_types.h"
 
@@ -93,6 +94,8 @@
   kEnable,  // The user attempted to enable the extension.
 };
 
+DECLARE_ELEMENT_IDENTIFIER_VALUE(kParentBlockedDialogMessage);
+
 // Displays a dialog to notify the user that the extension installation is
 // blocked by a parent
 void ShowExtensionInstallBlockedByParentDialog(
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
index 4bf9ef2..cc52f6e 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
@@ -673,6 +673,11 @@
       GetState() == password_manager::ui::NOTIFY_RECEIVED_SHARED_CREDENTIALS) {
     passwords_data_.TransitionToState(password_manager::ui::MANAGE_STATE);
     update_icon = true;
+  } else if (GetState() ==
+             password_manager::ui::PASSWORD_STORE_CHANGED_BUBBLE_STATE) {
+    passwords_data_.TransitionToState(
+        password_manager::ui::PENDING_PASSWORD_STATE);
+    update_icon = true;
   }
   if (update_icon)
     UpdateBubbleAndIconVisibility();
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
index c583cc6..ab9bdea 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
@@ -1037,6 +1037,30 @@
   ExpectIconAndControllerStateIs(password_manager::ui::PENDING_PASSWORD_STATE);
 }
 
+TEST_F(ManagePasswordsUIControllerTest,
+       DefaultStoreChangedBubbleClosedAndKeyIconPressedManually) {
+  std::vector<raw_ptr<const PasswordForm, VectorExperimental>> best_matches;
+  auto test_form_manager = CreateFormManagerWithBestMatches(&best_matches);
+  EXPECT_CALL(*client().GetPasswordFeatureManager(),
+              ShouldChangeDefaultPasswordStore)
+      .WillOnce(Return(true));
+  EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility()).Times(2);
+
+  // Change the pwm ui state to PASSWORD_STORE_CHANGED_BUBBLE_STATE.
+  controller()->OnPasswordSubmitted(std::move(test_form_manager));
+  EXPECT_TRUE(controller()->opened_automatic_bubble());
+  EXPECT_EQ(url::Origin::Create(test_local_form().url),
+            controller()->GetOrigin());
+  ExpectIconAndControllerStateIs(
+      password_manager::ui::PASSWORD_STORE_CHANGED_BUBBLE_STATE);
+
+  controller()->OnBubbleHidden();
+  EXPECT_FALSE(controller()->opened_automatic_bubble());
+  EXPECT_EQ(url::Origin::Create(test_local_form().url),
+            controller()->GetOrigin());
+  ExpectIconAndControllerStateIs(password_manager::ui::PENDING_PASSWORD_STATE);
+}
+
 TEST_F(ManagePasswordsUIControllerTest, AutoSignin) {
   std::vector<std::unique_ptr<PasswordForm>> local_credentials;
   local_credentials.emplace_back(new PasswordForm(test_local_form()));
diff --git a/chrome/browser/ui/supervised_user/parent_permission_dialog.h b/chrome/browser/ui/supervised_user/parent_permission_dialog.h
index 7450335..a252a2e 100644
--- a/chrome/browser/ui/supervised_user/parent_permission_dialog.h
+++ b/chrome/browser/ui/supervised_user/parent_permission_dialog.h
@@ -11,6 +11,7 @@
 
 #include "base/functional/callback_forward.h"
 #include "base/memory/weak_ptr.h"
+#include "ui/base/interaction/element_identifier.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/native_widget_types.h"
 
@@ -48,6 +49,8 @@
 // API for the Dialog.
 class ParentPermissionDialog {
  public:
+  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kDialogViewIdForTesting);
+
   enum class Result {
     // The parent has given their permission for the action.
     kParentPermissionReceived,
diff --git a/chrome/browser/ui/views/autofill/popup/popup_view_utils.cc b/chrome/browser/ui/views/autofill/popup/popup_view_utils.cc
index f7a2d1e..70a45df 100644
--- a/chrome/browser/ui/views/autofill/popup/popup_view_utils.cc
+++ b/chrome/browser/ui/views/autofill/popup/popup_view_utils.cc
@@ -198,16 +198,13 @@
   popup_bounds->set_height(popup_preferred_height);
   popup_bounds->set_y(top_growth_end);
 
-  if (bottom_available >= popup_preferred_height ||
-      bottom_available >= top_available) {
-    popup_bounds->AdjustToFit(
-        gfx::Rect(popup_bounds->x(), element_bounds.bottom(),
-                  popup_bounds->width(), bottom_available));
-  } else {
-    popup_bounds->AdjustToFit(gfx::Rect(popup_bounds->x(),
-                                        content_area_bounds.y(),
-                                        popup_bounds->width(), top_available));
-  }
+  int y_adjustment = (bottom_available >= popup_preferred_height ||
+                      bottom_available >= top_available)
+                         ? element_bounds.bottom()
+                         : content_area_bounds.y();
+  popup_bounds->AdjustToFit(gfx::Rect(popup_bounds->x(), y_adjustment,
+                                      popup_bounds->width(),
+                                      content_area_bounds.height()));
 }
 
 gfx::Rect CalculatePopupBounds(const gfx::Size& desired_size,
diff --git a/chrome/browser/ui/views/autofill/popup/popup_view_utils_unittest.cc b/chrome/browser/ui/views/autofill/popup/popup_view_utils_unittest.cc
index 256821b1..8696869 100644
--- a/chrome/browser/ui/views/autofill/popup/popup_view_utils_unittest.cc
+++ b/chrome/browser/ui/views/autofill/popup/popup_view_utils_unittest.cc
@@ -176,13 +176,13 @@
       // Corner cases, there is not enough space to grow to the top.
       {10, 10 + element_height},
       {0, 0 + element_height},
-      {90, 90 - desired_prompt_height},
+      {90, 100 - desired_prompt_height},
       {100, 100 - desired_prompt_height},
       // Extreme case: The field is outside of the viewport.
       {120, 100 - desired_prompt_height},
       // Special case: There is not enough space for the desired height.
-      {0, 0 + element_height, 0, 30, 30 - element_height},
-      {5, 5 + element_height, 0, 30, 25 - element_height}};
+      {0, 0 + element_height, 0, 30, 30},
+      {5, 5 + element_height, 0, 30, 30}};
 
   for (const auto& x_dim : x_dimension_cases) {
     for (const auto& y_dim : y_dimension_cases) {
diff --git a/chrome/browser/ui/views/autofill/popup/popup_view_views_unittest.cc b/chrome/browser/ui/views/autofill/popup/popup_view_views_unittest.cc
index e37f243..b5924b63 100644
--- a/chrome/browser/ui/views/autofill/popup/popup_view_views_unittest.cc
+++ b/chrome/browser/ui/views/autofill/popup/popup_view_views_unittest.cc
@@ -53,6 +53,8 @@
 #include "ui/events/keycodes/keyboard_codes.h"
 #include "ui/events/test/event_generator.h"
 #include "ui/gfx/geometry/point.h"
+#include "ui/gfx/geometry/point_f.h"
+#include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/vector2d.h"
 #include "ui/views/accessibility/view_accessibility.h"
 #include "ui/views/test/ax_event_counter.h"
@@ -247,6 +249,7 @@
   ui::test::EventGenerator& generator() { return *generator_; }
   PopupViewViews& view() { return *view_; }
   views::Widget& widget() { return *widget_; }
+  content::WebContents& web_contents() { return *web_contents_; }
 
   std::pair<std::unique_ptr<NiceMock<MockAutofillPopupController>>,
             PopupViewViews*>
@@ -1195,6 +1198,104 @@
 }
 #endif  // !BUILDFLAG(IS_MAC)
 
+// TODO(crbug.com/1523677): Rework into pixel tests and run on all available
+// platforms. The test below is a temporary solution to cover positioning
+// calculations in the popup. The exact numbers were obtained by observing
+// a local run, manually verified and hardcoded in the test with acceptable 15px
+// error, as on different machines the popup geometry/location slightly vary.
+#if BUILDFLAG(IS_LINUX)
+TEST_F(PopupViewViewsTest, PopupPositioning) {
+  constexpr gfx::Size kSmallWindow(300, 300);
+  constexpr gfx::Size kLargeWindow(1000, 1000);
+  constexpr gfx::SizeF kElementSize(100, 25);
+  constexpr gfx::PointF kLargeWindowTopLeftElement(0, 0);
+  constexpr gfx::PointF kLargeWindowBottomLeftElement(0, 975);
+  constexpr gfx::PointF kLargeWindowCenterElement(500, 500);
+  constexpr gfx::PointF kLargeWindowTopRightElement(900, 0);
+  constexpr gfx::PointF kLargeWindowBottomRightElement(900, 975);
+  constexpr gfx::PointF kSmallWindowTopLeftElement(0, 0);
+  constexpr gfx::PointF kSmallWindowLeftElement(0, 140);
+  constexpr gfx::PointF kSmallWindowTopElement(150, 0);
+  constexpr gfx::PointF kSmallWindowBottomElement(150, 275);
+  constexpr gfx::PointF kSmallWindowBottomRightElement(200, 275);
+  const std::vector<PopupItemId> kSmallPopupSuggestions(
+      2, PopupItemId::kAutocompleteEntry);
+  const std::vector<PopupItemId> kLargePopupSuggestions(
+      10, PopupItemId::kAutocompleteEntry);
+
+  struct TestCase {
+    const gfx::Size web_contents_bounds;
+    const gfx::PointF element_position;
+    const std::vector<PopupItemId> suggestions;
+    const gfx::Rect expected_popup_bounds;
+  } test_cases[]{
+      {kLargeWindow,
+       kLargeWindowTopLeftElement,
+       kSmallPopupSuggestions,
+       {25, 26, 164, 138}},
+      {kLargeWindow,
+       kLargeWindowBottomLeftElement,
+       kSmallPopupSuggestions,
+       {25, 840, 164, 134}},
+      {kLargeWindow,
+       kLargeWindowCenterElement,
+       kSmallPopupSuggestions,
+       {525, 526, 164, 138}},
+      {kLargeWindow,
+       kLargeWindowTopRightElement,
+       kSmallPopupSuggestions,
+       {832, 26, 164, 138}},
+      {kLargeWindow,
+       kLargeWindowBottomRightElement,
+       kSmallPopupSuggestions,
+       {832, 840, 164, 134}},
+      {kSmallWindow,
+       kSmallWindowTopLeftElement,
+       kSmallPopupSuggestions,
+       {25, 26, 164, 138}},
+      {kSmallWindow,
+       kSmallWindowTopLeftElement,
+       kLargePopupSuggestions,
+       {100, -10, 183, 308}},
+      {kSmallWindow,
+       kSmallWindowLeftElement,
+       kLargePopupSuggestions,
+       {100, -2, 183, 308}},
+      {kSmallWindow,
+       kSmallWindowTopElement,
+       kLargePopupSuggestions,
+       {117, 26, 179, 288}},
+      {kSmallWindow,
+       kSmallWindowBottomElement,
+       kLargePopupSuggestions,
+       {117, -10, 179, 284}},
+      {kSmallWindow,
+       kSmallWindowBottomRightElement,
+       kLargePopupSuggestions,
+       {17, 6, 183, 308}},
+  };
+
+  for (TestCase& test_case : test_cases) {
+    web_contents().Resize(gfx::Rect(test_case.web_contents_bounds));
+    controller().set_element_bounds(
+        gfx::RectF(test_case.element_position, kElementSize) +
+        web_contents().GetContainerBounds().OffsetFromOrigin());
+    CreateAndShowView(test_case.suggestions);
+
+    const gfx::Rect& expected = test_case.expected_popup_bounds;
+    const gfx::Rect& actual = widget().GetWindowBoundsInScreen();
+    // The exact position and size varies on different machines (e.g. because of
+    // different available fonts) and this comparison relaxation is to mitigate
+    // slightly different dimensions.
+    const int kPxError = 15;
+    EXPECT_NEAR(expected.x(), actual.x(), kPxError);
+    EXPECT_NEAR(expected.y(), actual.y(), kPxError);
+    EXPECT_NEAR(expected.width(), actual.width(), kPxError);
+    EXPECT_NEAR(expected.height(), actual.height(), kPxError);
+  }
+}
+#endif  // BUILDFLAG(IS_LINUX)
+
 TEST_F(PopupViewViewsTest, StandaloneCvcSuggestion_ElementId) {
   Suggestion suggestion(u"dummy_main_text");
   suggestion.feature_for_iph =
diff --git a/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog.cc b/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog.cc
index 5624e76..f8899cf 100644
--- a/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog.cc
+++ b/chrome/browser/ui/views/supervised_user/extension_install_blocked_by_parent_dialog.cc
@@ -41,6 +41,8 @@
 
 namespace extensions {
 
+DEFINE_ELEMENT_IDENTIFIER_VALUE(kParentBlockedDialogMessage);
+
 void ShowExtensionInstallBlockedByParentDialog(
     ExtensionInstalledBlockedByParentDialogAction action,
     const extensions::Extension* extension,
@@ -54,14 +56,15 @@
           .SetTitle(GetTitle(action, extension_type))
           .SetIcon(ui::ImageModel::FromVectorIcon(
               chromeos::kNotificationSupervisedUserIcon, ui::kColorIcon))
-          .AddParagraph(ui::DialogModelLabel(l10n_util::GetStringUTF16(
-              IDS_EXTENSION_PERMISSIONS_BLOCKED_BY_PARENT_PROMPT_MESSAGE)))
+          .AddParagraph(
+              ui::DialogModelLabel(l10n_util::GetStringUTF16(
+                  IDS_EXTENSION_PERMISSIONS_BLOCKED_BY_PARENT_PROMPT_MESSAGE)),
+              std::u16string(), kParentBlockedDialogMessage)
           .AddOkButton(base::DoNothing(),
                        ui::DialogModel::Button::Params().SetLabel(
                            l10n_util::GetStringUTF16(IDS_OK)))
           .SetDialogDestroyingCallback(std::move(done_callback))
           .Build();
-
   gfx::NativeWindow parent_window =
       web_contents ? web_contents->GetTopLevelNativeWindow() : nullptr;
   constrained_window::ShowBrowserModal(std::move(dialog_model), parent_window);
diff --git a/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view.cc b/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view.cc
index 73a9dd0f..3408674 100644
--- a/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view.cc
+++ b/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view.cc
@@ -97,7 +97,7 @@
 
 }  // namespace
 
-DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(ParentPermissionDialogView,
+DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(ParentPermissionDialog,
                                       kDialogViewIdForTesting);
 
 // Create the parent permission input section of the dialog and
@@ -289,7 +289,8 @@
   SetShowCloseButton(false);
   set_fixed_width(views::LayoutProvider::Get()->GetDistanceMetric(
       views::DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH));
-  SetProperty(views::kElementIdentifierKey, kDialogViewIdForTesting);
+  SetProperty(views::kElementIdentifierKey,
+              ParentPermissionDialog::kDialogViewIdForTesting);
 
   identity_manager_ = IdentityManagerFactory::GetForProfile(params_->profile);
 }
diff --git a/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view.h b/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view.h
index bbf58db5..5a511ee 100644
--- a/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view.h
+++ b/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view.h
@@ -46,8 +46,6 @@
   METADATA_HEADER(ParentPermissionDialogView, views::DialogDelegateView)
 
  public:
-  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kDialogViewIdForTesting);
-
   class Observer {
    public:
     // Tells observers that their references to the view are becoming invalid.
diff --git a/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view_browsertest.cc b/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view_browsertest.cc
index 35c7cad..75ffe207 100644
--- a/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view_browsertest.cc
+++ b/chrome/browser/ui/views/supervised_user/parent_permission_dialog_view_browsertest.cc
@@ -315,9 +315,9 @@
                        PermissionReceived_default) {
   RunTestSequence(InAnyContext(Steps(
       ShowDialog(),
-      WaitForShow(ParentPermissionDialogView::kDialogViewIdForTesting),
+      WaitForShow(ParentPermissionDialog::kDialogViewIdForTesting),
       PressButton(views::DialogClientView::kOkButtonElementId),
-      WaitForHide(ParentPermissionDialogView::kDialogViewIdForTesting),
+      WaitForHide(ParentPermissionDialog::kDialogViewIdForTesting),
       CheckResult([this]() { return harness_.GetResult(); },
                   ParentPermissionDialog::Result::kParentPermissionReceived))));
 }
@@ -329,9 +329,9 @@
 
   RunTestSequence(InAnyContext(Steps(
       ShowDialog(),
-      WaitForShow(ParentPermissionDialogView::kDialogViewIdForTesting),
+      WaitForShow(ParentPermissionDialog::kDialogViewIdForTesting),
       PressButton(views::DialogClientView::kOkButtonElementId),
-      WaitForHide(ParentPermissionDialogView::kDialogViewIdForTesting),
+      WaitForHide(ParentPermissionDialog::kDialogViewIdForTesting),
       CheckResult([this]() { return harness_.InvalidCredentialWasReceived(); },
                   true),
       CheckResult([this]() { return harness_.GetResult(); },
@@ -342,9 +342,9 @@
                        PermissionDialogCanceled_default) {
   RunTestSequence(InAnyContext(Steps(
       ShowDialog(),
-      WaitForShow(ParentPermissionDialogView::kDialogViewIdForTesting),
+      WaitForShow(ParentPermissionDialog::kDialogViewIdForTesting),
       PressButton(views::DialogClientView::kCancelButtonElementId),
-      WaitForHide(ParentPermissionDialogView::kDialogViewIdForTesting),
+      WaitForHide(ParentPermissionDialog::kDialogViewIdForTesting),
       CheckResult([this]() { return harness_.GetResult(); },
                   ParentPermissionDialog::Result::kParentPermissionCanceled))));
 }
@@ -356,9 +356,9 @@
 
   RunTestSequence(InAnyContext(Steps(
       ShowDialog(),
-      WaitForShow(ParentPermissionDialogView::kDialogViewIdForTesting),
+      WaitForShow(ParentPermissionDialog::kDialogViewIdForTesting),
       PressButton(views::DialogClientView::kOkButtonElementId),
-      WaitForHide(ParentPermissionDialogView::kDialogViewIdForTesting),
+      WaitForHide(ParentPermissionDialog::kDialogViewIdForTesting),
       CheckResult([this]() { return harness_.GetResult(); },
                   ParentPermissionDialog::Result::kParentPermissionReceived),
       CheckHistogramBucketCount(SupervisedUserExtensionsMetricsRecorder::
@@ -393,9 +393,9 @@
 
   RunTestSequence(InAnyContext(Steps(
       ShowDialog(),
-      WaitForShow(ParentPermissionDialogView::kDialogViewIdForTesting),
+      WaitForShow(ParentPermissionDialog::kDialogViewIdForTesting),
       PressButton(views::DialogClientView::kOkButtonElementId),
-      WaitForHide(ParentPermissionDialogView::kDialogViewIdForTesting),
+      WaitForHide(ParentPermissionDialog::kDialogViewIdForTesting),
       CheckResult([this]() { return harness_.InvalidCredentialWasReceived(); },
                   true),
       CheckResult([this]() { return harness_.GetResult(); },
@@ -423,9 +423,9 @@
                        PermissionDialogCanceled_extension) {
   RunTestSequence(InAnyContext(Steps(
       ShowDialog(),
-      WaitForShow(ParentPermissionDialogView::kDialogViewIdForTesting),
+      WaitForShow(ParentPermissionDialog::kDialogViewIdForTesting),
       PressButton(views::DialogClientView::kCancelButtonElementId),
-      WaitForHide(ParentPermissionDialogView::kDialogViewIdForTesting),
+      WaitForHide(ParentPermissionDialog::kDialogViewIdForTesting),
       CheckResult([this]() { return harness_.GetResult(); },
                   ParentPermissionDialog::Result::kParentPermissionCanceled),
       CheckHistogramBucketCount(SupervisedUserExtensionsMetricsRecorder::
diff --git a/chrome/browser/ui/webui/ash/login/user_creation_screen_handler.cc b/chrome/browser/ui/webui/ash/login/user_creation_screen_handler.cc
index 4d89734..8cd62b2 100644
--- a/chrome/browser/ui/webui/ash/login/user_creation_screen_handler.cc
+++ b/chrome/browser/ui/webui/ash/login/user_creation_screen_handler.cc
@@ -102,6 +102,10 @@
   ShowInWebUI();
 }
 
+void UserCreationScreenHandler::SetDefaultStep() {
+  CallExternalAPI("setDefaultStep");
+}
+
 void UserCreationScreenHandler::SetTriageStep() {
   CallExternalAPI("setTriageStep");
 }
diff --git a/chrome/browser/ui/webui/ash/login/user_creation_screen_handler.h b/chrome/browser/ui/webui/ash/login/user_creation_screen_handler.h
index 4ceb6d2..5d07eef 100644
--- a/chrome/browser/ui/webui/ash/login/user_creation_screen_handler.h
+++ b/chrome/browser/ui/webui/ash/login/user_creation_screen_handler.h
@@ -27,6 +27,7 @@
   virtual void SetIsBackButtonVisible(bool value) = 0;
   virtual void SetTriageStep() = 0;
   virtual void SetChildSetupStep() = 0;
+  virtual void SetDefaultStep() = 0;
 };
 
 class UserCreationScreenHandler : public UserCreationView,
@@ -47,6 +48,7 @@
   void SetIsBackButtonVisible(bool value) override;
   void SetTriageStep() override;
   void SetChildSetupStep() override;
+  void SetDefaultStep() override;
 
   // BaseScreenHandler:
   void DeclareLocalizedValues(
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc b/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc
index 47e3f99..3b4996f 100644
--- a/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc
+++ b/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc
@@ -7,6 +7,7 @@
 #include <vector>
 
 #include "base/functional/bind.h"
+#include "base/location.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/user_metrics.h"
 #include "base/notreached.h"
@@ -26,6 +27,7 @@
 #include "components/consent_auditor/consent_auditor.h"
 #include "components/signin/public/base/avatar_icon_util.h"
 #include "components/signin/public/base/consent_level.h"
+#include "components/signin/public/base/signin_switches.h"
 #include "components/signin/public/identity_manager/account_info.h"
 #include "components/signin/public/identity_manager/tribool.h"
 #include "content/public/browser/web_contents.h"
@@ -43,6 +45,19 @@
 
 namespace {
 const int kProfileImageSize = 128;
+
+// Derives screen mode of sync opt in screen from the
+// CanShowHistorySyncOptInsWithoutMinorModeRestrictions capability.
+bool UseMinorModeRestrictions() {
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+  // ChromeOS handles minor modes separately.
+  return false;
+#else
+  return base::FeatureList::IsEnabled(
+      ::switches::kMinorModeRestrictionsForHistorySyncOptIn);
+#endif
+}
+
 }  // namespace
 
 SyncConfirmationScreenMode GetScreenMode(
@@ -139,12 +154,11 @@
   AccountInfo primary_account_info = identity_manager_->FindExtendedAccountInfo(
       identity_manager_->GetPrimaryAccountInfo(ConsentLevel::kSignin));
 
-  // Fire the "account-info-changed" listener from |SetAccountInfo()|.
+  // Fire the "account-info-changed" and "screen-mode-changed" listeners.
   // Note: If the account info is not available yet in the
-  // IdentityManager, i.e. account_info is empty, the listener will be
-  // fired again through |OnAccountUpdated()|.
-  if (primary_account_info.IsValid())
-    SetAccountInfo(primary_account_info);
+  // IdentityManager, i.e. account_info is empty or capabilities are not ready
+  // yet, the listener will be fired again through `OnAccountUpdated()`.
+  DispatchAccountInfoUpdate(primary_account_info);
 }
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
@@ -193,13 +207,9 @@
       sync_consent);
 }
 
-void SyncConfirmationHandler::SetAccountInfo(const AccountInfo& info) {
+void SyncConfirmationHandler::OnAvatarChanged(const AccountInfo& info) {
   DCHECK(info.IsValid());
-  if (!SyncServiceFactory::IsSyncAllowed(profile_)) {
-    // The sync disabled confirmation handler does not present the user image.
-    // Avoid updating the image URL in this case.
-    return;
-  }
+  avatar_notified_ = true;
 
   GURL picture_gurl(info.picture_url);
   GURL picture_gurl_with_options = signin::GetAvatarImageURLWithOptions(
@@ -208,31 +218,73 @@
   base::Value::Dict value;
   value.Set("src", picture_gurl_with_options.spec());
   value.Set("showEnterpriseBadge", info.IsManaged());
-  value.Set("screenMode", static_cast<int>(GetScreenMode(info.capabilities)));
-
-  AllowJavascript();
   FireWebUIListener("account-info-changed", value);
 }
 
-void SyncConfirmationHandler::OnExtendedAccountInfoUpdated(
+void SyncConfirmationHandler::OnScreenModeChanged(
+    SyncConfirmationScreenMode mode) {
+  DCHECK(mode != SyncConfirmationScreenMode::kPending);
+  DCHECK(!screen_mode_notified_) << "Must be called only once";
+  screen_mode_notified_ = true;
+  screen_mode_deadline_.Stop();
+  FireWebUIListener("screen-mode-changed", static_cast<int>(mode));
+}
+
+void SyncConfirmationHandler::OnDeadline() {
+  if (!screen_mode_notified_) {
+    OnScreenModeChanged(SyncConfirmationScreenMode::kRestricted);
+  }
+}
+
+void SyncConfirmationHandler::DispatchAccountInfoUpdate(
     const AccountInfo& info) {
-  if (!info.IsValid())
+  if (info.IsEmpty()) {
+    // No account is signed in, so there is nothing to be displayed in the sync
+    // confirmation dialog.
     return;
+  }
+
+  if (!SyncServiceFactory::IsSyncAllowed(profile_)) {
+    // The sync disabled confirmation handler does not present the user image.
+    // Avoid updating the image URL in this case.
+    return;
+  }
 
   if (info.account_id !=
       identity_manager_->GetPrimaryAccountId(ConsentLevel::kSignin)) {
     return;
   }
 
-  if (GetScreenMode(info.capabilities) !=
-      SyncConfirmationScreenMode::kPending) {
-    // AccountCapabilities are fetched asynchronously, so stop observing changes
-    // only after the screen mode derived from the capability is not pending
-    // anymore.
-    identity_manager_observation_.Reset();
+  AllowJavascript();
+
+  if (info.IsValid() && !avatar_notified_) {
+    OnAvatarChanged(info);
   }
 
-  SetAccountInfo(info);
+  if (screen_mode_notified_) {
+    // Screen mode must be changed only once.
+    return;
+  }
+
+  if (UseMinorModeRestrictions()) {
+    if (SyncConfirmationScreenMode mode = GetScreenMode(info.capabilities);
+        mode != SyncConfirmationScreenMode::kPending) {
+      OnScreenModeChanged(mode);
+    }
+  } else {
+    OnScreenModeChanged(SyncConfirmationScreenMode::kUnrestricted);
+  }
+}
+
+void SyncConfirmationHandler::OnExtendedAccountInfoUpdated(
+    const AccountInfo& info) {
+  DispatchAccountInfoUpdate(info);
+
+  if (avatar_notified_ && screen_mode_notified_) {
+    // IdentityManager emitted both avatar and screen mode information and its
+    // function is done.
+    identity_manager_observation_.Reset();
+  }
 }
 
 void SyncConfirmationHandler::CloseModalSigninWindow(
@@ -259,8 +311,6 @@
 
 void SyncConfirmationHandler::HandleInitializedWithSize(
     const base::Value::List& args) {
-  AllowJavascript();
-
   AccountInfo primary_account_info = identity_manager_->FindExtendedAccountInfo(
       identity_manager_->GetPrimaryAccountInfo(ConsentLevel::kSignin));
   if (primary_account_info.IsEmpty()) {
@@ -269,12 +319,18 @@
     return;
   }
 
-  if (!(primary_account_info.IsValid() &&
-        GetScreenMode(primary_account_info.capabilities) !=
-            SyncConfirmationScreenMode::kPending)) {
+  DispatchAccountInfoUpdate(primary_account_info);
+
+  if (!avatar_notified_ ||
+      (!screen_mode_notified_ && UseMinorModeRestrictions())) {
+    // IdentityManager emits both avatar and screen mode information.
     identity_manager_observation_.Observe(identity_manager_);
-  } else {
-    SetAccountInfo(primary_account_info);
+  }
+
+  if (!screen_mode_notified_ && UseMinorModeRestrictions()) {
+    // Deadline timer for the case when screen mode doesn't arrive in time.
+    screen_mode_deadline_.Start(FROM_HERE, base::Seconds(2), this,
+                                &SyncConfirmationHandler::OnDeadline);
   }
 
   if (browser_)
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_handler.h b/chrome/browser/ui/webui/signin/sync_confirmation_handler.h
index 60f528da..ee41d6b7 100644
--- a/chrome/browser/ui/webui/signin/sync_confirmation_handler.h
+++ b/chrome/browser/ui/webui/signin/sync_confirmation_handler.h
@@ -11,6 +11,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/memory/safety_checks.h"
 #include "base/notreached.h"
+#include "base/timer/timer.h"
 #include "base/values.h"
 #include "chrome/browser/ui/browser_list_observer.h"
 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
@@ -41,9 +42,9 @@
                                 public signin::IdentityManager::Observer,
                                 public BrowserListObserver {
  public:
-  // Creates a SyncConfirmationHandler for the |profile|. All strings in the
-  // corresponding Web UI should be represented in |string_to_grd_id_map| and
-  // mapped to their GRD IDs. If |browser| is provided, its signin view
+  // Creates a SyncConfirmationHandler for the `profile`. All strings in the
+  // corresponding Web UI should be represented in `string_to_grd_id_map` and
+  // mapped to their GRD IDs. If `browser` is provided, its signin view
   // controller will be notified of the rendered size of the web page.
   SyncConfirmationHandler(
       Profile* profile,
@@ -82,13 +83,13 @@
   virtual void HandleGoToSettings(const base::Value::List& args);
 
   // Handles the web ui message sent when the html content is done being laid
-  // out and it's time to resize the native view hosting it to fit. |args| is
+  // out and it's time to resize the native view hosting it to fit. `args` is
   // a single integer value for the height the native view should resize to.
   virtual void HandleInitializedWithSize(const base::Value::List& args);
 
   // Handles the "accountInfoRequest" message sent after the
   // "account-info-changed" WebUIListener was added. This method calls
-  // |SetAccountInfo| with the signed-in user's picture url.
+  // `OnAvatarChanged` with the signed-in user's picture url.
   virtual void HandleAccountInfoRequest(const base::Value::List& args);
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
@@ -98,8 +99,8 @@
   // new window in ash for device sync settings .
   virtual void HandleOpenDeviceSyncSettings(const base::Value::List& args);
 #endif
-  // Records the user's consent to sync. Called from |HandleConfirm| and
-  // |HandleGoToSettings|, and expects two parameters to be passed through
+  // Records the user's consent to sync. Called from `HandleConfirm` and
+  // `HandleGoToSettings`, and expects two parameters to be passed through
   // these methods from the WebUI:
   // 1. List of strings (names of the string resources constituting the consent
   //                     description as per WebUIDataSource)
@@ -108,12 +109,23 @@
   // manner, i.e. clicks on the confirmation button or the settings link.
   virtual void RecordConsent(const base::Value::List& args);
 
-  // Sets the account image shown in the dialog based on |info|, which is
-  // expected to be valid.
-  virtual void SetAccountInfo(const AccountInfo& info);
+  // Dispatches incoming account info to respective ui listeners
+  // (::OnAvatarChanged, ::OnScreenModeChanged).
+  virtual void DispatchAccountInfoUpdate(const AccountInfo& info);
+
+  // Sets the account image shown in the dialog based on `info`, which is
+  // expected to be valid. UI is notified only once.
+  virtual void OnAvatarChanged(const AccountInfo& info);
+
+  // Sets the screen mode of the dialog based on `mode`.  UI is notified only
+  // once.
+  virtual void OnScreenModeChanged(SyncConfirmationScreenMode mode);
+
+  // Called when `screen_mode_deadline_` times out.
+  virtual void OnDeadline();
 
   // Closes the modal signin window and calls
-  // LoginUIService::SyncConfirmationUIClosed with |result|. |result| indicates
+  // LoginUIService::SyncConfirmationUIClosed with `result`. `result` indicates
   // the option chosen by the user in the confirmation UI.
   void CloseModalSigninWindow(
       LoginUIService::SyncConfirmationUIClosedResult result);
@@ -137,6 +149,12 @@
   base::ScopedObservation<signin::IdentityManager,
                           signin::IdentityManager::Observer>
       identity_manager_observation_{this};
+
+  base::OneShotTimer screen_mode_deadline_;
+
+  // Flipped when the UI is first notified, prevents multiple updates.
+  bool avatar_notified_ = false;
+  bool screen_mode_notified_ = false;
 };
 
 #endif  // CHROME_BROWSER_UI_WEBUI_SIGNIN_SYNC_CONFIRMATION_HANDLER_H_
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc b/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc
index 026b10b..e24f370 100644
--- a/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc
+++ b/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc
@@ -14,6 +14,7 @@
 #include "base/functional/callback_helpers.h"
 #include "base/memory/raw_ptr.h"
 #include "base/scoped_observation.h"
+#include "base/strings/stringprintf.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/metrics/user_action_tester.h"
 #include "base/values.h"
@@ -34,16 +35,39 @@
 #include "chrome/test/base/testing_profile.h"
 #include "components/consent_auditor/fake_consent_auditor.h"
 #include "components/signin/public/base/avatar_icon_util.h"
+#include "components/signin/public/base/signin_switches.h"
 #include "components/signin/public/identity_manager/account_capabilities_test_mutator.h"
 #include "content/public/test/browser_task_environment.h"
 #include "content/public/test/test_web_ui.h"
 
+namespace {
+
 const int kExpectedProfileImageSize = 128;
 
 // The dialog needs to be initialized with a height but the actual value doesn't
 // really matter in unit tests.
 const double kDefaultDialogHeight = 350.0;
 
+using MinorModeRestrictionsEnabled =
+    base::StrongAlias<class MinorModeRestrictionsEnabledTag, bool>;
+
+void ConfigureMinorModeRestrictionFeature(
+    MinorModeRestrictionsEnabled minor_mode_restrictions_enabled,
+    base::test::ScopedFeatureList& feature_flag_) {
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
+  if (minor_mode_restrictions_enabled.value()) {
+    feature_flag_.InitAndEnableFeature(
+        ::switches::kMinorModeRestrictionsForHistorySyncOptIn);
+  } else {
+    feature_flag_.InitAndDisableFeature(
+        ::switches::kMinorModeRestrictionsForHistorySyncOptIn);
+  }
+#else
+  CHECK(!minor_mode_restrictions_enabled.value())
+      << "This feature can be only enabled for selected platforms.";
+#endif
+}
+
 class TestingSyncConfirmationHandler : public SyncConfirmationHandler {
  public:
   TestingSyncConfirmationHandler(
@@ -68,8 +92,10 @@
   using SyncConfirmationHandler::RecordConsent;
 };
 
-class SyncConfirmationHandlerTest : public BrowserWithTestWindowTest,
-                                    public LoginUIService::Observer {
+class SyncConfirmationHandlerTest
+    : public BrowserWithTestWindowTest,
+      public LoginUIService::Observer,
+      public ::testing::WithParamInterface<MinorModeRestrictionsEnabled> {
  public:
   static const char kConsentText1[];
   static const char kConsentText2[];
@@ -77,11 +103,26 @@
   static const char kConsentText4[];
   static const char kConsentText5[];
 
+  static MinorModeRestrictionsEnabled IsMinorModeRequested() {
+    return GetParam();
+  }
+
+  static bool IsMinorModeEnabled() {
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
+    return IsMinorModeRequested().value();
+#else
+    return false;
+#endif
+  }
+
   SyncConfirmationHandlerTest()
       : did_user_explicitly_interact_(false),
         on_sync_confirmation_ui_closed_called_(false),
         sync_confirmation_ui_closed_result_(LoginUIService::ABORT_SYNC),
-        web_ui_(new content::TestWebUI) {}
+        web_ui_(new content::TestWebUI) {
+    ConfigureMinorModeRestrictionFeature(IsMinorModeRequested(),
+                                         scoped_feature_list_);
+  }
 
   SyncConfirmationHandlerTest(const SyncConfirmationHandlerTest&) = delete;
   SyncConfirmationHandlerTest& operator=(const SyncConfirmationHandlerTest&) =
@@ -196,6 +237,17 @@
     EXPECT_EQ(primary_account.IsManaged(), show_enterprise_badge.value());
   }
 
+  SyncConfirmationScreenMode GetScreenMode(
+      const content::TestWebUI::CallData& call_data) {
+    CHECK(call_data.arg1()->is_string())
+        << "arg1 should be string (callback name)";
+    CHECK(call_data.arg1()->GetString() == "screen-mode-changed")
+        << "Wrong callback name";
+
+    CHECK(call_data.arg2()->is_int()) << "arg2 should be int";
+    return static_cast<SyncConfirmationScreenMode>(call_data.arg2()->GetInt());
+  }
+
  protected:
   bool did_user_explicitly_interact_;
   bool on_sync_confirmation_ui_closed_called_;
@@ -216,6 +268,9 @@
   base::HistogramTester histogram_tester_;
   std::unique_ptr<IdentityTestEnvironmentProfileAdaptor>
       identity_test_env_adaptor_;
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 const char SyncConfirmationHandlerTest::kConsentText1[] = "consentText1";
@@ -224,8 +279,7 @@
 const char SyncConfirmationHandlerTest::kConsentText4[] = "consentText4";
 const char SyncConfirmationHandlerTest::kConsentText5[] = "consentText5";
 
-TEST_F(SyncConfirmationHandlerTest,
-       TestAccountInfoAloneIsNotEnoughToTriggerAccountInfoChange) {
+TEST_P(SyncConfirmationHandlerTest, TestAvatarChangeWhenPrimaryAccountReady) {
   identity_test_env()->SimulateSuccessfulFetchOfAccountInfo(
       account_info_.account_id, account_info_.email, account_info_.gaia, "",
       "full_name", "given_name", "locale",
@@ -235,84 +289,22 @@
   args.Append(kDefaultDialogHeight);
   handler()->HandleInitializedWithSize(args);
 
-  EXPECT_EQ(0U, web_ui()->call_data().size());
-}
-
-TEST_F(SyncConfirmationHandlerTest,
-       TestSetAccountInfoIfPrimaryAccountAndCapabilitiesReady) {
-  identity_test_env()->SimulateSuccessfulFetchOfAccountInfo(
-      account_info_.account_id, account_info_.email, account_info_.gaia, "",
-      "full_name", "given_name", "locale",
-      "http://picture.example.com/picture.jpg");
-
-  // Both account info and capability are required to trigger SetAccountInfo.
-  AccountCapabilitiesTestMutator mutator(&account_info_.capabilities);
-  mutator.set_can_show_history_sync_opt_ins_without_minor_mode_restrictions(
-      true);
-  identity_test_env()->UpdateAccountInfoForAccount(account_info_);
-
-  base::Value::List args;
-  args.Append(kDefaultDialogHeight);
-  handler()->HandleInitializedWithSize(args);
-
-  ASSERT_EQ(1U, web_ui()->call_data().size());
+  ASSERT_GE(web_ui()->call_data().size(), 1U);
   ExpectAccountInfoChanged(*web_ui()->call_data()[0]);
+
+  if (IsMinorModeEnabled()) {
+    // When minor mode is effective, screen mode is only sent when the
+    // capability is available.
+    EXPECT_EQ(1U, web_ui()->call_data().size());
+  } else {
+    // Without experiment, expect defaulting to kUnrestricted
+    ASSERT_EQ(2U, web_ui()->call_data().size());
+    EXPECT_EQ(SyncConfirmationScreenMode::kUnrestricted,
+              GetScreenMode(*web_ui()->call_data()[1]));
+  }
 }
 
-TEST_F(SyncConfirmationHandlerTest,
-       TestSetAccountInfoIfPrimaryAccountReadyLater) {
-  base::Value::List args;
-  args.Append(kDefaultDialogHeight);
-  handler()->HandleInitializedWithSize(args);
-
-  // No callback called when there's no account image available.
-  ASSERT_EQ(0U, web_ui()->call_data().size());
-
-  identity_test_env()->SimulateSuccessfulFetchOfAccountInfo(
-      account_info_.account_id, account_info_.email, account_info_.gaia, "",
-      "full_name", "given_name", "locale",
-      "http://picture.example.com/picture.jpg");
-
-  ASSERT_EQ(1U, web_ui()->call_data().size());
-  ExpectAccountInfoChanged(*web_ui()->call_data()[0]);
-}
-
-TEST_F(SyncConfirmationHandlerTest,
-       TestSetAccountInfoIgnoredIfSecondaryAccountUpdated) {
-  base::Value::List args;
-  args.Append(kDefaultDialogHeight);
-  handler()->HandleInitializedWithSize(args);
-  EXPECT_EQ(0U, web_ui()->call_data().size());
-
-  AccountInfo account_info =
-      identity_test_env()->MakeAccountAvailable("bar@example.com");
-  identity_test_env()->SimulateSuccessfulFetchOfAccountInfo(
-      account_info.account_id, account_info.email, account_info.gaia, "",
-      "bar_full_name", "bar_given_name", "bar_locale",
-      "http://picture.example.com/bar_picture.jpg");
-
-  // Updating the account info of a secondary account should not update the
-  // image of the sync confirmation dialog.
-  EXPECT_EQ(0U, web_ui()->call_data().size());
-
-  identity_test_env()->SimulateSuccessfulFetchOfAccountInfo(
-      account_info_.account_id, account_info_.email, account_info_.gaia, "",
-      "full_name", "given_name", "locale",
-      "http://picture.example.com/picture.jpg");
-
-  // Updating the account info of the primary account should update the
-  // image of the sync confirmation dialog.
-  ASSERT_EQ(1U, web_ui()->call_data().size());
-  ExpectAccountInfoChanged(*web_ui()->call_data()[0]);
-}
-
-TEST_F(SyncConfirmationHandlerTest,
-       TestSetAccountInfoManagedIfPrimaryAccountAndCapabilitiesReady) {
-  identity_test_env()->SimulateSuccessfulFetchOfAccountInfo(
-      account_info_.account_id, account_info_.email, account_info_.gaia,
-      "google.com", "full_name", "given_name", "locale",
-      "http://picture.example.com/picture.jpg");
-
+TEST_P(SyncConfirmationHandlerTest, TestScreenModeChangedWhenCapabilityReady) {
   // Both account info and capability are required to trigger SetAccountInfo.
   AccountCapabilitiesTestMutator mutator(&account_info_.capabilities);
   mutator.set_can_show_history_sync_opt_ins_without_minor_mode_restrictions(
@@ -323,11 +315,142 @@
   args.Append(kDefaultDialogHeight);
   handler()->HandleInitializedWithSize(args);
 
-  ASSERT_EQ(1U, web_ui()->call_data().size());
-  ExpectAccountInfoChanged(*web_ui()->call_data()[0]);
+  if (IsMinorModeEnabled()) {
+    // In minor mode, capability was set to false, which means restricting.
+    ASSERT_EQ(1U, web_ui()->call_data().size());
+    EXPECT_EQ(SyncConfirmationScreenMode::kRestricted,
+              GetScreenMode(*web_ui()->call_data()[0]));
+  } else {
+    // Without experiment, expect defaulting to kUnrestricted
+    ASSERT_EQ(1U, web_ui()->call_data().size());
+    EXPECT_EQ(SyncConfirmationScreenMode::kUnrestricted,
+              GetScreenMode(*web_ui()->call_data()[0]));
+  }
 }
 
-TEST_F(SyncConfirmationHandlerTest, TestHandleUndo) {
+TEST_P(SyncConfirmationHandlerTest, TestScreenModeChangeImmuneToAltering) {
+  // Both account info and capability are required to trigger SetAccountInfo.
+  AccountCapabilitiesTestMutator mutator(&account_info_.capabilities);
+  mutator.set_can_show_history_sync_opt_ins_without_minor_mode_restrictions(
+      false);
+  identity_test_env()->UpdateAccountInfoForAccount(account_info_);
+
+  base::Value::List args;
+  args.Append(kDefaultDialogHeight);
+  handler()->HandleInitializedWithSize(args);
+
+  if (IsMinorModeEnabled()) {
+    // In minor mode, capability was set to false, which means restricting.
+    ASSERT_EQ(1U, web_ui()->call_data().size());
+    EXPECT_EQ(SyncConfirmationScreenMode::kRestricted,
+              GetScreenMode(*web_ui()->call_data()[0]));
+  } else {
+    // Without experiment, expect defaulting to kUnrestricted
+    ASSERT_EQ(1U, web_ui()->call_data().size());
+    EXPECT_EQ(SyncConfirmationScreenMode::kUnrestricted,
+              GetScreenMode(*web_ui()->call_data()[0]));
+  }
+
+  // Now attempt flipping capability
+  mutator.set_can_show_history_sync_opt_ins_without_minor_mode_restrictions(
+      true);
+  identity_test_env()->UpdateAccountInfoForAccount(account_info_);
+
+  // The number of calls stays unchanged.
+  EXPECT_EQ(1U, web_ui()->call_data().size());
+}
+
+TEST_P(SyncConfirmationHandlerTest,
+       TestAvatarChangeWhenPrimaryAccountReadyLater) {
+  base::Value::List args;
+  args.Append(kDefaultDialogHeight);
+  handler()->HandleInitializedWithSize(args);
+
+  // Tracks the number of calls which is variable due to minor-mode flag
+  // possibly enabled.
+  unsigned call_count = 0;
+
+  if (!IsMinorModeEnabled()) {
+    // The only callback here is defaulting screen mode to kUnrestricted.
+    ASSERT_EQ(++call_count, web_ui()->call_data().size());
+    EXPECT_EQ(SyncConfirmationScreenMode::kUnrestricted,
+              GetScreenMode(*web_ui()->call_data()[call_count - 1]));
+  }
+
+  identity_test_env()->SimulateSuccessfulFetchOfAccountInfo(
+      account_info_.account_id, account_info_.email, account_info_.gaia, "",
+      "full_name", "given_name", "locale",
+      "http://picture.example.com/picture.jpg");
+
+  // AccountInfo proper is being changed
+  ASSERT_EQ(++call_count, web_ui()->call_data().size());
+  ExpectAccountInfoChanged(*web_ui()->call_data()[call_count - 1]);
+}
+
+TEST_P(SyncConfirmationHandlerTest,
+       TestSetAccountInfoIgnoredIfSecondaryAccountUpdated) {
+  base::Value::List args;
+  args.Append(kDefaultDialogHeight);
+  handler()->HandleInitializedWithSize(args);
+
+  // Tracks the number of calls which is variable due to minor-mode flag
+  // possibly enabled.
+  unsigned call_count = 0;
+
+  if (!IsMinorModeEnabled()) {
+    // The only callback here is defaulting screen mode to kUnrestricted.
+    ASSERT_EQ(++call_count, web_ui()->call_data().size());
+    EXPECT_EQ(SyncConfirmationScreenMode::kUnrestricted,
+              GetScreenMode(*web_ui()->call_data()[call_count - 1]));
+  }
+
+  AccountInfo account_info =
+      identity_test_env()->MakeAccountAvailable("bar@example.com");
+  identity_test_env()->SimulateSuccessfulFetchOfAccountInfo(
+      account_info.account_id, account_info.email, account_info.gaia, "",
+      "bar_full_name", "bar_given_name", "bar_locale",
+      "http://picture.example.com/bar_picture.jpg");
+
+  // Account update was ignored so number of calls is unchanged.
+  ASSERT_EQ(call_count, web_ui()->call_data().size());
+
+  identity_test_env()->SimulateSuccessfulFetchOfAccountInfo(
+      account_info_.account_id, account_info_.email, account_info_.gaia, "",
+      "full_name", "given_name", "locale",
+      "http://picture.example.com/picture.jpg");
+
+  // Updating the account info of the primary account should update the
+  // image of the sync confirmation dialog.
+  ASSERT_EQ(++call_count, web_ui()->call_data().size());
+  ExpectAccountInfoChanged(*web_ui()->call_data()[call_count - 1]);
+}
+
+TEST_P(SyncConfirmationHandlerTest,
+       TestAvatarChangeManagedWhenPrimaryAccountReady) {
+  identity_test_env()->SimulateSuccessfulFetchOfAccountInfo(
+      account_info_.account_id, account_info_.email, account_info_.gaia,
+      "google.com", "full_name", "given_name", "locale",
+      "http://picture.example.com/picture.jpg");
+
+  base::Value::List args;
+  args.Append(kDefaultDialogHeight);
+  handler()->HandleInitializedWithSize(args);
+
+  ASSERT_GE(web_ui()->call_data().size(), 1U);
+  ExpectAccountInfoChanged(*web_ui()->call_data()[0]);
+
+  if (IsMinorModeEnabled()) {
+    // When minor mode is effective, screen mode is only sent when the
+    // capability is available.
+    ASSERT_EQ(1U, web_ui()->call_data().size());
+  } else {
+    ASSERT_EQ(2U, web_ui()->call_data().size());
+    EXPECT_EQ(SyncConfirmationScreenMode::kUnrestricted,
+              GetScreenMode(*web_ui()->call_data()[1]));
+  }
+}
+
+TEST_P(SyncConfirmationHandlerTest, TestHandleUndo) {
   handler()->HandleUndo(base::Value::List());
   did_user_explicitly_interact_ = true;
 
@@ -340,7 +463,7 @@
       "Signin_Signin_WithAdvancedSyncSettings"));
 }
 
-TEST_F(SyncConfirmationHandlerTest, TestHandleConfirm) {
+TEST_P(SyncConfirmationHandlerTest, TestHandleConfirm) {
   // The consent description consists of strings 1, 2, and 4.
   base::Value::List consent_description;
   consent_description.Append(SyncConfirmationHandlerTest::kConsentText1);
@@ -378,7 +501,7 @@
   EXPECT_EQ(account_info_.account_id, consent_auditor()->account_id());
 }
 
-TEST_F(SyncConfirmationHandlerTest, TestHandleConfirmWithAdvancedSyncSettings) {
+TEST_P(SyncConfirmationHandlerTest, TestHandleConfirmWithAdvancedSyncSettings) {
   // The consent description consists of strings 2, 3, and 5.
   base::Value::List consent_description;
   consent_description.Append(SyncConfirmationHandlerTest::kConsentText2);
@@ -414,3 +537,19 @@
 
   EXPECT_EQ(account_info_.account_id, consent_auditor()->account_id());
 }
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         SyncConfirmationHandlerTest,
+                         testing::Values(MinorModeRestrictionsEnabled(false)
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
+                                             ,
+                                         MinorModeRestrictionsEnabled(true)
+#endif
+                                             ),
+                         [](const auto& info) {
+                           return base::StringPrintf(
+                               "%sMinorModeRestrictions",
+                               info.param.value() ? "With" : "Without");
+                         });
+
+}  // namespace
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
index 98cd9943..173d950 100644
--- a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
+++ b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
@@ -34,7 +34,6 @@
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/signin_resources.h"
 #include "components/signin/public/base/avatar_icon_util.h"
-#include "components/signin/public/base/consent_level.h"
 #include "components/signin/public/base/signin_switches.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "components/strings/grit/components_strings.h"
@@ -83,26 +82,6 @@
   return false;
 }
 
-// Derives screen mode of sync opt in screen from the
-// CanShowHistorySyncOptInsWithoutMinorModeRestrictions capability.
-SyncConfirmationScreenMode GetInitialScreenMode(
-    signin::IdentityManager* identity_manager) {
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
-  // ChromeOs handles minor modes separately.
-  return SyncConfirmationScreenMode::kUnrestricted;
-#else
-  if (base::FeatureList::IsEnabled(
-          ::switches::kMinorModeRestrictionsForHistorySyncOptIn)) {
-    CoreAccountInfo account_info =
-        identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin);
-    AccountInfo account =
-        identity_manager->FindExtendedAccountInfo(account_info);
-    return GetScreenMode(account.capabilities);
-  }
-  return SyncConfirmationScreenMode::kUnrestricted;
-#endif
-}
-
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
 bool ShouldShowAppsDisclaimerInLacros(Profile* profile) {
   syncer::SyncPrefs prefs_ = syncer::SyncPrefs(profile->GetPrefs());
@@ -342,10 +321,6 @@
   // Registering other variables that are computed above based on multiple
   // factors (e.g. platform).
   source->AddBoolean("useClickableSyncInfoDesc", use_clickable_sync_info_desc);
-
-  source->AddInteger("screenMode",
-                     static_cast<int>(GetInitialScreenMode(
-                         IdentityManagerFactory::GetForProfile(profile_))));
 }
 
 void SyncConfirmationUI::InitializeForSyncDisabled(
@@ -375,9 +350,6 @@
           : IDS_SYNC_DISABLED_CONFIRMATION_CONFIRM_BUTTON_LABEL);
   AddStringResource(source, "syncDisabledConfirmationUndoLabel",
                     IDS_SYNC_DISABLED_CONFIRMATION_UNDO_BUTTON_LABEL);
-
-  source->AddInteger(
-      "screenMode", static_cast<int>(SyncConfirmationScreenMode::kUnsupported));
 }
 
 void SyncConfirmationUI::AddStringResource(content::WebUIDataSource* source,
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
index 49b66d1..1fe7970 100644
--- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
+++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
@@ -513,7 +513,7 @@
   }
 
   auto* const sync_service = SyncServiceFactory::GetForProfile(profile);
-  // TODO(crbug.com/1462552): Remove this call once IsSyncFeatureEnabled()
+  // TODO(crbug.com/40066949): Remove this call once IsSyncFeatureEnabled()
   // is fully deprecated, see ConsentLevel::kSync documentation for details,
   // in components/signin/public/base/consent_level.h.
   return sync_service && sync_service->IsSyncFeatureEnabled() &&
diff --git a/chrome/build/lacros64.pgo.txt b/chrome/build/lacros64.pgo.txt
index 7fc7f7e..4746975a0 100644
--- a/chrome/build/lacros64.pgo.txt
+++ b/chrome/build/lacros64.pgo.txt
@@ -1 +1 @@
-chrome-chromeos-amd64-generic-main-1707350387-b81c34bb7277714ae9511fed8527263c18b9db82.profdata
+chrome-chromeos-amd64-generic-main-1707393701-cc2600d26d6a9903646b4706d5cf43efa7e73b0f.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 2da1b69..df659bc 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1707350387-c53afe4b59be5e777079ad7ac205233b1e1164b5.profdata
+chrome-linux-main-1707393306-ca2aa40870856472f3a20114b434434f95d798a8.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index 53c6bfd..b15358c 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1707371451-dec039a3dbf2292385be97878aca13b4e4ae2ec3.profdata
+chrome-mac-arm-main-1707400503-560572c1c183ea46f06eeebd8fb1b53e61875da3.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt
index 7df5639..b45dbe9 100644
--- a/chrome/build/win-arm64.pgo.txt
+++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@
-chrome-win-arm64-main-1707285186-cb40fbe1ff39210afa92a15c58b445013c616946.profdata
+chrome-win-arm64-main-1707393306-b9c0997da2326d2f6a7cb0bd5d6921395eebcdc6.profdata
diff --git a/chrome/common/extensions/api/scripting.idl b/chrome/common/extensions/api/scripting.idl
index 2bdfeae..6ce572b 100644
--- a/chrome/common/extensions/api/scripting.idl
+++ b/chrome/common/extensions/api/scripting.idl
@@ -192,10 +192,12 @@
   };
 
   interface Functions {
-    // Injects a script into a target context. The script will be run at
-    // <code>document_idle</code>. If the script evaluates to a promise,
-    // the browser will wait for the promise to settle and return the
-    // resulting value.
+    // Injects a script into a target context. By default, the script will be run
+    // at <code>document_idle</code>, or immediately if the page has already
+    // loaded. If the <code>injectImmediately</code> property is set, the script
+    // will inject without waiting, even if the page has not finished loading. If
+    // the script evaluates to a promise, the browser will wait for the promise to
+    // settle and return the resulting value.
     // |injection|: The details of the script which to inject.
     // |callback|: Invoked upon completion of the injection. The resulting
     // array contains the result of execution for each frame where the
diff --git a/chrome/renderer/autofill/form_autocomplete_browsertest.cc b/chrome/renderer/autofill/form_autocomplete_browsertest.cc
index a4833bba..8234bf1 100644
--- a/chrome/renderer/autofill/form_autocomplete_browsertest.cc
+++ b/chrome/renderer/autofill/form_autocomplete_browsertest.cc
@@ -18,6 +18,7 @@
 #include "components/autofill/content/renderer/form_autofill_util.h"
 #include "components/autofill/content/renderer/form_tracker_test_api.h"
 #include "components/autofill/core/common/autofill_features.h"
+#include "components/autofill/core/common/autofill_test_utils.h"
 #include "components/autofill/core/common/form_data.h"
 #include "components/autofill/core/common/mojom/autofill_types.mojom-shared.h"
 #include "content/public/renderer/render_frame.h"
@@ -193,12 +194,13 @@
   EXPECT_EQ(nullptr, fake_driver.form_submitted());
 }
 
+// TODO(crbug.com/1522821): Update.
 FormData CreateAutofillFormData(blink::WebLocalFrame* main_frame) {
   FormData data;
   data.name = u"name";
   data.url = GURL("http://example.com/");
   data.action = GURL("http://example.com/blade.php");
-  data.is_form_tag = true;  // Default value.
+  data.renderer_id = test::MakeFormRendererId();  // Default value.
 
   WebDocument document = main_frame->GetDocument();
   WebFormControlElement fname_element =
@@ -271,11 +273,12 @@
           .To<WebFormControlElement>();
   ASSERT_FALSE(lname_element.IsNull());
 
+  // TODO(crbug.com/1522821): Update.
   FormData form;
   form.name = u"name";
   form.url = GURL("http://example.com/");
   form.action = GURL("http://example.com/blade.php");
-  form.is_form_tag = true;  // Default value.
+  form.renderer_id = test::MakeFormRendererId();  // Default value.
 
   FormFieldData field;
   field.name = u"fname";
@@ -350,6 +353,7 @@
     return focus_test_utils_->GetFocusLog(GetMainFrame()->GetDocument());
   }
 
+  test::AutofillUnitTestEnvironment autofill_test_environment_;
   FakeContentAutofillDriver fake_driver_;
   std::unique_ptr<test::FocusTestUtils> focus_test_utils_;
 };
diff --git a/chrome/renderer/autofill/form_autofill_browsertest.cc b/chrome/renderer/autofill/form_autofill_browsertest.cc
index eb6629c..e750580e 100644
--- a/chrome/renderer/autofill/form_autofill_browsertest.cc
+++ b/chrome/renderer/autofill/form_autofill_browsertest.cc
@@ -5633,7 +5633,7 @@
     std::vector<FormData> forms = UpdateFormCache(form_cache).updated_forms;
     EXPECT_EQ(test_case.number_of_extracted_forms, forms.size());
     if (!forms.empty())
-      EXPECT_EQ(test_case.is_form_tag, forms.back().is_form_tag);
+      EXPECT_EQ(test_case.is_form_tag, !forms.back().renderer_id.is_null());
   }
 }
 
diff --git a/chrome/services/sharing/nearby/test_support/mock_webrtc_dependencies.h b/chrome/services/sharing/nearby/test_support/mock_webrtc_dependencies.h
index 9211941b..886636e 100644
--- a/chrome/services/sharing/nearby/test_support/mock_webrtc_dependencies.h
+++ b/chrome/services/sharing/nearby/test_support/mock_webrtc_dependencies.h
@@ -55,6 +55,7 @@
        const network::P2PPortRange& port_range,
        const network::P2PHostAndIPEndPoint& remote_address,
        const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
+       const absl::optional<base::UnguessableToken>& devtools_token,
        mojo::PendingRemote<network::mojom::P2PSocketClient> client,
        mojo::PendingReceiver<network::mojom::P2PSocket> receiver),
       (override));
diff --git a/chrome/services/sharing/webrtc/p2p_socket_client.cc b/chrome/services/sharing/webrtc/p2p_socket_client.cc
index 67e5aea..8de60ed 100644
--- a/chrome/services/sharing/webrtc/p2p_socket_client.cc
+++ b/chrome/services/sharing/webrtc/p2p_socket_client.cc
@@ -59,7 +59,7 @@
       type, local_address, network::P2PPortRange(min_port, max_port),
       remote_address,
       net::MutableNetworkTrafficAnnotationTag(traffic_annotation_),
-      receiver_.BindNewPipeAndPassRemote(),
+      /*devtools_token=*/absl::nullopt, receiver_.BindNewPipeAndPassRemote(),
       socket_.BindNewPipeAndPassReceiver());
   receiver_.set_disconnect_handler(base::BindOnce(
       &P2PSocketClient::OnConnectionError, base::Unretained(this)));
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index cfefc45..10af43f 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -2879,6 +2879,10 @@
         "supervised_user/family_member.cc",
         "supervised_user/family_member.h",
       ]
+      if (enable_extensions) {
+        sources +=
+            [ "../browser/supervised_user/extensions_interactive_uitest.cc" ]
+      }
       deps += [ "//components/supervised_user/test_support" ]
     }
 
@@ -6035,7 +6039,6 @@
     "../browser/component_updater/afp_blocked_domain_list_component_installer_unittest.cc",
     "../browser/component_updater/chrome_component_updater_configurator_unittest.cc",
     "../browser/component_updater/crl_set_component_installer_unittest.cc",
-    "../browser/component_updater/first_party_sets_component_installer_unittest.cc",
     "../browser/component_updater/masked_domain_list_component_installer_unittest.cc",
     "../browser/component_updater/origin_trials_component_installer_unittest.cc",
     "../browser/component_updater/pki_metadata_component_installer_unittest.cc",
diff --git a/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js b/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js
index 542d933..4ceb964 100644
--- a/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js
+++ b/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js
@@ -507,6 +507,30 @@
                result);
     }));
   },
+
+  function getDeviceStatesLacros() {
+    chrome.networkingPrivate.getDeviceStates(callbackPass(function(result) {
+      // Tether scanning value is flaky, ignore it in this test
+      tetherIdx = result.findIndex((element) => element.Type === 'Tether');
+      assertTrue(tetherIdx > -1);
+      delete result[tetherIdx].Scanning;
+
+      assertEq(
+          [
+            {Scanning: false, State: 'Enabled', Type: 'Ethernet'},
+            {
+              ManagedNetworkAvailable: false,
+              Scanning: false,
+              State: 'Enabled',
+              Type: 'WiFi'
+            },
+            {State: 'Enabled', Type: 'Tether'},
+            {State: 'Enabled', Type: 'Cellular'},
+          ],
+          result);
+    }));
+  },
+
   function requestNetworkScan() {
     // Connected or Connecting networks should be listed first, sorted by type.
     var expected = ['stub_ethernet_guid',
diff --git a/chrome/test/data/webui/signin/sync_confirmation_test.ts b/chrome/test/data/webui/signin/sync_confirmation_test.ts
index eac05db2..a9160e8 100644
--- a/chrome/test/data/webui/signin/sync_confirmation_test.ts
+++ b/chrome/test/data/webui/signin/sync_confirmation_test.ts
@@ -43,11 +43,16 @@
     await browserProxy.whenCalled('requestAccountInfo');
   });
 
-  // Tests that no DCHECKS are thrown during initialization of the UI.
+  // Tests that the buttons are initially hidden, pending minor-mode compliance
+  // configuration.
   test('LoadPage', function() {
     const cancelButton =
         app.shadowRoot!.querySelector<HTMLElement>('#notNowButton');
-    assertFalse(cancelButton!.hidden);
+    assertTrue(cancelButton!.hidden);
+
+    const confirmButton =
+        app.shadowRoot!.querySelector<HTMLElement>('#confirmButton');
+    assertTrue(confirmButton!.hidden);
   });
 
   // Tests clicking on confirm button.
diff --git a/chrome/test/supervised_user/family_member.cc b/chrome/test/supervised_user/family_member.cc
index d3c4a2c8..43ca042 100644
--- a/chrome/test/supervised_user/family_member.cc
+++ b/chrome/test/supervised_user/family_member.cc
@@ -40,11 +40,14 @@
   return identity_manager->GetPrimaryAccountId(signin::ConsentLevel::kSignin);
 }
 
+std::string GetFamilyMemberSettingsUrlBase(FamilyMember& member) {
+  return base::StrCat({"https://families.google.com/u/0/manage/family/child/",
+                       GetAccountId(member.browser()->profile()).ToString()});
+}
+
 GURL GetControlListUrlFor(FamilyMember& member, std::string_view page) {
-  return GURL(
-      base::StrCat({"https://families.google.com/u/0/manage/family/child/",
-                    GetAccountId(member.browser()->profile()).ToString(),
-                    "/exceptions/", page}));
+  return GURL(base::StrCat(
+      {GetFamilyMemberSettingsUrlBase(member), "/exceptions/", page}));
 }
 }  // namespace
 
@@ -69,9 +72,8 @@
 }
 
 GURL FamilyMember::GetPermissionsUrlFor(FamilyMember& member) const {
-  return GURL(base::StrCat(
-      {"https://families.google.com/u/0/manage/family/child/",
-       GetAccountId(member.browser()->profile()).ToString(), "/permissions"}));
+  return GURL(
+      base::StrCat({GetFamilyMemberSettingsUrlBase(member), "/permissions"}));
 }
 
 void FamilyMember::TurnOnSync() {
diff --git a/chromeos/ash/components/login/auth/login_performer.cc b/chromeos/ash/components/login/auth/login_performer.cc
index 3aba110..7bdbb4ff 100644
--- a/chromeos/ash/components/login/auth/login_performer.cc
+++ b/chromeos/ash/components/login/auth/login_performer.cc
@@ -59,6 +59,16 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   LoginEventRecorder::Get()->AddLoginTimeMarker("OnAuthSuccess", false);
   delegate_->ReportOnAuthSuccessMetrics();
+  auto mount_state = user_context.GetMountState();
+  if (mount_state &&
+      (*mount_state == UserContext::MountState::kNewPersistent)) {
+    // In rare cases (e.g. due to disk cleanup mechanism) it is possible that
+    // user's cryptohome is deleted, but information in `Local State` still
+    // assumes that user exists.
+    // Remove all such stale information at this point.
+    user_manager::UserManager::Get()->CleanStaleUserInformationFor(
+        user_context.GetAccountId());
+  }
 
   const bool is_known_user = user_manager::UserManager::Get()->IsKnownUser(
       user_context.GetAccountId());
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc
index cb0b4835..ab8a980 100644
--- a/chromeos/constants/chromeos_features.cc
+++ b/chromeos/constants/chromeos_features.cc
@@ -157,11 +157,6 @@
 // controls all system UI updates and new system components. go/jelly-flags
 BASE_FEATURE(kJellyroll, "Jellyroll", base::FEATURE_ENABLED_BY_DEFAULT);
 
-// Makes Kiosk close all tabs instead of closing the window.
-BASE_FEATURE(kKioskCloseAllTabs,
-             "KioskCloseAllTabs",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 // Enables Kiosk Heartbeats to be sent via Encrypted Reporting Pipeline
 BASE_FEATURE(kKioskHeartbeatsViaERP,
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h
index d77863ad..46cc3344 100644
--- a/chromeos/constants/chromeos_features.h
+++ b/chromeos/constants/chromeos_features.h
@@ -66,7 +66,6 @@
 BASE_DECLARE_FEATURE(kIWAForTelemetryExtensionAPI);
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS) BASE_DECLARE_FEATURE(kJelly);
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS) BASE_DECLARE_FEATURE(kJellyroll);
-COMPONENT_EXPORT(CHROMEOS_CONSTANTS) BASE_DECLARE_FEATURE(kKioskCloseAllTabs);
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 BASE_DECLARE_FEATURE(kKioskHeartbeatsViaERP);
diff --git a/clank b/clank
index ab0b951..80915fa 160000
--- a/clank
+++ b/clank
@@ -1 +1 @@
-Subproject commit ab0b95197af40620e76f2054c376e0068d43a968
+Subproject commit 80915fa76a95b7fb3ba6db65df700a789109350f
diff --git a/components/android_autofill/browser/form_data_android.cc b/components/android_autofill/browser/form_data_android.cc
index 83d97ca1..31b3a232 100644
--- a/components/android_autofill/browser/form_data_android.cc
+++ b/components/android_autofill/browser/form_data_android.cc
@@ -88,7 +88,7 @@
   // fields to have different labels, form control types, etc.
   auto SimilarityTuple = [](const FormData& f) {
     return std::tie(f.host_frame, f.renderer_id, f.name, f.id_attribute,
-                    f.name_attribute, f.url, f.action, f.is_form_tag);
+                    f.name_attribute, f.url, f.action);
   };
   return SimilarityTuple(form_) == SimilarityTuple(form) &&
          SimilarFieldsAs(form);
@@ -114,7 +114,6 @@
                   SimilarityCheckComponent::kNameAttribute);
   check_component(&FormData::url, SimilarityCheckComponent::kUrl);
   check_component(&FormData::action, SimilarityCheckComponent::kAction);
-  check_component(&FormData::is_form_tag, SimilarityCheckComponent::kIsFormTag);
 
   if (!SimilarFieldsAs(form)) {
     result.value() |= base::to_underlying(SimilarityCheckComponent::kFields);
diff --git a/components/android_autofill/browser/form_data_android.h b/components/android_autofill/browser/form_data_android.h
index 8548174..0d422ac 100644
--- a/components/android_autofill/browser/form_data_android.h
+++ b/components/android_autofill/browser/form_data_android.h
@@ -66,6 +66,7 @@
     kNameAttribute = 1 << 3,
     kUrl = 1 << 4,
     kAction = 1 << 5,
+    // TODO(crbug.com/1265655): Remove.
     kIsFormTag = 1 << 6,
     kFields = 1 << 7,
     kMaxValue = kFields
diff --git a/components/android_autofill/browser/form_data_android_unittest.cc b/components/android_autofill/browser/form_data_android_unittest.cc
index 663d91f..ca2f8c95 100644
--- a/components/android_autofill/browser/form_data_android_unittest.cc
+++ b/components/android_autofill/browser/form_data_android_unittest.cc
@@ -67,7 +67,7 @@
   f.id_attribute = u"form_id";
   f.url = GURL("https://foo.com");
   f.action = GURL("https://bar.com");
-  f.is_form_tag = true;
+  f.renderer_id = test::MakeFormRendererId();
   return f;
 }
 
@@ -117,6 +117,7 @@
   MockFormDataAndroidBridge& form_bridge() { return *form_bridge_; }
 
  private:
+  test::AutofillUnitTestEnvironment autofill_test_environment_;
   std::vector<MockFormFieldDataAndroidBridge*> field_bridges_;
   raw_ptr<MockFormDataAndroidBridge> form_bridge_;
 };
@@ -133,7 +134,7 @@
 }
 
 // Tests that form similarity checks include name, name_attribute, id_attribute,
-// url, action, and is_form_tag.
+// url, and action.
 // Similarity checks are used to determine whether a web page has modified a
 // field significantly enough to warrant restarting an ongoing Autofill session,
 // e.g., because their change would lead to a change in type predictions. As a
@@ -141,8 +142,8 @@
 // are unlikely to have been superficial dynamic changes by Javascript on the
 // website.
 TEST_F(FormDataAndroidTest, SimilarFormAs) {
-  FormDataAndroid af(CreateTestForm(), kSampleSessionId);
   FormData f = CreateTestForm();
+  FormDataAndroid af(f, kSampleSessionId);
 
   // If forms are the same, they are similar.
   EXPECT_TRUE(af.SimilarFormAs(f));
@@ -171,11 +172,6 @@
   f.action = GURL("https://other.com");
   EXPECT_FALSE(af.SimilarFormAs(f));
 
-  // If is_form_tag differs, they are not similar.
-  f = af.form();
-  f.is_form_tag = !f.is_form_tag;
-  EXPECT_FALSE(af.SimilarFormAs(f));
-
   // If their global ids differ, they are not similar.
   f = af.form();
   f.renderer_id = FormRendererId(f.renderer_id.value() + 1);
@@ -216,8 +212,8 @@
     return SimilarityCheckResult((base::to_underlying(components) | ...));
   };
 
-  FormDataAndroid af(CreateTestForm(), kSampleSessionId);
   FormData f = CreateTestForm();
+  FormDataAndroid af(f, kSampleSessionId);
 
   EXPECT_EQ(af.SimilarFormAsWithDiagnosis(f),
             FormDataAndroid::kFormsAreSimilar);
@@ -253,11 +249,6 @@
             to_check_result(SimilarityCheckComponent::kAction));
 
   f = af.form();
-  f.is_form_tag = !f.is_form_tag;
-  EXPECT_EQ(af.SimilarFormAsWithDiagnosis(f),
-            to_check_result(SimilarityCheckComponent::kIsFormTag));
-
-  f = af.form();
   f.name_attribute = af.form().name_attribute + u"x";
   f.id_attribute = af.form().id_attribute + u"x";
   EXPECT_EQ(af.SimilarFormAsWithDiagnosis(f),
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc
index f64bcfd..f790dd3 100644
--- a/components/autofill/content/renderer/autofill_agent.cc
+++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -1399,12 +1399,25 @@
   form_tracker_->AjaxSucceeded();
 }
 
-void AutofillAgent::JavaScriptChangedAutofilledValue(
-    const WebFormControlElement& element,
-    const WebString& old_value) {
+void AutofillAgent::JavaScriptChangedValue(const WebFormControlElement& element,
+                                           const WebString& old_value,
+                                           bool was_autofilled) {
   if (old_value == element.Value()) {
     return;
   }
+  // The provisionally saved form must be updated on JS changes. However, it
+  // should not be changed, so that only the user can set the tracked form and
+  // not JS. This call here is meant to keep the tracked form up to date with
+  // the form's most recent version, and not switch from one form to another.
+  if (base::FeatureList::IsEnabled(
+          features::kAutofillImproveSubmissionDetection) &&
+      form_util::GetFormRendererId(form_util::GetOwningForm(element)) ==
+          last_interacted_.form_id.GetId()) {
+    UpdateLastInteracted(form_util::GetOwningForm(element));
+  }
+  if (!was_autofilled) {
+    return;
+  }
   if (std::optional<FormAndField> form_and_field =
           form_util::FindFormAndFieldForFormControlElement(
               element, field_data_manager(),
@@ -1577,6 +1590,10 @@
 }
 
 std::optional<FormData> AutofillAgent::GetSubmittedForm() const {
+  if (base::FeatureList::IsEnabled(
+          features::kAutofillImproveSubmissionDetection)) {
+    return last_interacted_.saved_state;
+  }
   content::RenderFrame* render_frame = unsafe_render_frame();
   if (!render_frame) {
     return std::nullopt;
diff --git a/components/autofill/content/renderer/autofill_agent.h b/components/autofill/content/renderer/autofill_agent.h
index b0dea535..2280a9e 100644
--- a/components/autofill/content/renderer/autofill_agent.h
+++ b/components/autofill/content/renderer/autofill_agent.h
@@ -317,9 +317,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 JavaScriptChangedValue(const blink::WebFormControlElement& element,
+                              const blink::WebString& old_value,
+                              bool was_autofilled) override;
   void DidCompleteFocusChangeInFrame() override;
   void DidReceiveLeftMouseDownOrGestureTapInNode(
       const blink::WebNode& node) override;
diff --git a/components/autofill/content/renderer/autofill_agent_browsertest.cc b/components/autofill/content/renderer/autofill_agent_browsertest.cc
index e5e40ac4..f4f34dc 100644
--- a/components/autofill/content/renderer/autofill_agent_browsertest.cc
+++ b/components/autofill/content/renderer/autofill_agent_browsertest.cc
@@ -20,12 +20,14 @@
 #include "components/autofill/content/common/mojom/autofill_driver.mojom.h"
 #include "components/autofill/content/renderer/autofill_agent_test_api.h"
 #include "components/autofill/content/renderer/autofill_renderer_test.h"
+#include "components/autofill/content/renderer/form_autofill_util.h"
 #include "components/autofill/content/renderer/form_tracker.h"
 #include "components/autofill/content/renderer/test_utils.h"
 #include "components/autofill/core/common/autofill_features.h"
 #include "components/autofill/core/common/field_data_manager.h"
 #include "components/autofill/core/common/form_data.h"
 #include "components/autofill/core/common/mojom/autofill_types.mojom-shared.h"
+#include "components/autofill/core/common/unique_ids.h"
 #include "content/public/renderer/render_frame.h"
 #include "content/public/test/navigation_simulator.h"
 #include "content/public/test/test_utils.h"
@@ -483,6 +485,48 @@
   EXPECT_EQ(field.GetAutofillState(), blink::WebAutofillState::kNotFilled);
 }
 
+// Test that AutofillAgent::JavaScriptChangedValue updates the
+// last interacted saved state.
+TEST_F(AutofillAgentTest,
+       JavaScriptChangedValueUpdatesLastInteractedSavedState) {
+  base::test::ScopedFeatureList scoped_feature_list{
+      features::kAutofillImproveSubmissionDetection};
+  LoadHTML(R"(<form id="form_id"><input id="text_id"></form>)");
+
+  blink::WebFormElement form = GetMainFrame()
+                                   ->GetDocument()
+                                   .GetElementById("form_id")
+                                   .DynamicTo<blink::WebFormElement>();
+  FormRendererId form_id = form_util::GetFormRendererId(form);
+
+  ExecuteJavaScriptForTests(
+      R"(document.forms[0].elements[0].value = 'js-set value';)");
+  std::optional<FormData> last_interacted_saved_state =
+      AutofillAgentTestApi(&autofill_agent()).last_interacted_saved_state();
+  // Since we do not have a tracked form yet, the JS call should not update (in
+  // this case set) the last interacted form.
+  ASSERT_FALSE(last_interacted_saved_state.has_value());
+
+  SimulateUserEditField(form, "text_id", "user-set value");
+  last_interacted_saved_state =
+      AutofillAgentTestApi(&autofill_agent()).last_interacted_saved_state();
+  ASSERT_TRUE(last_interacted_saved_state.has_value());
+  EXPECT_EQ(last_interacted_saved_state->renderer_id, form_id);
+  ASSERT_EQ(1u, last_interacted_saved_state->fields.size());
+  EXPECT_EQ(u"user-set value", last_interacted_saved_state->fields[0].value);
+
+  ExecuteJavaScriptForTests(
+      R"(document.forms[0].elements[0].value = 'js-set value';)");
+  last_interacted_saved_state =
+      AutofillAgentTestApi(&autofill_agent()).last_interacted_saved_state();
+  // Since we now have a tracked form and JS modified the same form, we should
+  // see the JS modification reflected in the last interacted saved form.
+  ASSERT_TRUE(last_interacted_saved_state.has_value());
+  EXPECT_EQ(last_interacted_saved_state->renderer_id, form_id);
+  ASSERT_EQ(1u, last_interacted_saved_state->fields.size());
+  EXPECT_EQ(u"js-set value", last_interacted_saved_state->fields[0].value);
+}
+
 // Test that AutofillAgent::ApplyFormAction(mojom::ActionPersistence::kFill)
 // updates the last interacted saved state when the <input>s have no containing
 // <form>.
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc
index 8dca4f1..82ddb1ae 100644
--- a/components/autofill/content/renderer/form_autofill_util.cc
+++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -1353,7 +1353,6 @@
     if (form_element.IsNull()) {
       DCHECK(form.renderer_id.is_null());
       DCHECK(form.main_frame_origin.opaque());
-      form.is_form_tag = false;
       form.is_action_empty = true;
       return form;
     }
@@ -2151,7 +2150,6 @@
   form.name_attribute = GetAttribute<kName>(content_editable).Utf16();
   form.name =
       !form.id_attribute.empty() ? form.id_attribute : form.name_attribute;
-  form.is_form_tag = false;
   form.is_action_empty = true;
   form.fields.emplace_back();
 
diff --git a/components/autofill/core/browser/autofill_experiments.cc b/components/autofill/core/browser/autofill_experiments.cc
index 7ebbeb0..17079beb 100644
--- a/components/autofill/core/browser/autofill_experiments.cc
+++ b/components/autofill/core/browser/autofill_experiments.cc
@@ -125,7 +125,7 @@
   // Before address sync is available in transport mode, server card save is
   // offered in transport mode regardless of the setting. (The sync API exposes
   // the kAutofill type as disabled in this case.)
-  // TODO(crbug.com/1462552): Simplify once IsSyncFeatureActive() is deleted
+  // TODO(crbug.com/40066949): Simplify once IsSyncFeatureActive() is deleted
   // from the codebase.
   bool syncing_or_addresses_in_transport_mode =
       sync_service->IsSyncFeatureActive() ||
diff --git a/components/autofill/core/browser/autofill_form_test_utils.cc b/components/autofill/core/browser/autofill_form_test_utils.cc
index a47b54e..18d1fb16 100644
--- a/components/autofill/core/browser/autofill_form_test_utils.cc
+++ b/components/autofill/core/browser/autofill_form_test_utils.cc
@@ -142,7 +142,6 @@
   f.renderer_id = d.renderer_id.value_or(MakeFormRendererId());
   if (d.main_frame_origin)
     f.main_frame_origin = *d.main_frame_origin;
-  f.is_form_tag = d.is_form_tag;
   f.fields.reserve(d.fields.size());
   for (const FieldDescription& dd : d.fields) {
     FormFieldData ff = GetFormFieldData(dd);
diff --git a/components/autofill/core/browser/autofill_form_test_utils.h b/components/autofill/core/browser/autofill_form_test_utils.h
index 8943534..0ee8b55a 100644
--- a/components/autofill/core/browser/autofill_form_test_utils.h
+++ b/components/autofill/core/browser/autofill_form_test_utils.h
@@ -75,7 +75,6 @@
   const std::string url = kFormUrl;
   const std::string action = kFormActionUrl;
   std::optional<url::Origin> main_frame_origin;
-  bool is_form_tag = true;
 };
 
 // Flags determining whether the corresponding check should be run on the test
diff --git a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc
index 1d83d01..7c10fb1 100644
--- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc
+++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc
@@ -619,7 +619,7 @@
   upload.set_form_signature(form.form_signature().value());
   upload.set_autofill_used(false);
   upload.set_data_present(data_present);
-  upload.set_has_form_tag(form.is_form_tag());
+  upload.set_has_form_tag(form.is_form_element());
   if (!form.current_page_language()->empty() &&
       form.randomized_encoder().has_value()) {
     upload.set_language(form.current_page_language().value());
diff --git a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding_unittest.cc b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding_unittest.cc
index 5a6e3f39..a13dda4 100644
--- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding_unittest.cc
+++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding_unittest.cc
@@ -30,6 +30,7 @@
 #include "components/autofill/core/common/form_field_data.h"
 #include "components/autofill/core/common/html_field_types.h"
 #include "components/autofill/core/common/signatures.h"
+#include "components/autofill/core/common/unique_ids.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/testing_pref_service.h"
@@ -711,7 +712,7 @@
   std::vector<FieldTypeValidityStatesMap> possible_field_types_validities;
   FormData form;
   form.url = GURL("http://www.foo.com/");
-  form.is_form_tag = true;
+  form.renderer_id = test::MakeFormRendererId();
   form.fields = {
       CreateTestFormField("First Name", "firstname", "",
                           FormControlType::kInputText, "given-name"),
@@ -818,7 +819,7 @@
   std::vector<FieldTypeValidityStatesMap> possible_field_types_validities;
   FormData form;
   form.url = GURL("http://www.foo.com/");
-  form.is_form_tag = true;
+  form.renderer_id = test::MakeFormRendererId();
 
   form.fields.push_back(CreateTestFormField("First Name", "firstname", "",
                                             FormControlType::kInputText,
@@ -1217,9 +1218,7 @@
                              {.label = u"First Name", .name = u"first"},
                              {.label = u"Last Name", .name = u"last"},
                              {.label = u"Email", .name = u"email"},
-
                          }});
-
   FormStructure form_structure(form);
   form_structure.set_submission_source(SubmissionSource::FORM_SUBMISSION);
   for (auto& fs_field : form_structure) {
@@ -1455,7 +1454,7 @@
                                     {.label = u"First Name", .name = u"first"},
                                     {.label = u"Last Name", .name = u"last"},
                                     {.label = u"Address", .name = u"address"}},
-                         .is_form_tag = false});
+                         .renderer_id = FormRendererId()});
   test::InitializePossibleTypesAndValidities(
       possible_field_types, possible_field_types_validities, {EMAIL_ADDRESS});
   test::InitializePossibleTypesAndValidities(
@@ -1568,9 +1567,10 @@
 
 TEST_F(AutofillCrowdsourcingEncoding, EncodeUploadRequest_IsFormTag) {
   for (bool is_form_tag : {false, true}) {
-    SCOPED_TRACE(testing::Message() << "is_form_tag=" << is_form_tag);
     FormData form = test::GetFormData(
-        {.fields = {{.name = u"email"}}, .is_form_tag = is_form_tag});
+        {.fields = {{.name = u"email"}},
+         .renderer_id =
+             is_form_tag ? test::MakeFormRendererId() : FormRendererId()});
 
     FormStructure form_structure(form);
     for (auto& fs_field : form_structure) {
diff --git a/components/autofill/core/browser/data_model/autofill_i18n_parsing_expressions.h b/components/autofill/core/browser/data_model/autofill_i18n_parsing_expressions.h
index d1a8c21..d55168d 100644
--- a/components/autofill/core/browser/data_model/autofill_i18n_parsing_expressions.h
+++ b/components/autofill/core/browser/data_model/autofill_i18n_parsing_expressions.h
@@ -29,14 +29,15 @@
 inline constexpr char kRegularExpression_5[] = "(?m)(?i:(?:(?:ponto de )?refer[êe]ncia(?::\\s*|\\s+)(?P<ADDRESS_HOME_LANDMARK>[^,\\n]+)))"; // nocheck
 inline constexpr char kRegularExpression_6[] = "(?m)(?i:(?P<ADDRESS_HOME_APT>(?P<ADDRESS_HOME_APT_TYPE>(?:apto\\.?|apt\\.?|apartamento|sala nº|sala|conjunto))?(?:(?:^|\\s+)(?P<ADDRESS_HOME_APT_NUM>(?:\\d+\\w?\\b|\\w\\b)))))"; // nocheck
 inline constexpr char kRegularExpression_7[] = "(?m)(?i:(?P<ADDRESS_HOME_STREET_LOCATION>\\A\\s*(?P<ADDRESS_HOME_STREET_NAME>(?:[^\\s,]+(?:[^\\S\\r\\n]+[^\\s,]+)*?))(?:(?:^|[,\\s]+)(?:(?:no|nr|°|º|nummer|number)[-.\\s]*)?(?P<ADDRESS_HOME_HOUSE_NUMBER>\\d+(?:\\s*[[:alpha:]]\\b|\\s*[\\/-]\\s*\\d+)?))))"; // nocheck
-inline constexpr char kRegularExpression_8[] = "(?m)(?i:(?P<ADDRESS_HOME_STREET_ADDRESS>(?P<ADDRESS_HOME_STREET_LOCATION>\\A\\s*(?P<ADDRESS_HOME_STREET_NAME>(?:[^\\s,]+(?:[^\\S\\r\\n]+[^\\s,]+)*?))(?:(?:^|[,\\s]+)(?:(?:no|nr|°|º|nummer|number)[-.\\s]*)?(?P<ADDRESS_HOME_HOUSE_NUMBER>\\d+(?:\\s*[[:alpha:]]\\b|\\s*[\\/-]\\s*\\d+)?)))(?:(?:^|[,\\s]+)(?P<ADDRESS_HOME_OVERFLOW>(?:[^\\s,]+(?:[^\\S\\r\\n]+[^\\s,]+)*?)))?))"; // nocheck
-inline constexpr char kRegularExpression_9[] = "(?m)(?i:(?P<ADDRESS_HOME_STREET_LOCATION>\\A\\s*(?P<ADDRESS_HOME_STREET_NAME>(?:calle\\s+\\d+\\s+[^\\d,\\n\\r]*?|(?:[^\\s,]+(?:[^\\S\\r\\n]+[^\\s,]+)*?)))(?:[,]?\\s+?(?:(?:#|No\\.?|número\\s)\\s*)?(?P<ADDRESS_HOME_HOUSE_NUMBER>(?:(?:S/Num\\.?|S/N|Sin Nombre)|(?:KM\\s+)?\\d+\\w?)))))"; // nocheck
-inline constexpr char kRegularExpression_10[] = "(?m)(?i:(?P<ADDRESS_HOME_APT>(?P<ADDRESS_HOME_APT_TYPE>(?:despacho|loc\\.?|local|int(?:erior|\\.?)|n[uú]m(?:ero|\\.)? int(?:erno|\\.)?|Apartamento|Apto\\.?|Departamento|apto\\.?))(?:(?:^|\\s+)(?P<ADDRESS_HOME_APT_NUM>(?:\\d+\\w?\\b|\\w\\b))\\b)))"; // nocheck
-inline constexpr char kRegularExpression_11[] = "(?m)(?i:(?:piso\\s*(?P<ADDRESS_HOME_FLOOR>\\d+)))"; // nocheck
-inline constexpr char kRegularExpression_12[] = "(?m)(?i:(?:\\b(?:x|Entre( Calles)?)\\s+(?P<ADDRESS_HOME_BETWEEN_STREETS>(?P<ADDRESS_HOME_BETWEEN_STREETS_1>(?:[^\\s,]+(?:[^\\S\\r\\n]+[^\\s,]+)*?))(?:\\s+y\\s+)(?P<ADDRESS_HOME_BETWEEN_STREETS_2>(?:[^,\\r\\n]+)))))"; // nocheck
-inline constexpr char kRegularExpression_13[] = "(?m)(?i:(?:(?:Cerca del)(?P<ADDRESS_HOME_LANDMARK>[^,\\n]+)))"; // nocheck
-inline constexpr char kRegularExpression_14[] = "(?m)(?i:(?P<ADDRESS_HOME_APT>(?P<ADDRESS_HOME_APT_TYPE>(?:despacho|loc\\.?|local|int(?:erior|\\.?)|n[uú]m(?:ero|\\.)? int(?:erno|\\.)?|Apartamento|Apto\\.?|Departamento|apto\\.?))?(?:(?:^|\\s+)(?P<ADDRESS_HOME_APT_NUM>(?:\\d+\\w?\\b|\\w\\b)))))"; // nocheck
-inline constexpr char kRegularExpression_15[] = "(?m)(?i:(?P<ADDRESS_HOME_STREET_ADDRESS>(?:(?:(?:((no|°|º|number)(\\.|-|\\s)*)?)(?P<ADDRESS_HOME_HOUSE_NUMBER>(?:\\d+\\w?))(th\\.|\\.)?)(?:(?:^|\\s+)(?P<ADDRESS_HOME_STREET_NAME>(?:[^\\s,]+(?:[^\\S\\r\\n]+[^\\s,]+)*?)))|(?P<ADDRESS_HOME_STREET_NAME__2>(?:[^\\s,]+(?:[^\\S\\r\\n]+[^\\s,]+)*?))(?:(?:^|[,\\s]+)(?:((no|°|º|number)(\\.|-|\\s)*)?)(?P<ADDRESS_HOME_HOUSE_NUMBER__2>(?:\\d+\\w?))(th\\.|\\.)?))(?:(?:^|[,\\s]+)(?P<ADDRESS_HOME_SUBPREMISE>(?:(?:(?:(?:(°|º|\\.|\\s|-)*(floor|flur|fl|og|obergeschoss|ug|untergeschoss|geschoss|andar|piso|º)(\\.|\\s|-)*)(?P<ADDRESS_HOME_FLOOR>(?:(\\d{0,3}\\w?))))|(?:(?P<ADDRESS_HOME_FLOOR__2>(?:(\\d{1,3}\\w?|\\w)))(?:(°|º|\\.|\\s|-)*(floor|flur|fl|og|obergeschoss|ug|untergeschoss|geschoss|andar|piso|º)(\\.|\\s|-)*)))(?:(?:^|[,\\s]+)(?:(?:(?:(apt|apartment|wohnung|apto|-)(\\.|\\s|-)*)(?P<ADDRESS_HOME_APT_NUM>(?:(\\d{0,3}\\w?))))|(?:(-\\s*)?(?P<ADDRESS_HOME_APT_NUM__2>(?:(\\d{1,3}\\w?|\\w)))(?:(\\.|\\s|-)*(ª)))?))?|(?:(?:(?:(apt|apartment|wohnung|apto|-)(\\.|\\s|-)*)(?P<ADDRESS_HOME_APT_NUM__3>(?:(\\d{0,3}\\w?))))|(?:(-\\s*)?(?P<ADDRESS_HOME_APT_NUM__4>(?:(\\d{1,3}\\w?|\\w)))(?:(\\.|\\s|-)*(ª)))?))))?))"; // nocheck
+inline constexpr char kRegularExpression_8[] = "(?m)(?i:(?P<ADDRESS_HOME_STREET_ADDRESS>(?P<ADDRESS_HOME_STREET_LOCATION>.*)\\n(?P<ADDRESS_HOME_OVERFLOW>[\\s\\S]+)))"; // nocheck
+inline constexpr char kRegularExpression_9[] = "(?m)(?i:(?P<ADDRESS_HOME_STREET_ADDRESS>(?P<ADDRESS_HOME_STREET_LOCATION>\\A\\s*(?P<ADDRESS_HOME_STREET_NAME>(?:[^\\s,]+(?:[^\\S\\r\\n]+[^\\s,]+)*?))(?:(?:^|[,\\s]+)(?:(?:no|nr|°|º|nummer|number)[-.\\s]*)?(?P<ADDRESS_HOME_HOUSE_NUMBER>\\d+(?:\\s*[[:alpha:]]\\b|\\s*[\\/-]\\s*\\d+)?)))(?:(?:^|[,\\s]+)(?P<ADDRESS_HOME_OVERFLOW>(?:[^\\s,]+(?:[^\\S\\r\\n]+[^\\s,]+)*?)))?))"; // nocheck
+inline constexpr char kRegularExpression_10[] = "(?m)(?i:(?P<ADDRESS_HOME_STREET_LOCATION>\\A\\s*(?P<ADDRESS_HOME_STREET_NAME>(?:calle\\s+\\d+\\s+[^\\d,\\n\\r]*?|(?:[^\\s,]+(?:[^\\S\\r\\n]+[^\\s,]+)*?)))(?:[,]?\\s+?(?:(?:#|No\\.?|número\\s)\\s*)?(?P<ADDRESS_HOME_HOUSE_NUMBER>(?:(?:S/Num\\.?|S/N|Sin Nombre)|(?:KM\\s+)?\\d+\\w?)))))"; // nocheck
+inline constexpr char kRegularExpression_11[] = "(?m)(?i:(?P<ADDRESS_HOME_APT>(?P<ADDRESS_HOME_APT_TYPE>(?:despacho|loc\\.?|local|int(?:erior|\\.?)|n[uú]m(?:ero|\\.)? int(?:erno|\\.)?|Apartamento|Apto\\.?|Departamento|apto\\.?))(?:(?:^|\\s+)(?P<ADDRESS_HOME_APT_NUM>(?:\\d+\\w?\\b|\\w\\b))\\b)))"; // nocheck
+inline constexpr char kRegularExpression_12[] = "(?m)(?i:(?:piso\\s*(?P<ADDRESS_HOME_FLOOR>\\d+)))"; // nocheck
+inline constexpr char kRegularExpression_13[] = "(?m)(?i:(?:\\b(?:x|Entre( Calles)?)\\s+(?P<ADDRESS_HOME_BETWEEN_STREETS>(?P<ADDRESS_HOME_BETWEEN_STREETS_1>(?:[^\\s,]+(?:[^\\S\\r\\n]+[^\\s,]+)*?))(?:\\s+y\\s+)(?P<ADDRESS_HOME_BETWEEN_STREETS_2>(?:[^,\\r\\n]+)))))"; // nocheck
+inline constexpr char kRegularExpression_14[] = "(?m)(?i:(?:(?:Cerca del)(?P<ADDRESS_HOME_LANDMARK>[^,\\n]+)))"; // nocheck
+inline constexpr char kRegularExpression_15[] = "(?m)(?i:(?P<ADDRESS_HOME_APT>(?P<ADDRESS_HOME_APT_TYPE>(?:despacho|loc\\.?|local|int(?:erior|\\.?)|n[uú]m(?:ero|\\.)? int(?:erno|\\.)?|Apartamento|Apto\\.?|Departamento|apto\\.?))?(?:(?:^|\\s+)(?P<ADDRESS_HOME_APT_NUM>(?:\\d+\\w?\\b|\\w\\b)))))"; // nocheck
+inline constexpr char kRegularExpression_16[] = "(?m)(?i:(?P<ADDRESS_HOME_STREET_ADDRESS>(?:(?:(?:((no|°|º|number)(\\.|-|\\s)*)?)(?P<ADDRESS_HOME_HOUSE_NUMBER>(?:\\d+\\w?))(th\\.|\\.)?)(?:(?:^|\\s+)(?P<ADDRESS_HOME_STREET_NAME>(?:[^\\s,]+(?:[^\\S\\r\\n]+[^\\s,]+)*?)))|(?P<ADDRESS_HOME_STREET_NAME__2>(?:[^\\s,]+(?:[^\\S\\r\\n]+[^\\s,]+)*?))(?:(?:^|[,\\s]+)(?:((no|°|º|number)(\\.|-|\\s)*)?)(?P<ADDRESS_HOME_HOUSE_NUMBER__2>(?:\\d+\\w?))(th\\.|\\.)?))(?:(?:^|[,\\s]+)(?P<ADDRESS_HOME_SUBPREMISE>(?:(?:(?:(?:(°|º|\\.|\\s|-)*(floor|flur|fl|og|obergeschoss|ug|untergeschoss|geschoss|andar|piso|º)(\\.|\\s|-)*)(?P<ADDRESS_HOME_FLOOR>(?:(\\d{0,3}\\w?))))|(?:(?P<ADDRESS_HOME_FLOOR__2>(?:(\\d{1,3}\\w?|\\w)))(?:(°|º|\\.|\\s|-)*(floor|flur|fl|og|obergeschoss|ug|untergeschoss|geschoss|andar|piso|º)(\\.|\\s|-)*)))(?:(?:^|[,\\s]+)(?:(?:(?:(apt|apartment|wohnung|apto|-)(\\.|\\s|-)*)(?P<ADDRESS_HOME_APT_NUM>(?:(\\d{0,3}\\w?))))|(?:(-\\s*)?(?P<ADDRESS_HOME_APT_NUM__2>(?:(\\d{1,3}\\w?|\\w)))(?:(\\.|\\s|-)*(ª)))?))?|(?:(?:(?:(apt|apartment|wohnung|apto|-)(\\.|\\s|-)*)(?P<ADDRESS_HOME_APT_NUM__3>(?:(\\d{0,3}\\w?))))|(?:(-\\s*)?(?P<ADDRESS_HOME_APT_NUM__4>(?:(\\d{1,3}\\w?|\\w)))(?:(\\.|\\s|-)*(ª)))?))))?))"; // nocheck
 
 
 // Section for singular decomposition(s).
@@ -46,9 +47,10 @@
     Decomposition(kRegularExpression_7, true, true),
     Decomposition(kRegularExpression_8, true, true),
     Decomposition(kRegularExpression_9, true, true),
-    Decomposition(kRegularExpression_12, true, true),
-    Decomposition(kRegularExpression_14, true, true),
+    Decomposition(kRegularExpression_10, true, true),
+    Decomposition(kRegularExpression_13, true, true),
     Decomposition(kRegularExpression_15, true, true),
+    Decomposition(kRegularExpression_16, true, true),
 };
 
 // Section for singular extract part(s).
@@ -58,14 +60,16 @@
     ExtractPart("", kRegularExpression_4),
     ExtractPart("", kRegularExpression_5),
     ExtractPart("", kRegularExpression_1),
-    ExtractPart("", kRegularExpression_10),
     ExtractPart("", kRegularExpression_11),
-    ExtractPart("", kRegularExpression_13),
     ExtractPart("", kRegularExpression_12),
-    ExtractPart("", kRegularExpression_9),
+    ExtractPart("", kRegularExpression_14),
+    ExtractPart("", kRegularExpression_13),
+    ExtractPart("", kRegularExpression_10),
 };
 
 // Section for decomposition cascades and their alternatives.
+inline constexpr AutofillParsingProcess const* kDecompositionCascade_0_Alternatives[]{ &kDecompositionList[3], &kDecompositionList[4]};
+inline constexpr DecompositionCascade kDecompositionCascade_0 = DecompositionCascade("", kDecompositionCascade_0_Alternatives);
 
 // Section for extract parts and their pieces.
 inline constexpr ExtractPart const* kExtractParts_0_Pieces[]{&kExtractPartList[0],&kExtractPartList[1],&kExtractPartList[2]};
@@ -96,15 +100,15 @@
       {{"BR", ADDRESS_HOME_STREET_ADDRESS}, &kExtractParts_3},
       {{"BR", ADDRESS_HOME_APT}, &kDecompositionList[1]},
       {{"DE", ADDRESS_HOME_STREET_LOCATION}, &kDecompositionList[2]},
-      {{"DE", ADDRESS_HOME_STREET_ADDRESS}, &kDecompositionList[3]},
-      {{"MX", ADDRESS_HOME_STREET_LOCATION}, &kDecompositionList[4]},
+      {{"DE", ADDRESS_HOME_STREET_ADDRESS}, &kDecompositionCascade_0},
+      {{"MX", ADDRESS_HOME_STREET_LOCATION}, &kDecompositionList[5]},
       {{"MX", ADDRESS_HOME_SUBPREMISE}, &kExtractParts_4},
-      {{"MX", ADDRESS_HOME_BETWEEN_STREETS}, &kDecompositionList[5]},
+      {{"MX", ADDRESS_HOME_BETWEEN_STREETS}, &kDecompositionList[6]},
       {{"MX", ADDRESS_HOME_BETWEEN_STREETS_OR_LANDMARK}, &kExtractParts_5},
       {{"MX", ADDRESS_HOME_OVERFLOW}, &kExtractParts_6},
       {{"MX", ADDRESS_HOME_STREET_ADDRESS}, &kExtractParts_7},
-      {{"MX", ADDRESS_HOME_APT}, &kDecompositionList[6]},
-      {{"XX", ADDRESS_HOME_STREET_ADDRESS}, &kDecompositionList[7]}
+      {{"MX", ADDRESS_HOME_APT}, &kDecompositionList[7]},
+      {{"XX", ADDRESS_HOME_STREET_ADDRESS}, &kDecompositionList[8]}
       });
 
 }  // namespace autofill::i18n_model_definition
diff --git a/components/autofill/core/browser/data_model/autofill_structured_address_unittest.cc b/components/autofill/core/browser/data_model/autofill_structured_address_unittest.cc
index 803cc03..6ddcf21 100644
--- a/components/autofill/core/browser/data_model/autofill_structured_address_unittest.cc
+++ b/components/autofill/core/browser/data_model/autofill_structured_address_unittest.cc
@@ -1545,6 +1545,18 @@
        .street_name = "Implerstr.",
        .house_number = "73",
        .overflow = "abcdefg"},
+      {.country_code = "DE",
+       .street_address = "Implerstr. nummer 73\nRückgebäude",
+       .street_location = "Implerstr. nummer 73",
+       .street_name = "Implerstr.",
+       .house_number = "73",
+       .overflow = "Rückgebäude"},
+      {.country_code = "DE",
+       .street_address = "Implerstr. nummer 73\nRückgebäude\nExtra info",
+       .street_location = "Implerstr. nummer 73",
+       .street_name = "Implerstr.",
+       .house_number = "73",
+       .overflow = "Rückgebäude\nExtra info"},
   };
 
   for (const auto& test_case : test_cases) {
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index 8231a5a..3624d7e9 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -124,7 +124,6 @@
       full_source_url_(form.full_url),
       target_url_(form.action),
       main_frame_origin_(form.main_frame_origin),
-      is_form_tag_(form.is_form_tag),
       all_fields_are_passwords_(!form.fields.empty()),
       form_parsed_timestamp_(base::TimeTicks::Now()),
       host_frame_(form.host_frame),
@@ -666,17 +665,17 @@
   FieldCandidatesMap field_type_map;
 
   if (ShouldRunHeuristics()) {
-    FormFieldParser::ParseFormFields(context, fields_, is_form_tag_,
+    FormFieldParser::ParseFormFields(context, fields_, is_form_element(),
                                      field_type_map);
   } else if (ShouldRunHeuristicsForSingleFieldForms()) {
-    FormFieldParser::ParseSingleFieldForms(context, fields_, is_form_tag_,
+    FormFieldParser::ParseSingleFieldForms(context, fields_, is_form_element(),
                                            field_type_map);
     FormFieldParser::ParseStandaloneCVCFields(context, fields_, field_type_map);
 
     // For standalone email fields inside a form tag, allow heuristics even
     // when the minimum number of fields is not met. See similar comments
     // in `FormFieldParser::ClearCandidatesIfHeuristicsDidNotFindEnoughFields`.
-    if (is_form_tag_ &&
+    if (is_form_element() &&
         base::FeatureList::IsEnabled(
             features::kAutofillEnableEmailHeuristicOnlyAddressForms)) {
       FormFieldParser::ParseStandaloneEmailFields(context, fields_,
@@ -749,6 +748,14 @@
   return active_field_count_;
 }
 
+bool FormStructure::is_form_element() const {
+  return !renderer_id_.is_null() ||
+         (!fields_.empty() &&
+          fields_.begin()->get()->form_control_type ==
+              FormControlType::kContentEditable &&
+          *fields_.begin()->get()->renderer_id == *renderer_id_);
+}
+
 FormData FormStructure::ToFormData() const {
   FormData data;
   data.id_attribute = id_attribute_;
@@ -759,7 +766,6 @@
   data.full_url = full_source_url_;
   data.action = target_url_;
   data.main_frame_origin = main_frame_origin_;
-  data.is_form_tag = is_form_tag_;
   data.renderer_id = renderer_id_;
   data.host_frame = host_frame_;
   data.version = version_;
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h
index e3f3c76..dd987f168 100644
--- a/components/autofill/core/browser/form_structure.h
+++ b/components/autofill/core/browser/form_structure.h
@@ -295,7 +295,8 @@
 
   bool has_password_field() const { return has_password_field_; }
 
-  bool is_form_tag() const { return is_form_tag_; }
+  // Returns whether the form comes from an HTML form with a <form> tag.
+  bool is_form_element() const;
 
   void set_submission_event(mojom::SubmissionIndicatorEvent submission_event) {
     submission_event_ = submission_event;
@@ -500,9 +501,6 @@
   // True if the form contains at least one password field.
   bool has_password_field_ = false;
 
-  // True if the form is a <form>.
-  bool is_form_tag_ = true;
-
   // True if all form fields are password fields.
   bool all_fields_are_passwords_ = false;
 
diff --git a/components/autofill/core/browser/metrics/form_events/form_event_logger_base.cc b/components/autofill/core/browser/metrics/form_events/form_event_logger_base.cc
index 308221b..0eec313 100644
--- a/components/autofill/core/browser/metrics/form_events/form_event_logger_base.cc
+++ b/components/autofill/core/browser/metrics/form_events/form_event_logger_base.cc
@@ -49,7 +49,7 @@
   // applicable must be inside a form tag, must not run heuristics normally
   // (i.e., their field count is below `kMinRequiredFieldsForHeuristics`), but
   // must be eligible for single field form heuristics.
-  if (!form.is_form_tag() || form.ShouldRunHeuristics() ||
+  if (!form.is_form_element() || form.ShouldRunHeuristics() ||
       !form.ShouldRunHeuristicsForSingleFieldForms()) {
     return false;
   }
diff --git a/components/autofill/core/browser/metrics/form_events/form_event_logger_base_unittest.cc b/components/autofill/core/browser/metrics/form_events/form_event_logger_base_unittest.cc
index 4f7d5e4..0fa8d13 100644
--- a/components/autofill/core/browser/metrics/form_events/form_event_logger_base_unittest.cc
+++ b/components/autofill/core/browser/metrics/form_events/form_event_logger_base_unittest.cc
@@ -14,6 +14,7 @@
 #include "components/autofill/core/browser/metrics/ukm_metrics_test_utils.h"
 #include "components/autofill/core/common/autofill_features.h"
 #include "components/autofill/core/common/form_data.h"
+#include "components/autofill/core/common/unique_ids.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -570,7 +571,7 @@
 
   // Set the form to appear outside a <form> tag, which means it is not eligible
   // for the email heuristic only metric.
-  form_.is_form_tag = false;
+  form_.renderer_id = FormRendererId();
 
   // Simulate that suggestion is shown and user accepts it.
   SeeForm(form_);
diff --git a/components/autofill/core/browser/payments/account_info_getter.h b/components/autofill/core/browser/payments/account_info_getter.h
index 3655752..67165473 100644
--- a/components/autofill/core/browser/payments/account_info_getter.h
+++ b/components/autofill/core/browser/payments/account_info_getter.h
@@ -23,7 +23,7 @@
   // feature enabled. This value should be exclusively used for metrics only
   // or in the communication with the payments server, if this communication
   // only influences metrics.
-  // TODO(crbug.com/1462552): Simplify once ConsentLevel::kSync and
+  // TODO(crbug.com/40066949): Simplify once ConsentLevel::kSync and
   // SyncService::IsSyncFeatureEnabled() are deleted from the codebase.
   virtual bool IsSyncFeatureEnabledForPaymentsServerMetrics() const = 0;
 
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index c5c0049..4bf623a4 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -612,7 +612,7 @@
   // feature explicitly. `sync_service` is nullptr-checked because this
   // method can also be used (apart from the Sync service observer's calls) in
   // SetSyncService() where setting a nullptr is possible.
-  // TODO(crbug.com/1462552): Simplify once ConsentLevel::kSync and
+  // TODO(crbug.com/40066949): Simplify once ConsentLevel::kSync and
   // SyncService::IsSyncFeatureEnabled() are deleted from the codebase.
   database_helper_->SetUseAccountStorageForServerData(
       sync_service && !sync_service->IsSyncFeatureEnabled());
@@ -653,7 +653,7 @@
 }
 
 bool PersonalDataManager::IsSyncFeatureEnabledForPaymentsServerMetrics() const {
-  // TODO(crbug.com/1462552): Simplify once ConsentLevel::kSync and
+  // TODO(crbug.com/40066949): Simplify once ConsentLevel::kSync and
   // SyncService::IsSyncFeatureEnabled() are deleted from the codebase.
   return sync_service_ && sync_service_->IsSyncFeatureEnabled();
 }
@@ -681,7 +681,7 @@
           syncer::SyncService::TransportState::PAUSED) {
     return false;
   }
-  // TODO(crbug.com/1462552): Simplify (merge with
+  // TODO(crbug.com/40066949): Simplify (merge with
   // IsPaymentsWalletSyncTransportEnabled()) once ConsentLevel::kSync and
   // SyncService::IsSyncFeatureEnabled() are deleted from the codebase.
   return sync_service_->IsSyncFeatureEnabled() ||
@@ -695,7 +695,7 @@
           syncer::SyncService::TransportState::PAUSED) {
     return false;
   }
-  // TODO(crbug.com/1462552): Simplify (merge with IsPaymentsDownloadActive())
+  // TODO(crbug.com/40066949): Simplify (merge with IsPaymentsDownloadActive())
   // once ConsentLevel::kSync and SyncService::IsSyncFeatureEnabled() are
   // deleted from the codebase.
   return !sync_service_->IsSyncFeatureEnabled() &&
@@ -718,7 +718,7 @@
   }
 
   // Check if the user has turned on sync.
-  // TODO(crbug.com/1462552): Simplify once ConsentLevel::kSync and
+  // TODO(crbug.com/40066949): Simplify once ConsentLevel::kSync and
   // SyncService::IsSyncFeatureEnabled() are deleted from the codebase.
   if (sync_service_->IsSyncFeatureEnabled()) {
     return PaymentsSigninState::kSignedInAndSyncFeatureEnabled;
@@ -1551,7 +1551,7 @@
   CHECK(sync_service_);
 
   // Check if the user is in sync transport mode for wallet data.
-  // TODO(crbug.com/1462552): Simplify once ConsentLevel::kSync and
+  // TODO(crbug.com/40066949): Simplify once ConsentLevel::kSync and
   // SyncService::IsSyncFeatureEnabled() are deleted from the codebase.
   if (!sync_service_->IsSyncFeatureEnabled()) {
     // For SyncTransport, only show server payment methods if the user has opted
@@ -1769,7 +1769,7 @@
 }
 
 bool PersonalDataManager::IsSyncFeatureEnabledForAutofill() const {
-  // TODO(crbug.com/1462552): Remove this method in favor of
+  // TODO(crbug.com/40066949): Remove this method in favor of
   // `IsUserSelectableTypeEnabled` once ConsentLevel::kSync and
   // SyncService::IsSyncFeatureEnabled() are deleted from the codebase.
   return sync_service_ != nullptr && sync_service_->IsSyncFeatureEnabled() &&
@@ -2301,7 +2301,7 @@
     BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_FUCHSIA)
   // This option should only be shown for users that have not enabled the Sync
   // Feature and that have server credit cards available.
-  // TODO(crbug.com/1462552): Simplify once ConsentLevel::kSync and
+  // TODO(crbug.com/40066949): Simplify once ConsentLevel::kSync and
   // SyncService::IsSyncFeatureEnabled() are deleted from the codebase.
   if (!sync_service_ || sync_service_->IsSyncFeatureEnabled() ||
       GetServerCreditCards().empty()) {
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h
index dbd161a..1cf3dd8 100644
--- a/components/autofill/core/browser/personal_data_manager.h
+++ b/components/autofill/core/browser/personal_data_manager.h
@@ -656,7 +656,7 @@
 
   // Returns true if Sync-the-feature is enabled and
   // UserSelectableType::kAutofill is among the user's selected data types.
-  // TODO(crbug.com/1462552): Remove this method once ConsentLevel::kSync and
+  // TODO(crbug.com/40066949): Remove this method once ConsentLevel::kSync and
   // SyncService::IsSyncFeatureEnabled() are deleted from the codebase.
   bool IsSyncFeatureEnabledForAutofill() const;
 
diff --git a/components/autofill/core/common/form_data.cc b/components/autofill/core/common/form_data.cc
index a7e0af54..c9c268a3 100644
--- a/components/autofill/core/common/form_data.cc
+++ b/components/autofill/core/common/form_data.cc
@@ -20,7 +20,7 @@
 
 namespace {
 
-const int kFormDataPickleVersion = 7;
+const int kFormDataPickleVersion = 8;
 
 bool ReadGURL(base::PickleIterator* iter, GURL* url) {
   std::string spec;
@@ -97,9 +97,11 @@
 bool FormData::SameFormAs(const FormData& form) const {
   if (name != form.name || id_attribute != form.id_attribute ||
       name_attribute != form.name_attribute || url != form.url ||
-      action != form.action || is_form_tag != form.is_form_tag ||
-      fields.size() != form.fields.size())
+      action != form.action ||
+      renderer_id.is_null() != form.renderer_id.is_null() ||
+      fields.size() != form.fields.size()) {
     return false;
+  }
   for (size_t i = 0; i < fields.size(); ++i) {
     if (!fields[i].SameFieldAs(form.fields[i]))
       return false;
@@ -119,7 +121,7 @@
 
   if (a.name != b.name || a.id_attribute != b.id_attribute ||
       a.name_attribute != b.name_attribute || a.url != b.url ||
-      a.action != b.action || a.is_form_tag != b.is_form_tag ||
+      a.action != b.action ||
       !base::ranges::equal(a.fields, b.fields, &FormFieldData::DeepEqual)) {
     return false;
   }
@@ -150,8 +152,7 @@
 
 std::ostream& operator<<(std::ostream& os, const FormData& form) {
   os << base::UTF16ToUTF8(form.name) << " " << form.url << " " << form.action
-     << " " << form.main_frame_origin << " " << form.is_form_tag << " "
-     << "Fields:";
+     << " " << form.main_frame_origin << " " << "Fields:";
   for (const FormFieldData& field : form.fields) {
     os << field << ",";
   }
@@ -182,7 +183,6 @@
   pickle->WriteString(form_data.url.spec());
   pickle->WriteString(form_data.action.spec());
   SerializeFormFieldDataVector(form_data.fields, pickle);
-  pickle->WriteBool(form_data.is_form_tag);
   pickle->WriteString(form_data.main_frame_origin.Serialize());
 }
 
@@ -222,13 +222,12 @@
     return false;
   }
 
-  if (version >= 3) {
-    if (!iter->ReadBool(&temp_form_data.is_form_tag)) {
+  if (version >= 3 && version <= 7) {
+    bool temp_bool = false;
+    if (!iter->ReadBool(&temp_bool)) {
       LogDeserializationError(version);
       return false;
     }
-  } else {
-    form_data->is_form_tag = true;
   }
 
   if (version >= 5 && version <= 6) {
@@ -263,7 +262,6 @@
   buffer << Tr{} << "URL:" << form.url;
   buffer << Tr{} << "Action:" << form.action;
   buffer << Tr{} << "Is action empty:" << form.is_action_empty;
-  buffer << Tr{} << "Is <form> tag:" << form.is_form_tag;
   for (size_t i = 0; i < form.fields.size(); ++i) {
     buffer << Tag{"tr"};
     buffer << Tag{"td"} << "Field " << i << ": " << CTag{};
diff --git a/components/autofill/core/common/form_data.h b/components/autofill/core/common/form_data.h
index c814c660..55cf69e 100644
--- a/components/autofill/core/common/form_data.h
+++ b/components/autofill/core/common/form_data.h
@@ -220,9 +220,6 @@
   // trees. For details, see RenderFrameHost::GetMainFrame().
   url::Origin main_frame_origin;
 
-  // True if this form is a form tag.
-  bool is_form_tag = true;
-
   // A unique identifier of the containing frame. This value is not serialized
   // because LocalFrameTokens must not be leaked to other renderer processes.
   LocalFrameToken host_frame;
diff --git a/components/autofill/core/common/form_data_fuzzed_producer.cc b/components/autofill/core/common/form_data_fuzzed_producer.cc
index 4a88824..41cdd7d 100644
--- a/components/autofill/core/common/form_data_fuzzed_producer.cc
+++ b/components/autofill/core/common/form_data_fuzzed_producer.cc
@@ -36,8 +36,6 @@
 FormData GenerateFormData(FuzzedDataProvider& provider) {
   FormData result;
 
-  result.is_form_tag = provider.ConsumeBool();
-
   // Determine how many fields this form will have. Pick a low value because
   // after the fuzzer's seed is exhausted, all will be 0s anyway.
   const size_t number_of_fields =
diff --git a/components/autofill/core/common/form_data_unittest.cc b/components/autofill/core/common/form_data_unittest.cc
index cbd535315..c153aa3 100644
--- a/components/autofill/core/common/form_data_unittest.cc
+++ b/components/autofill/core/common/form_data_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/pickle.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/autofill/core/common/form_field_data.h"
+#include "components/autofill/core/common/unique_ids.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace autofill {
@@ -57,7 +58,7 @@
   for (size_t i = 0; i < form_data.fields.size(); ++i) {
     SerializeFormFieldData(form_data.fields[i], pickle);
   }
-  pickle->WriteBool(form_data.is_form_tag);
+  pickle->WriteBool(false);  // Used to be `is_form_tag`, which was removed
 }
 
 void SerializeInVersion4Format(const FormData& form_data,
@@ -70,7 +71,7 @@
   for (size_t i = 0; i < form_data.fields.size(); ++i) {
     SerializeFormFieldData(form_data.fields[i], pickle);
   }
-  pickle->WriteBool(form_data.is_form_tag);
+  pickle->WriteBool(false);  // Used to be `is_form_tag`, which was removed
 }
 
 void SerializeInVersion5Format(const FormData& form_data,
@@ -83,7 +84,7 @@
   for (size_t i = 0; i < form_data.fields.size(); ++i) {
     SerializeFormFieldData(form_data.fields[i], pickle);
   }
-  pickle->WriteBool(form_data.is_form_tag);
+  pickle->WriteBool(false);  // Used to be `is_form_tag`, which was removed
   pickle->WriteBool(/*is_formless_checkout=*/true);
 }
 
@@ -97,7 +98,7 @@
   for (size_t i = 0; i < form_data.fields.size(); ++i) {
     SerializeFormFieldData(form_data.fields[i], pickle);
   }
-  pickle->WriteBool(form_data.is_form_tag);
+  pickle->WriteBool(false);  // Used to be `is_form_tag`, which was removed
   pickle->WriteBool(/*is_formless_checkout=*/true);
   pickle->WriteString(form_data.main_frame_origin.Serialize());
 }
@@ -112,7 +113,20 @@
   for (size_t i = 0; i < form_data.fields.size(); ++i) {
     SerializeFormFieldData(form_data.fields[i], pickle);
   }
-  pickle->WriteBool(form_data.is_form_tag);
+  pickle->WriteBool(false);  // Used to be `is_form_tag`, which was removed
+  pickle->WriteString(form_data.main_frame_origin.Serialize());
+}
+
+void SerializeInVersion8Format(const FormData& form_data,
+                               base::Pickle* pickle) {
+  pickle->WriteInt(8);
+  pickle->WriteString16(form_data.name);
+  pickle->WriteString(form_data.url.spec());
+  pickle->WriteString(form_data.action.spec());
+  pickle->WriteInt(static_cast<int>(form_data.fields.size()));
+  for (size_t i = 0; i < form_data.fields.size(); ++i) {
+    SerializeFormFieldData(form_data.fields[i], pickle);
+  }
   pickle->WriteString(form_data.main_frame_origin.Serialize());
 }
 
@@ -135,7 +149,6 @@
   data->action = GURL("https://example.com/action");
   data->main_frame_origin =
       url::Origin::Create(GURL("https://origin-example.com"));
-  data->is_form_tag = true;            // Default value.
 
   FormFieldData field_data;
   field_data.label = u"label";
@@ -220,7 +233,7 @@
 TEST(FormDataTest, Serialize_v3_Deserialize_vCurrent_IsFormTagFalse) {
   FormData data;
   FillInDummyFormData(&data);
-  data.is_form_tag = false;
+  data.renderer_id = FormRendererId();
 
   base::Pickle pickle;
   SerializeInVersion3Format(data, &pickle);
@@ -288,6 +301,20 @@
   EXPECT_TRUE(actual.SameFormAs(data));
 }
 
+TEST(FormDataTest, Serialize_v8_Deserialize_vCurrent) {
+  FormData data;
+  FillInDummyFormData(&data);
+
+  base::Pickle pickle;
+  SerializeInVersion8Format(data, &pickle);
+
+  base::PickleIterator iter(pickle);
+  FormData actual;
+  EXPECT_TRUE(DeserializeFormData(&iter, &actual));
+
+  EXPECT_TRUE(actual.SameFormAs(data));
+}
+
 TEST(FormDataTest, SerializeIncorrectFormatAndDeserialize) {
   FormData data;
   FillInDummyFormData(&data);
diff --git a/components/autofill/core/common/mojom/autofill_types.mojom b/components/autofill/core/common/mojom/autofill_types.mojom
index 832dac2..fd781a2 100644
--- a/components/autofill/core/common/mojom/autofill_types.mojom
+++ b/components/autofill/core/common/mojom/autofill_types.mojom
@@ -414,7 +414,6 @@
   array<ButtonTitleInfo> button_titles;
   url.mojom.Url action;
   bool is_action_empty;
-  bool is_form_tag;
   FormRendererId renderer_id;
   array<FrameTokenWithPredecessor> child_frames;
   SubmissionIndicatorEvent submission_event;
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 40a6b04f..23fc463 100644
--- a/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc
+++ b/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc
@@ -296,8 +296,6 @@
     return false;
   out->is_action_empty = data.is_action_empty();
 
-  out->is_form_tag = data.is_form_tag();
-
   if (!data.ReadRendererId(&out->renderer_id)) {
     return false;
   }
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 5c7ab2bd..806282e8 100644
--- a/components/autofill/core/common/mojom/autofill_types_mojom_traits.h
+++ b/components/autofill/core/common/mojom/autofill_types_mojom_traits.h
@@ -417,8 +417,6 @@
     return r.is_action_empty;
   }
 
-  static bool is_form_tag(const autofill::FormData& r) { return r.is_form_tag; }
-
   static autofill::FormRendererId renderer_id(const autofill::FormData& r) {
     return r.renderer_id;
   }
diff --git a/components/autofill/core/common/save_password_progress_logger.cc b/components/autofill/core/common/save_password_progress_logger.cc
index 9288ea6..79c4e75e 100644
--- a/components/autofill/core/common/save_password_progress_logger.cc
+++ b/components/autofill/core/common/save_password_progress_logger.cc
@@ -65,10 +65,7 @@
   message += GetStringFromID(STRING_FORM_NAME) + ": " +
              ScrubElementID(form_data.name) + "\n";
 
-  message += GetStringFromID(STRING_IS_FORM_TAG) + ": " +
-             (form_data.is_form_tag ? "true" : "false") + "\n";
-
-  if (form_data.is_form_tag) {
+  if (!form_data.renderer_id.is_null()) {
     message +=
         "Form renderer id: " + NumberToString(form_data.renderer_id.value()) +
         "\n";
diff --git a/components/autofill/ios/browser/autofill_util.mm b/components/autofill/ios/browser/autofill_util.mm
index 00950ac2..05a6dfa5 100644
--- a/components/autofill/ios/browser/autofill_util.mm
+++ b/components/autofill/ios/browser/autofill_util.mm
@@ -223,8 +223,6 @@
   if (const std::string* id_attribute = form.FindString("id_attribute")) {
     form_data->id_attribute = base::UTF8ToUTF16(*id_attribute);
   }
-  form_data->is_form_tag =
-      form.FindBool("is_form_tag").value_or(form_data->is_form_tag);
 
   if (include_frame_metadata) {
     // Child frame tokens, optional.
diff --git a/components/autofill/ios/form_util/resources/fill.ts b/components/autofill/ios/form_util/resources/fill.ts
index 246289f..6df5e6d 100644
--- a/components/autofill/ios/form_util/resources/fill.ts
+++ b/components/autofill/ios/form_util/resources/fill.ts
@@ -658,7 +658,6 @@
   form.name = '';
   form.origin = gCrWeb.common.removeQueryAndReferenceFromURL(frame.origin);
   form.action = '';
-  form.is_form_tag = false;
 
   if (!restrictUnownedFieldsToFormlessCheckout) {
     // TODO(crbug.com/1440471): Pass iframe elements.
diff --git a/components/autofill/ios/form_util/resources/fill_util.ts b/components/autofill/ios/form_util/resources/fill_util.ts
index dccba0a3..2d3fda2 100644
--- a/components/autofill/ios/form_util/resources/fill_util.ts
+++ b/components/autofill/ios/form_util/resources/fill_util.ts
@@ -64,7 +64,6 @@
   child_frames?: FrameTokenWithPredecessor[];
   name_attribute?: string;
   id_attribute?: string;
-  is_form_tag: boolean;
 }
 
 declare interface FrameTokenWithPredecessor {
diff --git a/components/browsing_data/core/browsing_data_utils_unittest.cc b/components/browsing_data/core/browsing_data_utils_unittest.cc
index bc5adc5..2fcff39d 100644
--- a/components/browsing_data/core/browsing_data_utils_unittest.cc
+++ b/components/browsing_data/core/browsing_data_utils_unittest.cc
@@ -105,8 +105,11 @@
   auto store = base::MakeRefCounted<password_manager::TestPasswordStore>();
   store->Init(prefs(), /*affiliated_match_helper=*/nullptr);
   PasswordsCounter counter(
-      scoped_refptr<password_manager::PasswordStoreInterface>(store), nullptr,
-      nullptr);
+      /*profile_store=*/scoped_refptr<password_manager::PasswordStoreInterface>(
+          store),
+      /*account_store=*/nullptr,
+      /*pref_service=*/nullptr,
+      /*sync_service=*/nullptr);
 
   // Use a separate struct for input to make test cases easier to read after
   // auto formatting.
diff --git a/components/browsing_data/core/counters/passwords_counter.cc b/components/browsing_data/core/counters/passwords_counter.cc
index 72c1f95..cde24b7 100644
--- a/components/browsing_data/core/counters/passwords_counter.cc
+++ b/components/browsing_data/core/counters/passwords_counter.cc
@@ -11,6 +11,7 @@
 #include "base/functional/bind.h"
 #include "base/scoped_observation.h"
 #include "base/time/time.h"
+#include "build/build_config.h"
 #include "components/browsing_data/core/pref_names.h"
 #include "components/password_manager/core/browser/password_manager_client.h"
 #include "components/password_manager/core/browser/password_store/password_store_change.h"
@@ -20,13 +21,26 @@
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 #include "url/gurl.h"
 
+#if BUILDFLAG(IS_ANDROID)
+#include "components/password_manager/core/browser/password_store/split_stores_and_local_upm.h"
+#endif  // BUILDFLAG(IS_ANDROID)
+
 namespace browsing_data {
 namespace {
 
 // This predicate is only about profile (non-account) passwords, so it is only
 // concerned about whether sync-the-feature is on or off. Account passwords are
 // counted separately.
-bool IsProfilePasswordSyncEnabled(const syncer::SyncService* sync_service) {
+bool IsProfilePasswordSyncEnabled(PrefService* pref_service,
+                                  const syncer::SyncService* sync_service) {
+#if BUILDFLAG(IS_ANDROID)
+  // If UsesSplitStoresAndUPMForLocal() is true, the profile store is never
+  // synced, only the account store is.
+  if (password_manager::UsesSplitStoresAndUPMForLocal(pref_service)) {
+    return false;
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
+
   // TODO(crbug.com/1464264): Migrate away from `ConsentLevel::kSync` on desktop
   // platforms, including APIs that depend on sync-the-feature.
   return password_manager::sync_util::IsSyncFeatureActiveIncludingPasswords(
@@ -188,8 +202,9 @@
 PasswordsCounter::PasswordsCounter(
     scoped_refptr<password_manager::PasswordStoreInterface> profile_store,
     scoped_refptr<password_manager::PasswordStoreInterface> account_store,
+    PrefService* pref_service,
     syncer::SyncService* sync_service)
-    : sync_tracker_(this, sync_service) {
+    : sync_tracker_(this, sync_service), pref_service_(pref_service) {
   profile_store_fetcher_ = std::make_unique<PasswordStoreFetcher>(
       profile_store,
       base::BindRepeating(&PasswordsCounter::Restart, base::Unretained(this))),
@@ -219,7 +234,7 @@
 
 void PasswordsCounter::OnInitialized() {
   sync_tracker_.OnInitialized(
-      base::BindRepeating(&IsProfilePasswordSyncEnabled));
+      base::BindRepeating(&IsProfilePasswordSyncEnabled, pref_service_));
 }
 
 const char* PasswordsCounter::GetPrefName() const {
diff --git a/components/browsing_data/core/counters/passwords_counter.h b/components/browsing_data/core/counters/passwords_counter.h
index 4792da2..92c5f21 100644
--- a/components/browsing_data/core/counters/passwords_counter.h
+++ b/components/browsing_data/core/counters/passwords_counter.h
@@ -14,6 +14,8 @@
 #include "components/browsing_data/core/counters/sync_tracker.h"
 #include "components/password_manager/core/browser/password_store/password_store_consumer.h"
 
+class PrefService;
+
 namespace password_manager {
 class PasswordStoreInterface;
 }
@@ -58,6 +60,7 @@
   PasswordsCounter(
       scoped_refptr<password_manager::PasswordStoreInterface> profile_store,
       scoped_refptr<password_manager::PasswordStoreInterface> account_store,
+      PrefService* pref_service,
       syncer::SyncService* sync_service);
   ~PasswordsCounter() override;
 
@@ -84,6 +87,8 @@
   SyncTracker sync_tracker_;
   int remaining_tasks_ = 0;
 
+  const raw_ptr<PrefService> pref_service_;
+
   base::WeakPtrFactory<PasswordsCounter> weak_ptr_factory_{this};
 };
 
diff --git a/components/commerce/core/account_checker.cc b/components/commerce/core/account_checker.cc
index a371f5147..ef8f6a6 100644
--- a/components/commerce/core/account_checker.cc
+++ b/components/commerce/core/account_checker.cc
@@ -67,7 +67,7 @@
            identity_manager_->HasPrimaryAccount(signin::ConsentLevel::kSignin);
   }
   // The feature is not enabled, fallback to old behavior.
-  // TODO(crbug.com/1462978): Delete ConsentLevel::kSync usage once
+  // TODO(crbug.com/40067058): Delete ConsentLevel::kSync usage once
   // kReplaceSyncPromosWithSignInPromos is launched on all platforms. See
   // ConsentLevel::kSync documentation for details.
   return identity_manager_ &&
@@ -82,7 +82,7 @@
                                 syncer::UploadState::ACTIVE;
   }
   // The feature is not enabled, fallback to old behavior.
-  // TODO(crbug.com/1462978): Delete IsSyncFeatureActive() usage once
+  // TODO(crbug.com/40067058): Delete IsSyncFeatureActive() usage once
   // kReplaceSyncPromosWithSignInPromos is launched on all platforms. See
   // ConsentLevel::kSync documentation for details.
   return sync_service_ && sync_service_->IsSyncFeatureActive() &&
@@ -286,7 +286,7 @@
     const base::TimeDelta& timeout,
     const std::string& post_data,
     const net::NetworkTrafficAnnotationTag& annotation_tag) {
-  // TODO(crbug.com/1462978): Delete ConsentLevel::kSync usage once
+  // TODO(crbug.com/40067058): Delete ConsentLevel::kSync usage once
   // kReplaceSyncPromosWithSignInPromos is launched on all platforms. See
   // ConsentLevel::kSync documentation for details.
   signin::ConsentLevel consent_level =
diff --git a/components/commerce/core/shopping_service.h b/components/commerce/core/shopping_service.h
index d8f253e..73ab7cfe 100644
--- a/components/commerce/core/shopping_service.h
+++ b/components/commerce/core/shopping_service.h
@@ -335,7 +335,7 @@
   // and sync opt-in state, returns either LocalOrSyncable or Account bookmark
   // model instance.
   //
-  // TODO(crbug.com/1462978): Delete this when ConsentLevel::kSync is deleted.
+  // TODO(crbug.com/40067058): Delete this when ConsentLevel::kSync is deleted.
   //     See ConsentLevel::kSync documentation for details.
   virtual bookmarks::BookmarkModel* GetBookmarkModelUsedForSync();
 
@@ -710,7 +710,7 @@
   // The object for local extractions of commerce information.
   std::unique_ptr<commerce::WebExtractor> web_extractor_;
 
-  // TODO(crbug.com/1462978): Delete this when ConsentLevel::kSync is deleted.
+  // TODO(crbug.com/40067058): Delete this when ConsentLevel::kSync is deleted.
   //     See ConsentLevel::kSync documentation for details.
   base::ScopedObservation<syncer::SyncService, syncer::SyncServiceObserver>
       sync_service_observation_{this};
diff --git a/components/commerce/core/subscriptions/subscriptions_manager.h b/components/commerce/core/subscriptions/subscriptions_manager.h
index 94cd1d6..2d980f72 100644
--- a/components/commerce/core/subscriptions/subscriptions_manager.h
+++ b/components/commerce/core/subscriptions/subscriptions_manager.h
@@ -123,7 +123,7 @@
   // new calls for this method - this as temporary flow to support switching
   // BookmarkModel instances.
   //
-  // TODO(crbug.com/1462978): Delete this when ConsentLevel::kSync is deleted.
+  // TODO(crbug.com/40067058): Delete this when ConsentLevel::kSync is deleted.
   //     See ConsentLevel::kSync documentation for details.
   void WipeStorageAndSyncSubscriptions();
 
diff --git a/components/component_updater/android/BUILD.gn b/components/component_updater/android/BUILD.gn
index a637e43..4c37e2ef 100644
--- a/components/component_updater/android/BUILD.gn
+++ b/components/component_updater/android/BUILD.gn
@@ -110,6 +110,8 @@
 
 static_library("loader_policies") {
   sources = [
+    "loader_policies/first_party_sets_component_loader_policy.cc",
+    "loader_policies/first_party_sets_component_loader_policy.h",
     "loader_policies/masked_domain_list_component_loader_policy.cc",
     "loader_policies/masked_domain_list_component_loader_policy.h",
     "loader_policies/tpcd_metadata_component_loader_policy.cc",
diff --git a/components/component_updater/android/loader_policies/first_party_sets_component_loader_policy.cc b/components/component_updater/android/loader_policies/first_party_sets_component_loader_policy.cc
new file mode 100644
index 0000000..df65667e
--- /dev/null
+++ b/components/component_updater/android/loader_policies/first_party_sets_component_loader_policy.cc
@@ -0,0 +1,70 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/component_updater/android/loader_policies/first_party_sets_component_loader_policy.h"
+
+#include <cstdint>
+#include <optional>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/containers/flat_map.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_file.h"
+#include "base/logging.h"
+#include "base/task/thread_pool.h"
+#include "base/version.h"
+#include "components/component_updater/android/component_loader_policy.h"
+#include "components/component_updater/installer_policies/first_party_sets_component_installer_policy.h"
+
+namespace {
+
+// Persisted to logs, should never change.
+constexpr char kFirstPartySetsComponentMetricsSuffix[] = "RelatedWebsiteSets";
+
+}  // namespace
+
+namespace component_updater {
+
+FirstPartySetComponentLoaderPolicy::FirstPartySetComponentLoaderPolicy(
+    SetsReadyOnceCallback on_sets_ready)
+    : on_sets_ready_(std::move(on_sets_ready)) {}
+
+FirstPartySetComponentLoaderPolicy::~FirstPartySetComponentLoaderPolicy() =
+    default;
+
+void FirstPartySetComponentLoaderPolicy::ComponentLoaded(
+    const base::Version& version,
+    base::flat_map<std::string, base::ScopedFD>& fd_map,
+    base::Value::Dict manifest) {
+  auto keys_fd_iterator = fd_map.find(kFpsMetadataComponentFileName);
+  if (keys_fd_iterator == fd_map.end()) {
+    VLOG(1) << "FirstPartySetComponentLoaderPolicy#ComponentLoaded "
+               "failed because sets.json is not found in the fd map";
+    std::move(on_sets_ready_).Run(base::Version(), base::File());
+    return;
+  }
+  std::move(on_sets_ready_)
+      .Run(version, base::File(std::move(keys_fd_iterator->second)));
+}
+
+void FirstPartySetComponentLoaderPolicy::ComponentLoadFailed(
+    ComponentLoadResult /*error*/) {
+  // If the component did not load, we must still inform the rest of Chromium
+  // that we have finished attempting to load the component so that it can stop
+  // blocking on this.
+  std::move(on_sets_ready_).Run(base::Version(), base::File());
+}
+
+void FirstPartySetComponentLoaderPolicy::GetHash(
+    std::vector<uint8_t>* hash) const {
+  FirstPartySetsComponentInstallerPolicy::GetPublicKeyHash(hash);
+}
+
+std::string FirstPartySetComponentLoaderPolicy::GetMetricsSuffix() const {
+  return kFirstPartySetsComponentMetricsSuffix;
+}
+
+}  // namespace component_updater
diff --git a/components/component_updater/android/loader_policies/first_party_sets_component_loader_policy.h b/components/component_updater/android/loader_policies/first_party_sets_component_loader_policy.h
new file mode 100644
index 0000000..8f4d7d8
--- /dev/null
+++ b/components/component_updater/android/loader_policies/first_party_sets_component_loader_policy.h
@@ -0,0 +1,51 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_COMPONENT_UPDATER_ANDROID_LOADER_POLICIES_FIRST_PARTY_SETS_COMPONENT_LOADER_POLICY_H_
+#define COMPONENTS_COMPONENT_UPDATER_ANDROID_LOADER_POLICIES_FIRST_PARTY_SETS_COMPONENT_LOADER_POLICY_H_
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+#include "base/containers/flat_map.h"
+#include "base/files/scoped_file.h"
+#include "base/values.h"
+#include "base/version.h"
+#include "components/component_updater/android/component_loader_policy.h"
+#include "components/component_updater/installer_policies/first_party_sets_component_installer_policy.h"
+
+namespace component_updater {
+class FirstPartySetComponentLoaderPolicy : public ComponentLoaderPolicy {
+ public:
+  using SetsReadyOnceCallback = component_updater::
+      FirstPartySetsComponentInstallerPolicy::SetsReadyOnceCallback;
+
+  // `on_sets_ready` will be called on the UI thread when we either have sets,
+  // or know we won't get them.
+  explicit FirstPartySetComponentLoaderPolicy(
+      SetsReadyOnceCallback on_sets_ready);
+  ~FirstPartySetComponentLoaderPolicy() override;
+
+  FirstPartySetComponentLoaderPolicy(
+      const FirstPartySetComponentLoaderPolicy&) = delete;
+  FirstPartySetComponentLoaderPolicy& operator=(
+      const FirstPartySetComponentLoaderPolicy&) = delete;
+
+ private:
+  // The following methods override ComponentLoaderPolicy.
+  void ComponentLoaded(const base::Version& version,
+                       base::flat_map<std::string, base::ScopedFD>& fd_map,
+                       base::Value::Dict manifest) override;
+  void ComponentLoadFailed(ComponentLoadResult error) override;
+  void GetHash(std::vector<uint8_t>* hash) const override;
+  std::string GetMetricsSuffix() const override;
+
+  SetsReadyOnceCallback on_sets_ready_;
+};
+
+}  // namespace component_updater
+
+#endif  // COMPONENTS_COMPONENT_UPDATER_ANDROID_LOADER_POLICIES_FIRST_PARTY_SETS_COMPONENT_LOADER_POLICY_H_
diff --git a/components/component_updater/installer_policies/BUILD.gn b/components/component_updater/installer_policies/BUILD.gn
index 631cd05..933aa8b 100644
--- a/components/component_updater/installer_policies/BUILD.gn
+++ b/components/component_updater/installer_policies/BUILD.gn
@@ -16,6 +16,8 @@
   sources = [
     "autofill_states_component_installer.cc",
     "autofill_states_component_installer.h",
+    "first_party_sets_component_installer_policy.cc",
+    "first_party_sets_component_installer_policy.h",
     "masked_domain_list_component_installer_policy.cc",
     "masked_domain_list_component_installer_policy.h",
     "origin_trials_component_installer.cc",
@@ -65,6 +67,7 @@
   testonly = true
   sources = [
     "autofill_states_component_installer_unittest.cc",
+    "first_party_sets_component_installer_policy_unittest.cc",
     "masked_domain_list_component_installer_policy_unittest.cc",
     "optimization_hints_component_installer_unittest.cc",
     "tpcd_metadata_component_installer_policy_unittest.cc",
diff --git a/components/component_updater/installer_policies/first_party_sets_component_installer_policy.cc b/components/component_updater/installer_policies/first_party_sets_component_installer_policy.cc
new file mode 100644
index 0000000..faa0f701
--- /dev/null
+++ b/components/component_updater/installer_policies/first_party_sets_component_installer_policy.cc
@@ -0,0 +1,204 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/component_updater/installer_policies/first_party_sets_component_installer_policy.h"
+
+#include <optional>
+#include <utility>
+
+#include "base/files/file.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "base/no_destructor.h"
+#include "base/path_service.h"
+#include "base/task/thread_pool.h"
+#include "base/version.h"
+#include "components/component_updater/component_installer.h"
+#include "components/component_updater/component_updater_paths.h"
+#include "net/cookies/cookie_util.h"
+
+using component_updater::ComponentUpdateService;
+
+namespace {
+
+using SetsReadyOnceCallback = component_updater::
+    FirstPartySetsComponentInstallerPolicy::SetsReadyOnceCallback;
+
+// The SHA256 of the SubjectPublicKeyInfo used to sign the component.
+// The extension id is: gonpemdgkjcecdgbnaabipppbmgfggbe
+constexpr uint8_t kFirstPartySetsPublicKeySHA256[32] = {
+    0x6e, 0xdf, 0x4c, 0x36, 0xa9, 0x24, 0x23, 0x61, 0xd0, 0x01, 0x8f,
+    0xff, 0x1c, 0x65, 0x66, 0x14, 0xa8, 0x46, 0x37, 0xe6, 0xeb, 0x80,
+    0x8b, 0x8f, 0xb0, 0xb6, 0x18, 0xa7, 0xcd, 0x3d, 0xbb, 0xfb};
+
+constexpr char kFirstPartySetsManifestName[] = "Related Website Sets";
+
+constexpr base::FilePath::CharType kFirstPartySetsRelativeInstallDir[] =
+    FILE_PATH_LITERAL("FirstPartySetsPreloaded");
+
+base::File OpenFile(const base::FilePath& pb_path) {
+  return base::File(pb_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
+}
+
+std::optional<std::pair<base::FilePath, base::Version>>&
+GetConfigPathInstance() {
+  // Contains nullopt until registration is complete. Afterward, contains the
+  // FilePath and version for the component file, or empty FilePath and version
+  // if no component was installed at startup.
+  static base::NoDestructor<
+      std::optional<std::pair<base::FilePath, base::Version>>>
+      instance;
+  return *instance;
+}
+
+// Invokes `on_sets_ready`, if:
+// * First-Party Sets is enabled; and
+// * `on_sets_ready` is not null.
+//
+// If the component has been installed and can be read, we pass the component
+// file; otherwise, we pass an invalid file.
+void SetFirstPartySetsConfig(SetsReadyOnceCallback on_sets_ready,
+                             base::TaskPriority priority) {
+  if (on_sets_ready.is_null()) {
+    return;
+  }
+
+  const std::optional<std::pair<base::FilePath, base::Version>>& instance_path =
+      GetConfigPathInstance();
+  if (!instance_path.has_value()) {
+    // Registration not is complete yet. The policy's `on_sets_ready_` callback
+    // will still be invoked once registration is done, so we don't bother to
+    // save or invoke `on_sets_ready`.
+    return;
+  }
+
+  if (instance_path->first.empty()) {
+    // Registration is complete, but no component version exists on disk.
+    CHECK(!instance_path->second.IsValid());
+    std::move(on_sets_ready).Run(base::Version(), base::File());
+    return;
+  }
+
+  base::ThreadPool::PostTaskAndReplyWithResult(
+      FROM_HERE, {base::MayBlock(), priority},
+      base::BindOnce(&OpenFile, instance_path->first),
+      base::BindOnce(std::move(on_sets_ready), instance_path->second));
+}
+
+}  // namespace
+
+namespace component_updater {
+
+void FirstPartySetsComponentInstallerPolicy::OnRegistrationComplete() {
+  if (!GetConfigPathInstance().has_value()) {
+    GetConfigPathInstance() = std::make_pair(base::FilePath(), base::Version());
+  }
+  SetFirstPartySetsConfig(std::move(on_sets_ready_), priority_);
+}
+
+FirstPartySetsComponentInstallerPolicy::FirstPartySetsComponentInstallerPolicy(
+    SetsReadyOnceCallback on_sets_ready,
+    base::TaskPriority priority)
+    : on_sets_ready_(std::move(on_sets_ready)), priority_(priority) {}
+
+FirstPartySetsComponentInstallerPolicy::
+    ~FirstPartySetsComponentInstallerPolicy() = default;
+
+bool FirstPartySetsComponentInstallerPolicy::
+    SupportsGroupPolicyEnabledComponentUpdates() const {
+  return true;
+}
+
+bool FirstPartySetsComponentInstallerPolicy::RequiresNetworkEncryption() const {
+  // Update checks and pings associated with this component do not require
+  // confidentiality, since the component is identical for all users.
+  return false;
+}
+
+update_client::CrxInstaller::Result
+FirstPartySetsComponentInstallerPolicy::OnCustomInstall(
+    const base::Value::Dict& manifest,
+    const base::FilePath& install_dir) {
+  return update_client::CrxInstaller::Result(0);  // Nothing custom here.
+}
+
+void FirstPartySetsComponentInstallerPolicy::OnCustomUninstall() {}
+
+base::FilePath FirstPartySetsComponentInstallerPolicy::GetInstalledPath(
+    const base::FilePath& base) {
+  return base.Append(kFpsMetadataComponentFileName);
+}
+
+void FirstPartySetsComponentInstallerPolicy::ComponentReady(
+    const base::Version& version,
+    const base::FilePath& install_dir,
+    base::Value::Dict manifest) {
+  if (install_dir.empty() || GetConfigPathInstance().has_value()) {
+    return;
+  }
+
+  VLOG(1) << "Related Website Sets Component ready, version "
+          << version.GetString() << " in " << install_dir.value();
+
+  GetConfigPathInstance() =
+      std::make_pair(GetInstalledPath(install_dir), version);
+
+  SetFirstPartySetsConfig(std::move(on_sets_ready_), priority_);
+}
+
+// Called during startup and installation before ComponentReady().
+bool FirstPartySetsComponentInstallerPolicy::VerifyInstallation(
+    const base::Value::Dict& manifest,
+    const base::FilePath& install_dir) const {
+  // No need to actually validate the sets here, since we'll do the validation
+  // in the Network Service.
+  return base::PathExists(GetInstalledPath(install_dir));
+}
+
+base::FilePath FirstPartySetsComponentInstallerPolicy::GetRelativeInstallDir()
+    const {
+  return base::FilePath(kFirstPartySetsRelativeInstallDir);
+}
+
+// static
+void FirstPartySetsComponentInstallerPolicy::GetPublicKeyHash(
+    std::vector<uint8_t>* hash) {
+  hash->assign(kFirstPartySetsPublicKeySHA256,
+               kFirstPartySetsPublicKeySHA256 +
+                   std::size(kFirstPartySetsPublicKeySHA256));
+}
+
+void FirstPartySetsComponentInstallerPolicy::GetHash(
+    std::vector<uint8_t>* hash) const {
+  GetPublicKeyHash(hash);
+}
+
+std::string FirstPartySetsComponentInstallerPolicy::GetName() const {
+  return kFirstPartySetsManifestName;
+}
+
+update_client::InstallerAttributes
+FirstPartySetsComponentInstallerPolicy::GetInstallerAttributes() const {
+  return {};
+}
+
+// static
+void FirstPartySetsComponentInstallerPolicy::ResetForTesting() {
+  GetConfigPathInstance().reset();
+}
+
+// static
+void FirstPartySetsComponentInstallerPolicy::WriteComponentForTesting(
+    base::Version version,
+    const base::FilePath& install_dir,
+    base::StringPiece contents) {
+  CHECK(base::WriteFile(GetInstalledPath(install_dir), contents));
+
+  GetConfigPathInstance() =
+      std::make_pair(GetInstalledPath(install_dir), std::move(version));
+}
+
+}  // namespace component_updater
diff --git a/components/component_updater/installer_policies/first_party_sets_component_installer_policy.h b/components/component_updater/installer_policies/first_party_sets_component_installer_policy.h
new file mode 100644
index 0000000..4acabdd5
--- /dev/null
+++ b/components/component_updater/installer_policies/first_party_sets_component_installer_policy.h
@@ -0,0 +1,109 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_COMPONENT_UPDATER_INSTALLER_POLICIES_FIRST_PARTY_SETS_COMPONENT_INSTALLER_POLICY_H_
+#define COMPONENTS_COMPONENT_UPDATER_INSTALLER_POLICIES_FIRST_PARTY_SETS_COMPONENT_INSTALLER_POLICY_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/files/file.h"
+#include "base/functional/callback.h"
+#include "base/gtest_prod_util.h"
+#include "base/strings/string_piece.h"
+#include "base/values.h"
+#include "base/version.h"
+#include "components/component_updater/component_installer.h"
+
+namespace base {
+class FilePath;
+}  // namespace base
+
+namespace component_updater {
+
+inline constexpr base::FilePath::CharType kFpsMetadataComponentFileName[] =
+    FILE_PATH_LITERAL("sets.json");
+
+class FirstPartySetsComponentInstallerPolicy : public ComponentInstallerPolicy {
+ public:
+  using SetsReadyOnceCallback =
+      base::OnceCallback<void(base::Version, base::File)>;
+
+  // `on_sets_ready` will be called on the UI thread when the sets are ready. It
+  // is exposed here for testing.
+  explicit FirstPartySetsComponentInstallerPolicy(
+      SetsReadyOnceCallback on_sets_ready,
+      base::TaskPriority priority);
+  ~FirstPartySetsComponentInstallerPolicy() override;
+
+  FirstPartySetsComponentInstallerPolicy(
+      const FirstPartySetsComponentInstallerPolicy&) = delete;
+  FirstPartySetsComponentInstallerPolicy operator=(
+      const FirstPartySetsComponentInstallerPolicy&) = delete;
+
+  void OnRegistrationComplete();
+
+  // Resets static state. Should only be used to clear state during testing.
+  static void ResetForTesting();
+
+  // Seeds a component at `install_dir` with the given `contents`. Only to be
+  // used in testing.
+  static void WriteComponentForTesting(base::Version version,
+                                       const base::FilePath& install_dir,
+                                       base::StringPiece contents);
+
+  static base::FilePath GetInstalledPathForTesting(const base::FilePath& base) {
+    return GetInstalledPath(base);
+  }
+
+  void ComponentReadyForTesting(const base::Version& version,
+                                const base::FilePath& install_dir,
+                                base::Value::Dict manifest) {
+    ComponentReady(version, install_dir, std::move(manifest));
+  }
+
+  update_client::InstallerAttributes GetInstallerAttributesForTesting() const {
+    return GetInstallerAttributes();
+  }
+
+  // Returns the component's SHA2 hash as raw bytes.
+  static void GetPublicKeyHash(std::vector<uint8_t>* hash);
+
+ private:
+  // The following methods override ComponentInstallerPolicy.
+  bool SupportsGroupPolicyEnabledComponentUpdates() const override;
+  bool RequiresNetworkEncryption() const override;
+  update_client::CrxInstaller::Result OnCustomInstall(
+      const base::Value::Dict& manifest,
+      const base::FilePath& install_dir) override;
+  void OnCustomUninstall() override;
+  bool VerifyInstallation(const base::Value::Dict& manifest,
+                          const base::FilePath& install_dir) const override;
+  // After the first call, ComponentReady will be no-op for new versions
+  // delivered from Component Updater, i.e. new components will be installed
+  // (kept on-disk) but not propagated to the NetworkService until next
+  // browser startup.
+  void ComponentReady(const base::Version& version,
+                      const base::FilePath& install_dir,
+                      base::Value::Dict manifest) override;
+  base::FilePath GetRelativeInstallDir() const override;
+  void GetHash(std::vector<uint8_t>* hash) const override;
+  std::string GetName() const override;
+  update_client::InstallerAttributes GetInstallerAttributes() const override;
+
+  static base::FilePath GetInstalledPath(const base::FilePath& base);
+
+  // We use a OnceCallback to ensure we only pass along the sets file once
+  // during Chromium's lifetime.
+  SetsReadyOnceCallback on_sets_ready_;
+
+  base::TaskPriority priority_;
+};
+
+}  // namespace component_updater
+
+#endif  // COMPONENTS_COMPONENT_UPDATER_INSTALLER_POLICIES_FIRST_PARTY_SETS_COMPONENT_INSTALLER_POLICY_H_
diff --git a/chrome/browser/component_updater/first_party_sets_component_installer_unittest.cc b/components/component_updater/installer_policies/first_party_sets_component_installer_policy_unittest.cc
similarity index 87%
rename from chrome/browser/component_updater/first_party_sets_component_installer_unittest.cc
rename to components/component_updater/installer_policies/first_party_sets_component_installer_policy_unittest.cc
index 73b5659..b1084c8c 100644
--- a/chrome/browser/component_updater/first_party_sets_component_installer_unittest.cc
+++ b/components/component_updater/installer_policies/first_party_sets_component_installer_policy_unittest.cc
@@ -1,20 +1,19 @@
-// Copyright 2020 The Chromium Authors
+// Copyright 2024 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/component_updater/first_party_sets_component_installer.h"
+#include "components/component_updater/installer_policies/first_party_sets_component_installer_policy.h"
 
 #include "base/check.h"
 #include "base/files/file.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/functional/callback_helpers.h"
+#include "base/task/thread_pool.h"
 #include "base/test/task_environment.h"
 #include "base/test/test_future.h"
 #include "base/version.h"
-#include "chrome/browser/first_party_sets/scoped_mock_first_party_sets_handler.h"
 #include "components/component_updater/mock_component_updater_service.h"
-#include "content/public/common/content_features.h"
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -48,8 +47,6 @@
   base::test::TaskEnvironment env_;
 
   base::ScopedTempDir component_install_dir_;
-  first_party_sets::ScopedMockFirstPartySetsHandler
-      mock_first_party_sets_handler_;
 };
 
 TEST_F(FirstPartySetsComponentInstallerTest, NonexistentFile_OnComponentReady) {
@@ -58,7 +55,8 @@
           component_install_dir_.GetPath())));
 
   base::test::TestFuture<base::Version, base::File> future;
-  FirstPartySetsComponentInstallerPolicy(future.GetCallback())
+  FirstPartySetsComponentInstallerPolicy(future.GetCallback(),
+                                         base::TaskPriority::USER_BLOCKING)
       .ComponentReadyForTesting(base::Version(),
                                 component_install_dir_.GetPath(),
                                 base::Value::Dict());
@@ -75,7 +73,8 @@
           component_install_dir_.GetPath())));
 
   base::test::TestFuture<base::Version, base::File> future;
-  FirstPartySetsComponentInstallerPolicy policy(future.GetCallback());
+  FirstPartySetsComponentInstallerPolicy policy(
+      future.GetCallback(), base::TaskPriority::USER_BLOCKING);
   policy.OnRegistrationComplete();
 
   std::tuple<base::Version, base::File> got = future.Take();
@@ -92,7 +91,7 @@
   const std::string expectation = "some first party sets";
   base::test::TestFuture<base::Version, base::File> future;
   auto policy = std::make_unique<FirstPartySetsComponentInstallerPolicy>(
-      future.GetCallback());
+      future.GetCallback(), base::TaskPriority::USER_BLOCKING);
 
   ASSERT_TRUE(base::WriteFile(
       FirstPartySetsComponentInstallerPolicy::GetInstalledPathForTesting(
@@ -114,7 +113,8 @@
 // the OnceCallback.
 TEST_F(FirstPartySetsComponentInstallerTest, IgnoreNewSets_NoInitialComponent) {
   base::test::TestFuture<base::Version, base::File> future;
-  FirstPartySetsComponentInstallerPolicy policy(future.GetCallback());
+  FirstPartySetsComponentInstallerPolicy policy(
+      future.GetCallback(), base::TaskPriority::USER_BLOCKING);
 
   policy.OnRegistrationComplete();
   std::tuple<base::Version, base::File> got = future.Take();
@@ -139,7 +139,8 @@
 // newer versions are installed.
 TEST_F(FirstPartySetsComponentInstallerTest, IgnoreNewSets_OnComponentReady) {
   base::test::TestFuture<base::Version, base::File> future;
-  FirstPartySetsComponentInstallerPolicy policy(future.GetCallback());
+  FirstPartySetsComponentInstallerPolicy policy(
+      future.GetCallback(), base::TaskPriority::USER_BLOCKING);
 
   const base::Version version = base::Version("0.0.1");
   const std::string sets_v1 = "first party sets v1";
@@ -176,7 +177,8 @@
 }
 
 TEST_F(FirstPartySetsComponentInstallerTest, GetInstallerAttributes) {
-  FirstPartySetsComponentInstallerPolicy policy(base::DoNothing());
+  FirstPartySetsComponentInstallerPolicy policy(
+      base::DoNothing(), base::TaskPriority::USER_BLOCKING);
 
   EXPECT_THAT(policy.GetInstallerAttributesForTesting(), IsEmpty());
 }
diff --git a/components/content_settings/core/browser/cookie_settings_unittest.cc b/components/content_settings/core/browser/cookie_settings_unittest.cc
index f12727e..26148be6 100644
--- a/components/content_settings/core/browser/cookie_settings_unittest.cc
+++ b/components/content_settings/core/browser/cookie_settings_unittest.cc
@@ -60,15 +60,30 @@
     "API.StorageAccess.AllowedRequests2";
 #endif
 
-// NOTE: Consider modifying services/network/cookie_settings_unittest.cc if
-// applicable.
-enum TestVariables {
-  kTopLevelStorageAccessGrantEligible = 0,
+// To avoid an explosion of test cases, please don't just add a boolean to
+// the test features. Consider whether features can interact with each other and
+// whether you really need all combinations.
+
+// Controls features that can unblock 3p cookies.
+enum GrantSource {
+  // Not eligible for additional grants.
+  kNoneGranted,
+  // Eligible for StorageAccess grants.
   kStorageAccessGrantsEligible,
+  // Eligible for TopLevelStorageAccess grants.
+  kTopLevelStorageAccessGrantsEligible,
   // Whether `net::features::kTpcdTrialSettings` is enabled.
   k3pcdTrialEligible,
   // Whether `net::features::kTpcdMetadataGrants` is enabled.
   kTpcdMetadataGrantsEligible,
+
+  kGrantSourceCount
+};
+
+// NOTE: Consider modifying services/network/cookie_settings_unittest.cc if
+// applicable.
+enum TestVariables {
+  kGrantSource,
   // Whether `content_settings_features::kHostIndexedMetadataGrants` is enabled
   kIndexedContentSettings,
 };
@@ -207,10 +222,7 @@
 class CookieSettingsTest
     : public CookieSettingsTestBase,
       public testing::TestWithParam<
-          std::tuple</*kStorageAccessGrantsEligible*/ bool,
-                     /*kTopLevelStorageAccessGrantEligible*/ bool,
-                     /*k3pcdTrialEligible*/ bool,
-                     /*kTpcdMetadataGrantsEligible*/ bool,
+          std::tuple</*kGrantSource*/ GrantSource,
                      /*kHostIndexedMetadataGrantsEnabled*/ bool>> {
  public:
   CookieSettingsTest() {
@@ -252,20 +264,23 @@
   void SetUp() override { CookieSettingsTestBase::SetUp(); }
 
   bool IsStorageAccessGrantEligible() const {
-    return std::get<TestVariables::kStorageAccessGrantsEligible>(GetParam());
+    return std::get<TestVariables::kGrantSource>(GetParam()) ==
+           GrantSource::kStorageAccessGrantsEligible;
   }
 
   bool IsTopLevelStorageAccessGrantEligible() const {
-    return std::get<TestVariables::kTopLevelStorageAccessGrantEligible>(
-        GetParam());
+    return std::get<TestVariables::kGrantSource>(GetParam()) ==
+           GrantSource::kTopLevelStorageAccessGrantsEligible;
   }
 
   bool Is3pcdTrialEligible() const {
-    return std::get<TestVariables::k3pcdTrialEligible>(GetParam());
+    return std::get<TestVariables::kGrantSource>(GetParam()) ==
+           GrantSource::k3pcdTrialEligible;
   }
 
   bool Is3pcdMetadataGrantEligible() const {
-    return std::get<TestVariables::kTpcdMetadataGrantsEligible>(GetParam());
+    return std::get<TestVariables::kGrantSource>(GetParam()) ==
+           GrantSource::kTpcdMetadataGrantsEligible;
   }
 
   bool IsIndexedContentSettingsEnabled() const {
@@ -1888,15 +1903,9 @@
   std::stringstream custom_test_name;
   // clang-format off
   custom_test_name
-      << "TopLevelStorageAccessGrantEligible_"
-      << std::get<TestVariables::kTopLevelStorageAccessGrantEligible>(
+      << "GrantSource_"
+      << std::get<TestVariables::kGrantSource>(
              info.param)
-      << "_StorageAccessGrantsEligible_"
-      << std::get<TestVariables::kStorageAccessGrantsEligible>(info.param)
-      << "_3pcdTrialEligible_"
-      << std::get<TestVariables::k3pcdTrialEligible>(info.param)
-      << "_TpcdMetadataGrantsEligible_"
-      << std::get<TestVariables::kTpcdMetadataGrantsEligible>(info.param)
       << "_HostIndexedMetadataGrantsEnabled_"
       << std::get<TestVariables::kIndexedContentSettings>(info.param);
   // clang-format on
@@ -1906,37 +1915,27 @@
 INSTANTIATE_TEST_SUITE_P(
     /* no prefix */,
     CookieSettingsTest,
-    testing::Combine(testing::Bool(),
+    testing::Combine(
 #if BUILDFLAG(IS_IOS)
-                     testing::Values(false),
-                     testing::Values(false),
-                     testing::Values(false),
-                     testing::Values(false)
+        testing::Values(GrantSource::kNoneGranted),
 #else
-                     testing::Bool(),
-                     testing::Bool(),
-                     testing::Bool(),
-                     testing::Bool()
+        testing::Range(GrantSource::kNoneGranted,
+                       GrantSource::kGrantSourceCount),
 #endif
-                         ),
+        testing::Bool()),
     CustomTestName);
 
 INSTANTIATE_TEST_SUITE_P(
     /* no prefix */,
     CookieSettingsTestUserBypass,
-    testing::Combine(testing::Bool(),
+    testing::Combine(
 #if BUILDFLAG(IS_IOS)
-                     testing::Values(false),
-                     testing::Values(false),
-                     testing::Values(false),
-                     testing::Values(false)
+        testing::Values(GrantSource::kNoneGranted),
 #else
-                     testing::Bool(),
-                     testing::Bool(),
-                     testing::Bool(),
-                     testing::Bool()
+        testing::Range(GrantSource::kNoneGranted,
+                       GrantSource::kGrantSourceCount),
 #endif
-                         ),
+        testing::Bool()),
     CustomTestName);
 
 #if !BUILDFLAG(IS_IOS)
diff --git a/components/facilitated_payments/DIR_METADATA b/components/facilitated_payments/DIR_METADATA
index 53ab283..360c6927 100644
--- a/components/facilitated_payments/DIR_METADATA
+++ b/components/facilitated_payments/DIR_METADATA
@@ -1,4 +1,7 @@
-monorail {
+monorail: {
   component: "Blink>Payments"
 }
 team_email: "payments-dev@chromium.org"
+buganizer_public: {
+  component_id: 1456412
+}
diff --git a/components/favicon/DIR_METADATA b/components/favicon/DIR_METADATA
index 9b08ae7f..38f4bc1 100644
--- a/components/favicon/DIR_METADATA
+++ b/components/favicon/DIR_METADATA
@@ -1,3 +1,6 @@
-monorail {
+monorail: {
   component: "UI>Browser>History"
 }
+buganizer_public: {
+  component_id: 1456716
+}
diff --git a/components/favicon_base/DIR_METADATA b/components/favicon_base/DIR_METADATA
index 9b08ae7f..38f4bc1 100644
--- a/components/favicon_base/DIR_METADATA
+++ b/components/favicon_base/DIR_METADATA
@@ -1,3 +1,6 @@
-monorail {
+monorail: {
   component: "UI>Browser>History"
 }
+buganizer_public: {
+  component_id: 1456716
+}
diff --git a/components/filename_generation/DIR_METADATA b/components/filename_generation/DIR_METADATA
index 6bf7cbf..2873170 100644
--- a/components/filename_generation/DIR_METADATA
+++ b/components/filename_generation/DIR_METADATA
@@ -1,3 +1,6 @@
-monorail {
+monorail: {
   component: "UI>Browser>Downloads"
 }
+buganizer_public: {
+  component_id: 1457176
+}
diff --git a/components/find_in_page/DIR_METADATA b/components/find_in_page/DIR_METADATA
index 831a23a2..a14b63e8 100644
--- a/components/find_in_page/DIR_METADATA
+++ b/components/find_in_page/DIR_METADATA
@@ -1,3 +1,6 @@
-monorail {
+monorail: {
   component: "UI>Browser>FindInPage"
 }
+buganizer_public: {
+  component_id: 1457177
+}
diff --git a/components/flags_ui/COMMON_METADATA b/components/flags_ui/COMMON_METADATA
index 8325efa..613ca0c 100644
--- a/components/flags_ui/COMMON_METADATA
+++ b/components/flags_ui/COMMON_METADATA
@@ -1,3 +1,6 @@
-monorail {
+monorail: {
   component: "UI>Browser>WebUI"
 }
+buganizer_public: {
+  component_id: 1457323
+}
diff --git a/components/fullscreen_control/DIR_METADATA b/components/fullscreen_control/DIR_METADATA
index 9719bd8..e773b40 100644
--- a/components/fullscreen_control/DIR_METADATA
+++ b/components/fullscreen_control/DIR_METADATA
@@ -1,3 +1,6 @@
-monorail {
+monorail: {
   component: "UI>Browser"
 }
+buganizer_public: {
+  component_id: 1457469
+}
diff --git a/components/fullscreen_control_strings_grdp/DIR_METADATA b/components/fullscreen_control_strings_grdp/DIR_METADATA
index 9719bd8..e773b40 100644
--- a/components/fullscreen_control_strings_grdp/DIR_METADATA
+++ b/components/fullscreen_control_strings_grdp/DIR_METADATA
@@ -1,3 +1,6 @@
-monorail {
+monorail: {
   component: "UI>Browser"
 }
+buganizer_public: {
+  component_id: 1457469
+}
diff --git a/components/gcm_driver/DIR_METADATA b/components/gcm_driver/DIR_METADATA
index fd2070a..4b8996e7 100644
--- a/components/gcm_driver/DIR_METADATA
+++ b/components/gcm_driver/DIR_METADATA
@@ -1,4 +1,7 @@
-monorail {
+monorail: {
   component: "Services>CloudMessaging"
 }
 team_email: "platform-capabilities@chromium.org"
+buganizer_public: {
+  component_id: 1456167
+}
diff --git a/components/global_media_controls/DIR_METADATA b/components/global_media_controls/DIR_METADATA
index 5655fca0..69ade52 100644
--- a/components/global_media_controls/DIR_METADATA
+++ b/components/global_media_controls/DIR_METADATA
@@ -2,3 +2,6 @@
   component: "Internals>Media>UI"
 }
 team_email: "media-dev@chromium.org"
+buganizer_public: {
+  component_id: 1456838
+}
diff --git a/components/google/DIR_METADATA b/components/google/DIR_METADATA
index 25ed5eec..205e8a5 100644
--- a/components/google/DIR_METADATA
+++ b/components/google/DIR_METADATA
@@ -1,5 +1,7 @@
-monorail {
+monorail: {
   component: "Internals"
 }
-
 team_email: "chromium-dev@chromium.org"
+buganizer_public: {
+  component_id: 1456292
+}
diff --git a/components/grpc_support/DIR_METADATA b/components/grpc_support/DIR_METADATA
index 9e5f77e..7de334dcb 100644
--- a/components/grpc_support/DIR_METADATA
+++ b/components/grpc_support/DIR_METADATA
@@ -1,5 +1,7 @@
-monorail {
+monorail: {
   component: "Internals>Network>Library"
 }
-
 team_email: "net-dev@chromium.org"
+buganizer_public: {
+  component_id: 1456244
+}
diff --git a/components/gwp_asan/DIR_METADATA b/components/gwp_asan/DIR_METADATA
index 6b8ed80..03dad34 100644
--- a/components/gwp_asan/DIR_METADATA
+++ b/components/gwp_asan/DIR_METADATA
@@ -1,3 +1,6 @@
-monorail {
+monorail: {
   component: "Internals>Instrumentation"
 }
+buganizer_public: {
+  component_id: 1456524
+}
diff --git a/components/history_embeddings/BUILD.gn b/components/history_embeddings/BUILD.gn
index f66c1f44..d28b2cc 100644
--- a/components/history_embeddings/BUILD.gn
+++ b/components/history_embeddings/BUILD.gn
@@ -8,17 +8,23 @@
     "history_embeddings_features.h",
     "history_embeddings_service.cc",
     "history_embeddings_service.h",
+    "vector_database.cc",
+    "vector_database.h",
   ]
 
   deps = [
     "//base",
     "//components/keyed_service/core",
+    "//url",
   ]
 }
 
 source_set("unit_tests") {
   testonly = true
-  sources = [ "history_embeddings_service_unittest.cc" ]
+  sources = [
+    "history_embeddings_service_unittest.cc",
+    "vector_database_unittest.cc",
+  ]
   deps = [
     ":history_embeddings",
     "//base/test:test_support",
diff --git a/components/history_embeddings/DEPS b/components/history_embeddings/DEPS
index f0bf3d9..d1bd861 100644
--- a/components/history_embeddings/DEPS
+++ b/components/history_embeddings/DEPS
@@ -1,3 +1,4 @@
 include_rules = [
   "+components/keyed_service/core",
+  "+url",
 ]
diff --git a/components/history_embeddings/vector_database.cc b/components/history_embeddings/vector_database.cc
new file mode 100644
index 0000000..f59330a1
--- /dev/null
+++ b/components/history_embeddings/vector_database.cc
@@ -0,0 +1,94 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/history_embeddings/vector_database.h"
+
+#include <queue>
+
+namespace history_embeddings {
+
+namespace {}  // namespace
+
+Embedding::Embedding(std::vector<float> data) : data(std::move(data)) {}
+Embedding::~Embedding() = default;
+Embedding::Embedding(Embedding&&) = default;
+
+float Embedding::Magnitude() const {
+  float sum = 0.0f;
+  for (float s : data) {
+    sum += s * s;
+  }
+  return std::sqrt(sum);
+}
+
+void Embedding::Normalize() {
+  float magnitude = Magnitude();
+  for (float& s : data) {
+    s /= magnitude;
+  }
+}
+
+float Embedding::ScoreWith(const Embedding& other) const {
+  // Cardinality is always equal.
+  DCHECK_EQ(data.size(), other.data.size());
+
+  // Magnitudes are also assumed equal; they are provided normalized by design.
+  DCHECK_LT(std::abs(Magnitude() - other.Magnitude()), 0.01f);
+
+  float score = 0.0f;
+  for (size_t i = 0; i < data.size(); i++) {
+    score += data[i] * other.data[i];
+  }
+  return score;
+}
+
+UrlEmbeddings::UrlEmbeddings() = default;
+UrlEmbeddings::~UrlEmbeddings() = default;
+UrlEmbeddings::UrlEmbeddings(UrlEmbeddings&&) = default;
+
+float UrlEmbeddings::BestScoreWith(const Embedding& query) const {
+  float best = std::numeric_limits<float>::min();
+  for (const Embedding& embedding : embeddings) {
+    best = std::max(best, query.ScoreWith(embedding));
+  }
+  return best;
+}
+
+VectorDatabase::VectorDatabase() = default;
+VectorDatabase::~VectorDatabase() = default;
+
+void VectorDatabase::Add(UrlEmbeddings url_embeddings) {
+  data_.push_back(std::move(url_embeddings));
+}
+
+std::vector<ScoredUrl> VectorDatabase::FindNearest(size_t count,
+                                                   const Embedding& query) {
+  // TODO(orinj): Manage a heap for speed.
+  struct Compare {
+    bool operator()(const ScoredUrl& a, const ScoredUrl& b) {
+      return a.score < b.score;
+    }
+  };
+  std::priority_queue<ScoredUrl, std::vector<ScoredUrl>, Compare> q;
+
+  for (const UrlEmbeddings& item : data_) {
+    while (q.size() > count) {
+      q.pop();
+    }
+    q.push(ScoredUrl{
+        .url = item.url,
+        .score = item.BestScoreWith(query),
+    });
+  }
+
+  // Empty queue into vector and return result.
+  std::vector<ScoredUrl> nearest;
+  while (!q.empty()) {
+    nearest.push_back(q.top());
+    q.pop();
+  }
+  return nearest;
+}
+
+}  // namespace history_embeddings
diff --git a/components/history_embeddings/vector_database.h b/components/history_embeddings/vector_database.h
new file mode 100644
index 0000000..d54c4bf
--- /dev/null
+++ b/components/history_embeddings/vector_database.h
@@ -0,0 +1,62 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_HISTORY_EMBEDDINGS_VECTOR_DATABASE_H_
+#define COMPONENTS_HISTORY_EMBEDDINGS_VECTOR_DATABASE_H_
+
+#include "components/keyed_service/core/keyed_service.h"
+
+#include <vector>
+
+#include "url/gurl.h"
+
+namespace history_embeddings {
+
+class Embedding {
+ public:
+  Embedding(std::vector<float> data);
+  ~Embedding();
+  Embedding(Embedding&&);
+  Embedding(const Embedding&) = delete;
+
+  float Magnitude() const;
+  void Normalize();
+  float ScoreWith(const Embedding& other) const;
+
+ private:
+  std::vector<float> data;
+};
+
+struct UrlEmbeddings {
+  UrlEmbeddings();
+  ~UrlEmbeddings();
+  UrlEmbeddings(UrlEmbeddings&&);
+  UrlEmbeddings(const UrlEmbeddings&) = delete;
+
+  float BestScoreWith(const Embedding& query) const;
+
+  GURL url;
+  std::vector<Embedding> embeddings;
+};
+
+struct ScoredUrl {
+  GURL url;
+  float score;
+};
+
+class VectorDatabase {
+ public:
+  VectorDatabase();
+  ~VectorDatabase();
+
+  void Add(UrlEmbeddings url_embeddings);
+  std::vector<ScoredUrl> FindNearest(size_t count, const Embedding& query);
+
+ private:
+  std::vector<UrlEmbeddings> data_;
+};
+
+}  // namespace history_embeddings
+
+#endif  // COMPONENTS_HISTORY_EMBEDDINGS_VECTOR_DATABASE_H_
diff --git a/components/history_embeddings/vector_database_unittest.cc b/components/history_embeddings/vector_database_unittest.cc
new file mode 100644
index 0000000..c1f7aca
--- /dev/null
+++ b/components/history_embeddings/vector_database_unittest.cc
@@ -0,0 +1,71 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/history_embeddings/vector_database.h"
+
+#include <memory>
+
+#include "base/logging.h"
+#include "base/rand_util.h"
+#include "base/time/time.h"
+#include "base/timer/elapsed_timer.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace history_embeddings {
+
+namespace {
+
+Embedding RandomEmbedding() {
+  constexpr size_t kSize = 768u;
+  std::vector<float> random_vector(kSize, 0.0f);
+  for (float& v : random_vector) {
+    v = base::RandFloat();
+  }
+  Embedding embedding(std::move(random_vector));
+  embedding.Normalize();
+  return embedding;
+}
+
+}  // namespace
+
+TEST(HistoryEmbeddingsVectorDatabaseTest, Constructs) {
+  std::make_unique<VectorDatabase>();
+}
+
+TEST(HistoryEmbeddingsVectorDatabaseTest, EmbeddingOperations) {
+  Embedding a({1, 1, 1});
+  EXPECT_FLOAT_EQ(a.Magnitude(), std::sqrt(3));
+
+  a.Normalize();
+  EXPECT_FLOAT_EQ(a.Magnitude(), 1.0f);
+
+  Embedding b({2, 2, 2});
+  b.Normalize();
+  EXPECT_FLOAT_EQ(a.ScoreWith(b), 1.0f);
+}
+
+// Note: Disabled by default so as to not burden the bots. Enable when needed.
+TEST(HistoryEmbeddingsVectorDatabaseTest, DISABLED_ManyVectorsAreFastEnough) {
+  VectorDatabase database;
+  size_t count = 0;
+  // 95th percentile for URL count
+  for (size_t i = 0; i < 15000; i++) {
+    UrlEmbeddings url_embeddings;
+    // Times 3 embeddings each, on average
+    for (size_t j = 0; j < 3; j++) {
+      url_embeddings.embeddings.push_back(RandomEmbedding());
+      count++;
+    }
+    database.Add(std::move(url_embeddings));
+  }
+  Embedding query = RandomEmbedding();
+  base::ElapsedTimer timer;
+  database.FindNearest(3, query);
+  // This could be an assertion with an extraordinarily high threshold, but for
+  // now we avoid any possibility of blowing up trybots and just need the info.
+  LOG(INFO) << "Searched " << count << " embeddings in " << timer.Elapsed();
+}
+
+}  // namespace history_embeddings
diff --git a/components/metrics/demographics/demographic_metrics_provider.cc b/components/metrics/demographics/demographic_metrics_provider.cc
index b45aae5c4..fc919b7 100644
--- a/components/metrics/demographics/demographic_metrics_provider.cc
+++ b/components/metrics/demographics/demographic_metrics_provider.cc
@@ -55,7 +55,7 @@
 
   // If `kReplaceSyncPromosWithSignInPromos` is NOT enabled, then demographics
   // may only be uploaded for users who have opted in to Sync.
-  // TODO(crbug.com/1462552): Simplify once IsSyncFeatureEnabled() is deleted
+  // TODO(crbug.com/40066949): Simplify once IsSyncFeatureEnabled() is deleted
   // from the codebase.
   if (sync_service->IsSyncFeatureEnabled()) {
     return true;
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc
index 7667054..332ac62a3d 100644
--- a/components/omnibox/common/omnibox_features.cc
+++ b/components/omnibox/common/omnibox_features.cc
@@ -308,7 +308,7 @@
 // Feature used to enable the simplified actions UI design.
 BASE_FEATURE(kOmniboxActionsUISimplification,
              "OmniboxActionsUISimplification",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             enabled_by_default_desktop_only);
 
 // Feature used to enable the new keyword mode behavior.
 BASE_FEATURE(kOmniboxKeywordModeRefresh,
diff --git a/components/page_image_service/image_service_consent_helper.cc b/components/page_image_service/image_service_consent_helper.cc
index 73eb93c..fbaa8b5 100644
--- a/components/page_image_service/image_service_consent_helper.cc
+++ b/components/page_image_service/image_service_consent_helper.cc
@@ -47,7 +47,8 @@
   if (base::FeatureList::IsEnabled(kImageServiceObserveSyncDownloadStatus)) {
     sync_service_observer_.Observe(sync_service);
   } else if (model_type == syncer::ModelType::BOOKMARKS) {
-    // TODO(crbug.com/1463438): Migrate to require_sync_feature_enabled = false.
+    // TODO(crbug.com/40067770): Migrate to require_sync_feature_enabled =
+    // false.
     consent_throttle_ = std::make_unique<unified_consent::ConsentThrottle>(
         unified_consent::UrlKeyedDataCollectionConsentHelper::
             NewPersonalizedBookmarksDataCollectionConsentHelper(
diff --git a/components/password_manager/content/browser/content_password_manager_driver.cc b/components/password_manager/content/browser/content_password_manager_driver.cc
index d0bb570..76c1b5e1 100644
--- a/components/password_manager/content/browser/content_password_manager_driver.cc
+++ b/components/password_manager/content/browser/content_password_manager_driver.cc
@@ -182,6 +182,9 @@
 
 void ContentPasswordManagerDriver::GeneratedPasswordAccepted(
     const std::u16string& password) {
+  // Same check as in PasswordGenerationAgent::GeneratedPasswordAccepted. The
+  // generated password can't be too short.
+  CHECK_LE(4u, password.size());
   GetPasswordGenerationAgent()->GeneratedPasswordAccepted(password);
 }
 
diff --git a/components/password_manager/core/browser/browser_save_password_progress_logger_unittest.cc b/components/password_manager/core/browser/browser_save_password_progress_logger_unittest.cc
index 37e8fe8..a26430b 100644
--- a/components/password_manager/core/browser/browser_save_password_progress_logger_unittest.cc
+++ b/components/password_manager/core/browser/browser_save_password_progress_logger_unittest.cc
@@ -92,7 +92,6 @@
   EXPECT_TRUE(logger.LogsContainSubstring("Origin: http://myform.com"));
   EXPECT_TRUE(logger.LogsContainSubstring("Action: http://m.myform.com"));
   EXPECT_TRUE(logger.LogsContainSubstring("Form name: form_name"));
-  EXPECT_TRUE(logger.LogsContainSubstring("Form with form tag: true"));
   EXPECT_TRUE(logger.LogsContainSubstring("Form fields:"));
   EXPECT_TRUE(logger.LogsContainSubstring(
       "password: signature=2051817934, type=password, renderer_id=10, "
diff --git a/components/password_manager/core/browser/features/password_manager_features_util_common.cc b/components/password_manager/core/browser/features/password_manager_features_util_common.cc
index 58b72e9..63e9d9a 100644
--- a/components/password_manager/core/browser/features/password_manager_features_util_common.cc
+++ b/components/password_manager/core/browser/features/password_manager_features_util_common.cc
@@ -58,7 +58,7 @@
     return false;
   }
 
-  // TODO(crbug.com/1462978): Delete this when ConsentLevel::kSync is deleted.
+  // TODO(crbug.com/40067058): Delete this when ConsentLevel::kSync is deleted.
   // See ConsentLevel::kSync documentation for details.
   // Eligibility for account storage is controlled by separate flags for syncing
   // and non-syncing users. Enabling the flag is a necessary condition but not
@@ -175,7 +175,7 @@
     return PasswordAccountStorageUserState::kSignedOutUser;
   }
 
-  // TODO(crbug.com/1462978): Delete this when ConsentLevel::kSync is deleted.
+  // TODO(crbug.com/40067058): Delete this when ConsentLevel::kSync is deleted.
   // See ConsentLevel::kSync documentation for details.
   if (sync_service->IsSyncFeatureEnabled()) {
     return PasswordAccountStorageUserState::kSyncUser;
diff --git a/components/password_manager/core/browser/form_parsing/fuzzer/form_data_proto_producer.cc b/components/password_manager/core/browser/form_parsing/fuzzer/form_data_proto_producer.cc
index 38303a37..bd7b9828 100644
--- a/components/password_manager/core/browser/form_parsing/fuzzer/form_data_proto_producer.cc
+++ b/components/password_manager/core/browser/form_parsing/fuzzer/form_data_proto_producer.cc
@@ -34,7 +34,6 @@
 
   result.id_attribute = UTF8ToUTF16(form_proto.id());
   result.name_attribute = UTF8ToUTF16(form_proto.name());
-  result.is_form_tag = form_proto.is_form_tag();
   result.name = UTF8ToUTF16(form_proto.name());
   result.action = GURL(form_proto.action());
   result.url = GURL(form_proto.origin());
diff --git a/components/password_manager/core/browser/generation/password_generator.cc b/components/password_manager/core/browser/generation/password_generator.cc
index b9c58df4..3187c56 100644
--- a/components/password_manager/core/browser/generation/password_generator.cc
+++ b/components/password_manager/core/browser/generation/password_generator.cc
@@ -268,21 +268,26 @@
   // For passwords without letters, add the '0' and '1' to the numeric alphabet.
   ConditionallyAddNumericDigitsToAlphabet(&actual_spec);
 
+  std::u16string password;
+
   // For specs that allow dash symbol and can be longer than 8 chars generate a
   // chunked password when `kChunkPassword` variaton of
   // kPasswordGenerationExperiment is enabled.
   if (actual_spec.symbols().character_set().find('-') != std::string::npos &&
       actual_spec.max_length() >= kMinLengthToChunkPassword &&
       ChunkingPasswordExperimentEnabled()) {
-    return GenerateMaxEntropyChunkedPassword(std::move(actual_spec));
+    password = GenerateMaxEntropyChunkedPassword(std::move(actual_spec));
+    CHECK_LE(4u, password.size());
+    return password;
   }
 
-  std::u16string password = GenerateMaxEntropyPassword(std::move(actual_spec));
+  password = GenerateMaxEntropyPassword(std::move(actual_spec));
 
   // Catch cases where supplied spec is infeasible.
   if (password.empty())
     password = GenerateMaxEntropyPassword(BuildDefaultSpec());
 
+  CHECK_LE(4u, password.size());
   return password;
 }
 
diff --git a/components/password_manager/core/browser/leak_detection_delegate.cc b/components/password_manager/core/browser/leak_detection_delegate.cc
index 17c57aa..2719853 100644
--- a/components/password_manager/core/browser/leak_detection_delegate.cc
+++ b/components/password_manager/core/browser/leak_detection_delegate.cc
@@ -17,6 +17,7 @@
 #include "components/password_manager/core/browser/password_manager_client.h"
 #include "components/password_manager/core/browser/password_manager_util.h"
 #include "components/password_manager/core/browser/password_store/password_store_interface.h"
+#include "components/password_manager/core/browser/password_store/split_stores_and_local_upm.h"
 #include "components/password_manager/core/browser/password_sync_util.h"
 #include "components/password_manager/core/common/password_manager_features.h"
 #include "components/password_manager/core/common/password_manager_pref_names.h"
@@ -111,24 +112,32 @@
                           std::exchange(is_leaked_timer_, nullptr)->Elapsed());
   helper_.reset();
 
+  const bool in_account_store =
+      (in_stores & PasswordForm::Store::kAccountStore) ==
+      PasswordForm::Store::kAccountStore;
+
   // A credential is marked as syncing if either the profile store is synced
   // or it is in the account store.
-  // TODO(b/317058107): Revisit if this codepath, and possibly others using
-  // `PasswordForm::Store::kAccountStore` are compatible with ongoing changes
-  // on Android.
   IsSyncing is_syncing{false};
-  bool in_account_store = (in_stores & PasswordForm::Store::kAccountStore) ==
-                          PasswordForm::Store::kAccountStore;
-  const syncer::SyncService* sync_service = client_->GetSyncService();
-  switch (sync_util::GetPasswordSyncState(sync_service)) {
-    case sync_util::SyncState::kNotActive:
-      break;
-    case sync_util::SyncState::kActiveWithNormalEncryption:
-    case sync_util::SyncState::kActiveWithCustomPassphrase:
-      is_syncing = IsSyncing(
-          in_account_store ||
-          sync_util::IsSyncFeatureEnabledIncludingPasswords(sync_service));
-      break;
+
+  if (in_account_store) {
+    // Credential saved to the account store.
+    is_syncing = IsSyncing{true};
+  } else {
+    // Credential saved to the local-or-syncable store.
+#if BUILDFLAG(IS_ANDROID)
+    const bool uses_split_stores_for_sync_users =
+        UsesSplitStoresAndUPMForLocal(client_->GetPrefs());
+#else
+    const bool uses_split_stores_for_sync_users = false;
+#endif  // BUILDFLAG(IS_ANDROID)
+
+    if (!uses_split_stores_for_sync_users) {
+      // TODO(crbug.com/40066949): Remove this codepath once
+      // IsSyncFeatureEnabled() is fully deprecated.
+      is_syncing = IsSyncing(sync_util::IsSyncFeatureEnabledIncludingPasswords(
+          client_->GetSyncService()));
+    }
   }
 
   CredentialLeakType leak_type =
diff --git a/components/password_manager/core/browser/leak_detection_delegate_unittest.cc b/components/password_manager/core/browser/leak_detection_delegate_unittest.cc
index 9ffb83d..e688c6b 100644
--- a/components/password_manager/core/browser/leak_detection_delegate_unittest.cc
+++ b/components/password_manager/core/browser/leak_detection_delegate_unittest.cc
@@ -104,11 +104,16 @@
     mock_factory_ = mock_factory.get();
     delegate_.set_leak_factory(std::move(mock_factory));
     pref_service_->registry()->RegisterBooleanPref(
-        password_manager::prefs::kPasswordLeakDetectionEnabled, true);
+        prefs::kPasswordLeakDetectionEnabled, true);
     pref_service_->registry()->RegisterBooleanPref(
         ::prefs::kSafeBrowsingEnabled, true);
     pref_service_->registry()->RegisterBooleanPref(
         ::prefs::kSafeBrowsingEnhanced, false);
+#if BUILDFLAG(IS_ANDROID)
+    pref_service_->registry()->RegisterIntegerPref(
+        prefs::kPasswordsUseUPMLocalAndSeparateStores,
+        static_cast<int>(prefs::UseUpmLocalAndSeparateStoresState::kOff));
+#endif  // BUILDFLAG(IS_ANDROID)
     ON_CALL(client_, GetPrefs()).WillByDefault(Return(pref_service()));
   }
 
@@ -463,6 +468,90 @@
   WaitForPasswordStore();
 }
 
+#if BUILDFLAG(IS_ANDROID)
+TEST_F(LeakDetectionDelegateTest,
+       LeakDetectionDoneForLocalStoreWithSplitStoresAndUPMForLocal) {
+  LeakDetectionDelegateInterface* delegate_interface = &delegate();
+  const PasswordForm form = CreateTestForm();
+
+  ON_CALL(client(), GetSyncService()).WillByDefault(Return(sync_service()));
+  ON_CALL(client(), GetAccountPasswordStore())
+      .WillByDefault(Return(account_store()));
+  ON_CALL(client(), GetProfilePasswordStore())
+      .WillByDefault(Return(profile_store()));
+
+  // Mark that the local and account stores are split.
+  pref_service()->SetInteger(
+      prefs::kPasswordsUseUPMLocalAndSeparateStores,
+      static_cast<int>(prefs::UseUpmLocalAndSeparateStoresState::kOn));
+
+  ASSERT_EQ(sync_util::GetPasswordSyncState(sync_service()),
+            sync_util::SyncState::kActiveWithNormalEncryption);
+  ASSERT_TRUE(
+      sync_util::IsSyncFeatureEnabledIncludingPasswords(sync_service()));
+
+  ExpectPasswords({}, /*store=*/account_store());
+  ExpectPasswords({form}, /*store=*/profile_store());
+  EXPECT_CALL(factory(), TryCreateLeakCheck)
+      .WillOnce(
+          Return(ByMove(std::make_unique<NiceMock<MockLeakDetectionCheck>>())));
+  delegate().StartLeakCheck(LeakDetectionInitiator::kSignInCheck, form);
+
+  EXPECT_CALL(
+      client(),
+      NotifyUserCredentialsWereLeaked(
+          password_manager::CreateLeakType(IsSaved(true), IsReused(false),
+                                           IsSyncing(false)),
+          form.url, form.username_value, /* in_account_store = */ false));
+  delegate_interface->OnLeakDetectionDone(
+      /*is_leaked=*/true, form.url, form.username_value, form.password_value);
+
+  EXPECT_CALL(*profile_store(), UpdateLogin);
+  WaitForPasswordStore();
+}
+
+TEST_F(LeakDetectionDelegateTest,
+       LeakDetectionDoneForAccountStoreWithSplitStoresAndUPMForLocal) {
+  LeakDetectionDelegateInterface* delegate_interface = &delegate();
+  const PasswordForm form = CreateTestForm();
+
+  ON_CALL(client(), GetSyncService()).WillByDefault(Return(sync_service()));
+  ON_CALL(client(), GetAccountPasswordStore())
+      .WillByDefault(Return(account_store()));
+  ON_CALL(client(), GetProfilePasswordStore())
+      .WillByDefault(Return(profile_store()));
+
+  // Mark that the local and account stores are split.
+  pref_service()->SetInteger(
+      prefs::kPasswordsUseUPMLocalAndSeparateStores,
+      static_cast<int>(prefs::UseUpmLocalAndSeparateStoresState::kOn));
+
+  ASSERT_EQ(sync_util::GetPasswordSyncState(sync_service()),
+            sync_util::SyncState::kActiveWithNormalEncryption);
+  ASSERT_TRUE(
+      sync_util::IsSyncFeatureEnabledIncludingPasswords(sync_service()));
+
+  ExpectPasswords({form}, /*store=*/account_store());
+  ExpectPasswords({}, /*store=*/profile_store());
+  EXPECT_CALL(factory(), TryCreateLeakCheck)
+      .WillOnce(
+          Return(ByMove(std::make_unique<NiceMock<MockLeakDetectionCheck>>())));
+  delegate().StartLeakCheck(LeakDetectionInitiator::kSignInCheck, form);
+
+  EXPECT_CALL(
+      client(),
+      NotifyUserCredentialsWereLeaked(
+          password_manager::CreateLeakType(IsSaved(true), IsReused(false),
+                                           IsSyncing(true)),
+          form.url, form.username_value, /* in_account_store = */ true));
+  delegate_interface->OnLeakDetectionDone(
+      /*is_leaked=*/true, form.url, form.username_value, form.password_value);
+
+  EXPECT_CALL(*account_store(), UpdateLogin);
+  WaitForPasswordStore();
+}
+#endif  // BUILDFLAG(IS_ANDROID)
+
 TEST_F(LeakDetectionDelegateTest, LeakHistoryAddCredentials) {
   LeakDetectionDelegateInterface* delegate_interface = &delegate();
   PasswordForm form = CreateTestForm();
diff --git a/components/password_manager/core/browser/password_form_filling_unittest.cc b/components/password_manager/core/browser/password_form_filling_unittest.cc
index bc389a2..f39659368 100644
--- a/components/password_manager/core/browser/password_form_filling_unittest.cc
+++ b/components/password_manager/core/browser/password_form_filling_unittest.cc
@@ -762,7 +762,6 @@
   form_data.host_frame = autofill::LocalFrameToken(
       base::UnguessableToken::CreateForTesting(98765, 43210));
   form_data.renderer_id = FormRendererId(42);
-  form_data.is_form_tag = true;
   form_on_page.form_data = form_data;
   form_on_page.username_element_renderer_id = FieldRendererId(123);
   form_on_page.password_element_renderer_id = FieldRendererId(456);
@@ -799,7 +798,6 @@
 
   FormData form_data;
   form_data.renderer_id = FormRendererId(42);
-  form_data.is_form_tag = true;
   form_on_page.form_data = form_data;
 
   Origin page_origin = Origin::Create(GURL("https://foo.com/"));
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc
index 383f10a3..921d100b 100644
--- a/components/password_manager/core/browser/password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -399,7 +399,6 @@
     observed_form_.action = action;
     observed_form_.name = u"sign-in";
     observed_form_.renderer_id = FormRendererId(1);
-    observed_form_.is_form_tag = true;
 
     observed_form_only_password_fields_ = observed_form_;
 
@@ -651,7 +650,6 @@
   EXPECT_FALSE(
       form_manager_->DoesManage(observed_form_.renderer_id, &another_driver));
   FormData another_form = observed_form_;
-  another_form.is_form_tag = false;
   another_form.renderer_id = FormRendererId();
   EXPECT_FALSE(form_manager_->DoesManage(another_form.renderer_id, &driver_));
 
@@ -662,7 +660,7 @@
 }
 
 TEST_P(PasswordFormManagerTest, DoesManageNoFormTag) {
-  observed_form_.is_form_tag = false;
+  observed_form_.renderer_id = FormRendererId();
   CreateFormManager(observed_form_);
 
   FormData another_form = observed_form_;
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc
index fb3dc3f..1428aac 100644
--- a/components/password_manager/core/browser/password_manager.cc
+++ b/components/password_manager/core/browser/password_manager.cc
@@ -620,7 +620,7 @@
     return;
   }
   // If a password form was cleared, login is successful.
-  if (form_data.is_form_tag) {
+  if (!form_data.renderer_id.is_null()) {
     manager->UpdateSubmissionIndicatorEvent(
         SubmissionIndicatorEvent::CHANGE_PASSWORD_FORM_CLEARED);
     OnLoginSuccessful();
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc
index 072502d9..a678b3b6 100644
--- a/components/password_manager/core/browser/password_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -4677,7 +4677,7 @@
 
   // Create FormdData for a form with 1 password field and process it.
   FormData form_data;
-  form_data.is_form_tag = false;
+  form_data.renderer_id = FormRendererId();
   form_data.url = GURL("http://www.testwebsite.com");
 
   FormFieldData old_password_field;
@@ -4724,20 +4724,19 @@
 }
 
 TEST_P(PasswordManagerTest, SubmissionDetectedOnClearedForm) {
-  base::test::ScopedFeatureList feature_list;
   EXPECT_CALL(client_, IsSavingAndFillingEnabled).WillRepeatedly(Return(true));
   PasswordForm saved_match(MakeSavedForm());
   store_->AddLogin(saved_match);
 
   // Create FormData for a form with 3 password fields and process it.
   FormData form_data;
-  form_data.renderer_id = FormRendererId(0);
+  form_data.renderer_id = FormRendererId(1);
   form_data.url = test_form_url_;
 
   FormFieldData old_password_field;
   old_password_field.form_control_type =
       autofill::FormControlType::kInputPassword;
-  old_password_field.renderer_id = FieldRendererId(1);
+  old_password_field.renderer_id = FieldRendererId(2);
   old_password_field.name = u"oldpass";
   old_password_field.value = u"oldpass";
   form_data.fields.push_back(old_password_field);
@@ -4745,7 +4744,7 @@
   FormFieldData new_password_field;
   new_password_field.form_control_type =
       autofill::FormControlType::kInputPassword;
-  new_password_field.renderer_id = FieldRendererId(2);
+  new_password_field.renderer_id = FieldRendererId(3);
   new_password_field.name = u"newpass";
   new_password_field.autocomplete_attribute = "new-password";
   form_data.fields.push_back(new_password_field);
@@ -4753,7 +4752,7 @@
   FormFieldData confirm_password_field;
   confirm_password_field.form_control_type =
       autofill::FormControlType::kInputPassword;
-  confirm_password_field.renderer_id = FieldRendererId(3);
+  confirm_password_field.renderer_id = FieldRendererId(4);
   confirm_password_field.name = u"confpass";
   form_data.fields.push_back(confirm_password_field);
 
@@ -4813,19 +4812,18 @@
 // Similar test as above with fields that have empty names.
 TEST_P(PasswordManagerTest, SubmissionDetectedOnClearedNamelessForm) {
   constexpr char16_t kEmptyName[] = u"";
-  base::test::ScopedFeatureList feature_list;
   EXPECT_CALL(client_, IsSavingAndFillingEnabled).WillRepeatedly(Return(true));
   PasswordForm saved_match(MakeSavedForm());
   store_->AddLogin(saved_match);
 
   FormData form_data;
-  form_data.renderer_id = FormRendererId(0);
+  form_data.renderer_id = FormRendererId(1);
   form_data.url = test_form_url_;
 
   FormFieldData old_password_field;
   old_password_field.form_control_type =
       autofill::FormControlType::kInputPassword;
-  old_password_field.renderer_id = FieldRendererId(1);
+  old_password_field.renderer_id = FieldRendererId(2);
   old_password_field.name = kEmptyName;
   old_password_field.value = u"oldpass";
   form_data.fields.push_back(old_password_field);
@@ -4833,7 +4831,7 @@
   FormFieldData new_password_field;
   new_password_field.form_control_type =
       autofill::FormControlType::kInputPassword;
-  new_password_field.renderer_id = FieldRendererId(2);
+  new_password_field.renderer_id = FieldRendererId(3);
   new_password_field.name = kEmptyName;
   new_password_field.autocomplete_attribute = "new-password";
   form_data.fields.push_back(new_password_field);
@@ -4853,7 +4851,6 @@
 }
 
 TEST_P(PasswordManagerTest, SubmissionDetectedOnClearedFormlessFields) {
-  base::test::ScopedFeatureList feature_list;
   EXPECT_CALL(client_, IsSavingAndFillingEnabled).WillRepeatedly(Return(true));
   PasswordForm saved_match(MakeSavedForm());
   store_->AddLogin(saved_match);
@@ -4864,7 +4861,6 @@
 
     // Create FormData for a form with 1 password field and process it.
     FormData form_data;
-    form_data.is_form_tag = false;
     form_data.renderer_id = FormRendererId(0);
     form_data.url = test_form_url_;
 
@@ -4920,7 +4916,6 @@
 // Similar test as above with fields that have empty names.
 TEST_P(PasswordManagerTest, SubmissionDetectedOnClearedNameAndFormlessFields) {
   constexpr char16_t kEmptyName[] = u"";
-  base::test::ScopedFeatureList feature_list;
   EXPECT_CALL(client_, IsSavingAndFillingEnabled).WillRepeatedly(Return(true));
   PasswordForm saved_match(MakeSavedForm());
   store_->AddLogin(saved_match);
@@ -4931,7 +4926,6 @@
 
     // Create FormData for a form with 1 password field and process it.
     FormData form_data;
-    form_data.is_form_tag = false;
     form_data.renderer_id = FormRendererId(0);
     form_data.url = test_form_url_;
 
diff --git a/components/password_manager/core/browser/password_save_manager_impl_unittest.cc b/components/password_manager/core/browser/password_save_manager_impl_unittest.cc
index 9c88fff..43f631d 100644
--- a/components/password_manager/core/browser/password_save_manager_impl_unittest.cc
+++ b/components/password_manager/core/browser/password_save_manager_impl_unittest.cc
@@ -209,7 +209,6 @@
     observed_form_.action = action;
     observed_form_.name = u"sign-in";
     observed_form_.renderer_id = autofill::FormRendererId(1);
-    observed_form_.is_form_tag = true;
 
     observed_form_only_password_fields_ = observed_form_;
 
diff --git a/components/password_manager/core/browser/password_store_signin_notifier_impl.cc b/components/password_manager/core/browser/password_store_signin_notifier_impl.cc
index d9f424b..758543c 100644
--- a/components/password_manager/core/browser/password_store_signin_notifier_impl.cc
+++ b/components/password_manager/core/browser/password_store_signin_notifier_impl.cc
@@ -50,7 +50,7 @@
 // IdentityManager::Observer implementation.
 void PasswordStoreSigninNotifierImpl::OnPrimaryAccountChanged(
     const signin::PrimaryAccountChangeEvent& event) {
-  // TODO(crbug.com/1462978): Remove this code when ConsentLevel::kSync is
+  // TODO(crbug.com/40067058): Remove this code when ConsentLevel::kSync is
   // deleted (since kSignin users are handled by
   // OnExtendedAccountInfoRemoved()). See ConsentLevel::kSync documentation for
   // details.
@@ -66,7 +66,7 @@
     const AccountInfo& info) {
   // Only react to non-syncing Gaia account sign-out event - the syncing
   // account is handled separately in OnPrimaryAccountChanged().
-  // TODO(crbug.com/1462978): Remove the not-kSync check when
+  // TODO(crbug.com/40067058): Remove the not-kSync check when
   // ConsentLevel::kSync is deleted. See ConsentLevel::kSync documentation for
   // details.
   if (info.account_id !=
diff --git a/components/password_manager/core/browser/password_sync_util.cc b/components/password_manager/core/browser/password_sync_util.cc
index 20873ba..3de1191f 100644
--- a/components/password_manager/core/browser/password_sync_util.cc
+++ b/components/password_manager/core/browser/password_sync_util.cc
@@ -81,7 +81,7 @@
 
 bool IsSyncFeatureEnabledIncludingPasswords(
     const syncer::SyncService* sync_service) {
-  // TODO(crbug.com/1462552): Remove this function once IsSyncFeatureEnabled()
+  // TODO(crbug.com/40066949): Remove this function once IsSyncFeatureEnabled()
   // is fully deprecated, see ConsentLevel::kSync documentation for details.
   return sync_service && sync_service->IsSyncFeatureEnabled() &&
          sync_service->GetUserSettings()->GetSelectedTypes().Has(
diff --git a/components/password_manager/core/browser/password_sync_util.h b/components/password_manager/core/browser/password_sync_util.h
index fba294da..d967e30 100644
--- a/components/password_manager/core/browser/password_sync_util.h
+++ b/components/password_manager/core/browser/password_sync_util.h
@@ -31,7 +31,7 @@
 // sync-the-feature turned on, and if so, return the e-mail representing the
 // account for which sync is on. Returns an empty string otherwise (which
 // includes the sync-off case even if account passwords are on).
-// TODO(crbug.com/1462552): Remove this function once IsSyncFeatureEnabled() is
+// TODO(crbug.com/40066949): Remove this function once IsSyncFeatureEnabled() is
 // fully deprecated, see ConsentLevel::kSync documentation for details.
 std::string GetAccountEmailIfSyncFeatureEnabledIncludingPasswords(
     const syncer::SyncService* sync_service);
@@ -56,7 +56,7 @@
 // even if account passwords are enabled. On some platforms, e.g. iOS, this can
 // be the majority of users (eventually all), so please avoid integrating with
 // this function if possible.
-// TODO(crbug.com/1462552): Remove this function once IsSyncFeatureEnabled() is
+// TODO(crbug.com/40066949): Remove this function once IsSyncFeatureEnabled() is
 // fully deprecated, see ConsentLevel::kSync documentation for details.
 bool IsSyncFeatureEnabledIncludingPasswords(
     const syncer::SyncService* sync_service);
@@ -68,7 +68,7 @@
 // even if account passwords are enabled and active. On some platforms, e.g.
 // iOS, this can be the majority of users (eventually all), so please avoid
 // integrating with this function if possible.
-// TODO(crbug.com/1462552): Remove this function once IsSyncFeatureEnabled()/
+// TODO(crbug.com/40066949): Remove this function once IsSyncFeatureEnabled()/
 // IsSyncFeatureActive() is fully deprecated, see ConsentLevel::kSync
 // documentation for details.
 bool IsSyncFeatureActiveIncludingPasswords(
diff --git a/components/policy/core/browser/cloud/user_policy_signin_service_util.cc b/components/policy/core/browser/cloud/user_policy_signin_service_util.cc
index f099a9ec..912321f 100644
--- a/components/policy/core/browser/cloud/user_policy_signin_service_util.cc
+++ b/components/policy/core/browser/cloud/user_policy_signin_service_util.cc
@@ -17,14 +17,14 @@
 }
 
 bool IsTurnOffSyncEvent(const signin::PrimaryAccountChangeEvent& event) {
-  // TODO(crbug.com/1462552): Remove kSync usage after users are migrated to
+  // TODO(crbug.com/40066949): Remove kSync usage after users are migrated to
   // kSignin only after kSync sunset. See ConsentLevel::kSync for more details.
   return event.GetEventTypeFor(signin::ConsentLevel::kSync) ==
          signin::PrimaryAccountChangeEvent::Type::kCleared;
 }
 
 bool IsAnySigninEvent(const signin::PrimaryAccountChangeEvent& event) {
-  // TODO(crbug.com/1462552): Remove kSync usage after users are migrated to
+  // TODO(crbug.com/40066949): Remove kSync usage after users are migrated to
   // kSignin only after kSync sunset. See ConsentLevel::kSync for more details.
   return event.GetEventTypeFor(signin::ConsentLevel::kSync) ==
              signin::PrimaryAccountChangeEvent::Type::kSet ||
diff --git a/components/safe_browsing/core/browser/sync/safe_browsing_primary_account_token_fetcher_unittest.cc b/components/safe_browsing/core/browser/sync/safe_browsing_primary_account_token_fetcher_unittest.cc
index a2d53cb..cf7e2a8 100644
--- a/components/safe_browsing/core/browser/sync/safe_browsing_primary_account_token_fetcher_unittest.cc
+++ b/components/safe_browsing/core/browser/sync/safe_browsing_primary_account_token_fetcher_unittest.cc
@@ -57,7 +57,7 @@
 
 TEST_F(SafeBrowsingPrimaryAccountTokenFetcherTest,
        SuccessWithConsentedPrimaryAccount) {
-  // TODO(https://crbug.com/1462552): Delete this test after UNO phase 3
+  // TODO(https://crbug.com/40066949): Delete this test after UNO phase 3
   // migration is complete. See `ConsentLevel::kSync` documentation for more
   // details.
   identity_test_environment_.MakePrimaryAccountAvailable(
diff --git a/components/signin/core/browser/about_signin_internals.cc b/components/signin/core/browser/about_signin_internals.cc
index 1e48d92..decadbd 100644
--- a/components/signin/core/browser/about_signin_internals.cc
+++ b/components/signin/core/browser/about_signin_internals.cc
@@ -215,7 +215,7 @@
   if (!identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin)) {
     return "Not Signed In";
   } else if (identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync)) {
-    // TODO(crbug.com/1462978): Delete when ConsentLevel::kSync is deleted from
+    // TODO(crbug.com/40067058): Delete when ConsentLevel::kSync is deleted from
     // the codebase. See ConsentLevel::kSync documentation for details.
     return "Signed In, Consented for Sync";
   } else {
diff --git a/components/signin/internal/identity_manager/primary_account_mutator_impl.cc b/components/signin/internal/identity_manager/primary_account_mutator_impl.cc
index 520e398..b27b9b7 100644
--- a/components/signin/internal/identity_manager/primary_account_mutator_impl.cc
+++ b/components/signin/internal/identity_manager/primary_account_mutator_impl.cc
@@ -70,9 +70,9 @@
   switch (consent_level) {
     case ConsentLevel::kSync:
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
-      // TODO(crbug.com/1462858): Replace with NOTREACHED on iOS after all flows
-      //     have been migrated away from kSync. See ConsentLevel::kSync
-      //     documentation for details.
+      // TODO(crbug.com/40067025): Replace with NOTREACHED on iOS after all
+      // flows have been migrated away from kSync. See ConsentLevel::kSync
+      // documentation for details.
       if (primary_account_manager_->HasPrimaryAccount(ConsentLevel::kSync))
         return PrimaryAccountError::kSyncConsentAlreadySet;
 #endif
@@ -83,7 +83,7 @@
       DCHECK(
           !primary_account_manager_->HasPrimaryAccount(ConsentLevel::kSignin));
 #endif
-      // TODO(crbug.com/1462978): Delete this when ConsentLevel::kSync is
+      // TODO(crbug.com/40067058): Delete this when ConsentLevel::kSync is
       //     deleted. See ConsentLevel::kSync documentation for details.
       DCHECK(!primary_account_manager_->HasPrimaryAccount(ConsentLevel::kSync));
       break;
@@ -112,7 +112,7 @@
 void PrimaryAccountMutatorImpl::RevokeSyncConsent(
     signin_metrics::ProfileSignout source_metric,
     signin_metrics::SignoutDelete delete_metric) {
-  // TODO(crbug.com/1462552): `RevokeSyncConsent` shouldn't be available on iOS
+  // TODO(crbug.com/40066949): `RevokeSyncConsent` shouldn't be available on iOS
   //     when kSync is no longer used. See ConsentLevel::kSync documentation for
   //     details.
   DCHECK(primary_account_manager_->HasPrimaryAccount(ConsentLevel::kSync));
diff --git a/components/signin/public/base/signin_metrics.cc b/components/signin/public/base/signin_metrics.cc
index d92c180..136cc88 100644
--- a/components/signin/public/base/signin_metrics.cc
+++ b/components/signin/public/base/signin_metrics.cc
@@ -288,7 +288,7 @@
       base::UmaHistogramEnumeration("Signin.AccountType.SigninConsent",
                                     account_type);
       break;
-    // TODO(crbug.com/1462552): Remove kSync usage after phase 3 migration. See
+    // TODO(crbug.com/40066949): Remove kSync usage after phase 3 migration. See
     // ConsentLevel::kSync documentation for more details.
     case signin::ConsentLevel::kSync:
       base::UmaHistogramEnumeration("Signin.AccountType.SyncConsent",
@@ -349,10 +349,6 @@
       base::RecordAction(
           base::UserMetricsAction("Signin_Signin_FromDevicesPage"));
       break;
-    case AccessPoint::ACCESS_POINT_CLOUD_PRINT:
-      base::RecordAction(
-          base::UserMetricsAction("Signin_Signin_FromCloudPrint"));
-      break;
     case AccessPoint::ACCESS_POINT_SIGNIN_PROMO:
       base::RecordAction(
           base::UserMetricsAction("Signin_Signin_FromSigninPromo"));
@@ -542,10 +538,6 @@
       base::RecordAction(
           base::UserMetricsAction("Signin_Impression_FromDevicesPage"));
       break;
-    case AccessPoint::ACCESS_POINT_CLOUD_PRINT:
-      base::RecordAction(
-          base::UserMetricsAction("Signin_Impression_FromCloudPrint"));
-      break;
     case AccessPoint::ACCESS_POINT_SIGNIN_PROMO:
       base::RecordAction(
           base::UserMetricsAction("Signin_Impression_FromSigninPromo"));
diff --git a/components/signin/public/base/signin_metrics.h b/components/signin/public/base/signin_metrics.h
index 63c03e4..479cb96 100644
--- a/components/signin/public/base/signin_metrics.h
+++ b/components/signin/public/base/signin_metrics.h
@@ -133,7 +133,7 @@
   ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN = 10,
   ACCESS_POINT_USER_MANAGER = 11,
   ACCESS_POINT_DEVICES_PAGE = 12,
-  ACCESS_POINT_CLOUD_PRINT = 13,
+  // ACCESS_POINT_CLOUD_PRINT = 13, no longer used.
   // ACCESS_POINT_CONTENT_AREA = 14, no longer used.
   ACCESS_POINT_SIGNIN_PROMO = 15,
   ACCESS_POINT_RECENT_TABS = 16,
diff --git a/components/signin/public/base/signin_metrics_unittest.cc b/components/signin/public/base/signin_metrics_unittest.cc
index 2829779..b76ad322 100644
--- a/components/signin/public/base/signin_metrics_unittest.cc
+++ b/components/signin/public/base/signin_metrics_unittest.cc
@@ -26,7 +26,6 @@
     AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN,
     AccessPoint::ACCESS_POINT_USER_MANAGER,
     AccessPoint::ACCESS_POINT_DEVICES_PAGE,
-    AccessPoint::ACCESS_POINT_CLOUD_PRINT,
     AccessPoint::ACCESS_POINT_SIGNIN_PROMO,
     AccessPoint::ACCESS_POINT_RECENT_TABS,
     AccessPoint::ACCESS_POINT_UNKNOWN,
@@ -58,7 +57,6 @@
     AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER,
     AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN,
     AccessPoint::ACCESS_POINT_DEVICES_PAGE,
-    AccessPoint::ACCESS_POINT_CLOUD_PRINT,
     AccessPoint::ACCESS_POINT_SIGNIN_PROMO,
     AccessPoint::ACCESS_POINT_RECENT_TABS,
     AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE,
@@ -104,8 +102,6 @@
         return "UserManager";
       case AccessPoint::ACCESS_POINT_DEVICES_PAGE:
         return "DevicesPage";
-      case AccessPoint::ACCESS_POINT_CLOUD_PRINT:
-        return "CloudPrint";
       case AccessPoint::ACCESS_POINT_SIGNIN_PROMO:
         return "SigninPromo";
       case AccessPoint::ACCESS_POINT_RECENT_TABS:
diff --git a/components/signin/public/identity_manager/access_token_fetcher.h b/components/signin/public/identity_manager/access_token_fetcher.h
index 7a2ccfc..ff4704b 100644
--- a/components/signin/public/identity_manager/access_token_fetcher.h
+++ b/components/signin/public/identity_manager/access_token_fetcher.h
@@ -236,7 +236,7 @@
   TokenCallback callback_;
   const Mode mode_;
 
-  // TODO(crbug.com/1462858): Remove this field once
+  // TODO(crbug.com/40067025): Remove this field once
   // kReplaceSyncPromosWithSignInPromos launches.
   const bool should_verify_scope_access_;
 
diff --git a/components/signin/public/identity_manager/identity_manager.h b/components/signin/public/identity_manager/identity_manager.h
index 2658952..bb3046b 100644
--- a/components/signin/public/identity_manager/identity_manager.h
+++ b/components/signin/public/identity_manager/identity_manager.h
@@ -171,7 +171,7 @@
   // documentation.
   // Returns a non-empty struct if the primary account exists and was granted
   // the required consent level.
-  // TODO(crbug.com/1462978): revisit this once `ConsentLevel::kSync` is
+  // TODO(crbug.com/40067058): revisit this once `ConsentLevel::kSync` is
   // removed.
   // TODO(1046746): Update (./README.md).
   CoreAccountInfo GetPrimaryAccountInfo(ConsentLevel consent_level) const;
@@ -185,7 +185,7 @@
   // account for sync.
   // Note that `ConsentLevel::kSync` is deprecated, see the `ConsentLevel`
   // documentation.
-  // TODO(crbug.com/1462978): revisit this once `ConsentLevel::kSync` is
+  // TODO(crbug.com/40067058): revisit this once `ConsentLevel::kSync` is
   // removed.
   bool HasPrimaryAccount(ConsentLevel consent_level) const;
 
@@ -678,7 +678,7 @@
   AccountConsistencyMethod account_consistency_ =
       AccountConsistencyMethod::kDisabled;
 
-  // TODO(crbug.com/1462858): Remove this field once
+  // TODO(crbug.com/40067025): Remove this field once
   // kReplaceSyncPromosWithSignInPromos launches.
   const bool should_verify_scope_access_;
 
diff --git a/components/signin/public/identity_manager/identity_test_environment_unittest.cc b/components/signin/public/identity_manager/identity_test_environment_unittest.cc
index e529911..cec26a1 100644
--- a/components/signin/public/identity_manager/identity_test_environment_unittest.cc
+++ b/components/signin/public/identity_manager/identity_test_environment_unittest.cc
@@ -56,7 +56,7 @@
   fetcher.reset();
 }
 
-// TODO(https://crbug.com/1462552): Delete this test once `ConsentLevel::kSync`
+// TODO(https://crbug.com/40066949): Delete this test once `ConsentLevel::kSync`
 // is deleted.
 TEST_F(IdentityTestEnvironmentTest,
        IdentityTestEnvironmentSetPrimaryAccountWithSyncConsent) {
@@ -90,12 +90,12 @@
                                                ConsentLevel::kSignin);
   EXPECT_TRUE(identity_manager->HasPrimaryAccount(ConsentLevel::kSignin));
 
-  // TODO(https://crbug.com/1462552): Remove once `ConsentLevel::kSync` is
+  // TODO(https://crbug.com/40066949): Remove once `ConsentLevel::kSync` is
   // deleted.
   EXPECT_FALSE(identity_manager->HasPrimaryAccount(ConsentLevel::kSync));
 }
 
-// TODO(https://crbug.com/1462552): Delete this test once `ConsentLevel::kSync`
+// TODO(https://crbug.com/40066949): Delete this test once `ConsentLevel::kSync`
 // is deleted.
 TEST_F(IdentityTestEnvironmentTest,
        IdentityTestEnvironmentMakePrimaryAccountAvailableWithSyncConsent) {
@@ -125,7 +125,7 @@
                                                          ConsentLevel::kSignin);
   EXPECT_TRUE(identity_manager->HasPrimaryAccount(ConsentLevel::kSignin));
 
-  // TODO(https://crbug.com/1462552): Remove once `ConsentLevel::kSync` is
+  // TODO(https://crbug.com/40066949): Remove once `ConsentLevel::kSync` is
   // deleted.
   EXPECT_FALSE(identity_manager->HasPrimaryAccount(ConsentLevel::kSync));
 }
diff --git a/components/signin/public/identity_manager/identity_test_utils.cc b/components/signin/public/identity_manager/identity_test_utils.cc
index f0c02c2d..c790d93 100644
--- a/components/signin/public/identity_manager/identity_test_utils.cc
+++ b/components/signin/public/identity_manager/identity_test_utils.cc
@@ -244,7 +244,7 @@
     return std::nullopt;
   }
 
-  // TODO(crbug.com/1462978): revisit this once `ConsentLevel::kSync` is
+  // TODO(crbug.com/40067058): revisit this once `ConsentLevel::kSync` is
   // removed.
   return identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync)
              ? signin::ConsentLevel::kSync
@@ -304,7 +304,7 @@
 }
 
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
-// TODO(crbug.com/1462978): remove this function once `ConsentLevel::kSync` is
+// TODO(crbug.com/40067058): remove this function once `ConsentLevel::kSync` is
 // removed.
 void RevokeSyncConsent(IdentityManager* identity_manager) {
   if (!identity_manager->HasPrimaryAccount(ConsentLevel::kSync))
diff --git a/components/signin/public/identity_manager/identity_test_utils.h b/components/signin/public/identity_manager/identity_test_utils.h
index c3f37f9..69ff88f6 100644
--- a/components/signin/public/identity_manager/identity_test_utils.h
+++ b/components/signin/public/identity_manager/identity_test_utils.h
@@ -111,7 +111,7 @@
 // NOTE: See disclaimer at top of file re: direct usage.
 // NOTE:`ConsentLevel::kSync` is deprecated, see the `ConsentLevel`
 // documentation.
-// TODO(crbug.com/1462978): remove this function once `ConsentLevel::kSync` is
+// TODO(crbug.com/40067058): remove this function once `ConsentLevel::kSync` is
 // removed.
 void RevokeSyncConsent(IdentityManager* identity_manager);
 #endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/components/signin/public/identity_manager/primary_account_change_event.cc b/components/signin/public/identity_manager/primary_account_change_event.cc
index 2a1ccc3a..182bf011 100644
--- a/components/signin/public/identity_manager/primary_account_change_event.cc
+++ b/components/signin/public/identity_manager/primary_account_change_event.cc
@@ -46,7 +46,7 @@
     return Type::kNone;
 
   // Cannot change the Sync account without clearing the primary account first.
-  // TODO(crbug.com/1462978): Delete this when ConsentLevel::kSync is
+  // TODO(crbug.com/40067058): Delete this when ConsentLevel::kSync is
   //     deleted. See ConsentLevel::kSync documentation for details.
   DCHECK(previous_state_.consent_level != ConsentLevel::kSync ||
          previous_state_.primary_account == current_state_.primary_account ||
@@ -64,7 +64,7 @@
       }
       return Type::kNone;
     case ConsentLevel::kSync:
-      // TODO(crbug.com/1462978): Delete this when ConsentLevel::kSync is
+      // TODO(crbug.com/40067058): Delete this when ConsentLevel::kSync is
       //     deleted. See ConsentLevel::kSync documentation for details.
       if (previous_state_.consent_level != current_state_.consent_level) {
         return current_state_.consent_level == ConsentLevel::kSync
@@ -119,7 +119,7 @@
     const PrimaryAccountChangeEvent& event_details) {
   PrimaryAccountChangeEvent::Type event_type_not_required =
       event_details.GetEventTypeFor(ConsentLevel::kSignin);
-  // TODO(crbug.com/1462978): Delete this when ConsentLevel::kSync is
+  // TODO(crbug.com/40067058): Delete this when ConsentLevel::kSync is
   //     deleted. See ConsentLevel::kSync documentation for details.
   PrimaryAccountChangeEvent::Type event_type_sync =
       event_details.GetEventTypeFor(ConsentLevel::kSync);
diff --git a/components/signin/public/identity_manager/primary_account_change_event_unittest.cc b/components/signin/public/identity_manager/primary_account_change_event_unittest.cc
index 33260bc..e3addd7 100644
--- a/components/signin/public/identity_manager/primary_account_change_event_unittest.cc
+++ b/components/signin/public/identity_manager/primary_account_change_event_unittest.cc
@@ -15,7 +15,7 @@
 using Type = signin::PrimaryAccountChangeEvent::Type;
 using State = signin::PrimaryAccountChangeEvent::State;
 
-// TODO(crbug.com/1462978): Revise this test suite when ConsentLevel::kSync is
+// TODO(crbug.com/40067058): Revise this test suite when ConsentLevel::kSync is
 //     deleted. See ConsentLevel::kSync documentation for details.
 class PrimaryAccountChangeEventTest : public testing::Test {
  public:
@@ -78,7 +78,7 @@
   EXPECT_EQ(Type::kNone, event.GetEventTypeFor(ConsentLevel::kSync));
 }
 
-// TODO(crbug.com/1462978): Delete this test when ConsentLevel::kSync is
+// TODO(crbug.com/40067058): Delete this test when ConsentLevel::kSync is
 //     deleted. See ConsentLevel::kSync documentation for details.
 TEST_F(PrimaryAccountChangeEventTest, ConsentLevelChangeFromNotRequiredToSync) {
   PrimaryAccountChangeEvent event(empty_not_required_, account1_sync_);
@@ -94,7 +94,7 @@
   EXPECT_EQ(Type::kSet, event.GetEventTypeFor(ConsentLevel::kSync));
 }
 
-// TODO(crbug.com/1462978): Delete this test when ConsentLevel::kSync is
+// TODO(crbug.com/40067058): Delete this test when ConsentLevel::kSync is
 //     deleted. See ConsentLevel::kSync documentation for details.
 TEST_F(PrimaryAccountChangeEventTest, ConsentLevelChangeFromSyncToNotRequired) {
   PrimaryAccountChangeEvent event(account1_sync_, account1_not_required_);
diff --git a/components/signin/public/identity_manager/primary_account_mutator.h b/components/signin/public/identity_manager/primary_account_mutator.h
index a79d0b0..cb20dcc 100644
--- a/components/signin/public/identity_manager/primary_account_mutator.h
+++ b/components/signin/public/identity_manager/primary_account_mutator.h
@@ -82,7 +82,7 @@
   // are written to the persistent storage.
   // TODO(crbug.com/1261772): Don't set a default `access_point`. All callsites
   //     should provide a valid value.
-  // TODO(crbug.com/1462858): ConsentLevel::kSync is being migrated away from,
+  // TODO(crbug.com/40067025): ConsentLevel::kSync is being migrated away from,
   //     please see ConsentLevel::kSync documentation before adding new calls
   //     with ConsentLevel::kSync. Also, update this documentation when the
   //     deprecation process advances.
diff --git a/components/signin/public/identity_manager/primary_account_mutator_unittest.cc b/components/signin/public/identity_manager/primary_account_mutator_unittest.cc
index 15767d0..0383372 100644
--- a/components/signin/public/identity_manager/primary_account_mutator_unittest.cc
+++ b/components/signin/public/identity_manager/primary_account_mutator_unittest.cc
@@ -55,7 +55,7 @@
 
 // Helper IdentityManager::Observer that forwards some events to the
 // callback passed to the constructor.
-// TODO(crbug.com/1462978): Delete this class when ConsentLevel::kSync is
+// TODO(crbug.com/40067058): Delete this class when ConsentLevel::kSync is
 //     deleted. See ConsentLevel::kSync documentation for details.
 class ClearPrimaryAccountTestObserver
     : public signin::IdentityManager::Observer {
@@ -113,7 +113,7 @@
 // Optionally, it's possible to specify whether a normal auth process will
 // take place, or whether an auth error should happen, useful for some tests.
 //
-// TODO(crbug.com/1462978): Delete this test when ConsentLevel::kSync is
+// TODO(crbug.com/40067058): Delete this test when ConsentLevel::kSync is
 //     deleted. See ConsentLevel::kSync documentation for details.
 void RunRevokeConsentTest(
     RevokeConsentAction action,
@@ -284,7 +284,7 @@
       .WillOnce([&](const signin::PrimaryAccountChangeEvent& event) {
         ASSERT_EQ(event.GetEventTypeFor(signin::ConsentLevel::kSignin),
                   signin::PrimaryAccountChangeEvent::Type::kCleared);
-        // TODO(crbug.com/1462978): Delete this assert when ConsentLevel::kSync
+        // TODO(crbug.com/40067058): Delete this assert when ConsentLevel::kSync
         //     is deleted. See ConsentLevel::kSync documentation for details.
         ASSERT_EQ(event.GetEventTypeFor(signin::ConsentLevel::kSync),
                   signin::PrimaryAccountChangeEvent::Type::kNone);
@@ -352,7 +352,7 @@
 }
 
 // Checks that setting the primary account works.
-// TODO(crbug.com/1462978): Delete this test when ConsentLevel::kSync is
+// TODO(crbug.com/40067058): Delete this test when ConsentLevel::kSync is
 //     deleted. See ConsentLevel::kSync documentation for details.
 TEST_F(PrimaryAccountMutatorTest, SetPrimaryAccount_Sync) {
   base::test::TaskEnvironment task_environment;
@@ -449,7 +449,7 @@
 
 // Checks that trying to set the primary account fails when there is already a
 // primary account.
-// TODO(crbug.com/1462978): Delete this test when ConsentLevel::kSync is
+// TODO(crbug.com/40067058): Delete this test when ConsentLevel::kSync is
 //     deleted. See ConsentLevel::kSync documentation for details.
 TEST_F(PrimaryAccountMutatorTest, SetPrimaryAccount_AlreadyHasPrimaryAccount) {
   base::test::TaskEnvironment task_environment;
diff --git a/components/sync/protocol/get_updates_caller_info.proto b/components/sync/protocol/get_updates_caller_info.proto
index ccdaf188..97eec5b 100644
--- a/components/sync/protocol/get_updates_caller_info.proto
+++ b/components/sync/protocol/get_updates_caller_info.proto
@@ -15,49 +15,15 @@
 package sync_pb;
 
 message GetUpdatesCallerInfo {
-  // This enum was deprecated in M28.  The preferred represenation of this
-  // information is now the GetUpdatesOrigin enum, which is defined in
-  // sync_enums.proto.
-  // TODO(crbug.com/510165): Remove all values except for UNKNOWN and stop
-  // filling the field once the server doesn't depend on it anymore.
+  // This enum was deprecated in M28, and is unused since 2018. But since it's
+  // used in a required field, it's hard to fully remove.
   enum GetUpdatesSource {
-    UNKNOWN = 0;       // The source was not set by the caller.
-    FIRST_UPDATE = 1;  // First request after browser restart.  Not to
-                       // be confused with "NEW_CLIENT".
-    LOCAL = 2;         // The source of the update was a local change.
-    NOTIFICATION = 3;  // The source of the update was a p2p notification.
-    PERIODIC = 4;      // The source of the update was periodic polling.
-    SYNC_CYCLE_CONTINUATION = 5;  // The source of the update was a
-                                  // continuation of a previous sync cycle.
-                                  // No longer sent as of M24.
-
-    // This value is deprecated and was never used in production.
-    // CLEAR_PRIVATE_DATA = 6;
-
-    NEWLY_SUPPORTED_DATATYPE = 7;  // The client is in configuration mode
-                                   // because it's syncing all datatypes, and
-                                   // support for a new datatype was recently
-                                   // released via a software auto-update.
-    MIGRATION = 8;          // The client is in configuration mode because a
-                            // MIGRATION_DONE error previously returned by the
-                            // server necessitated resynchronization.
-    NEW_CLIENT = 9;         // The client is in configuration mode because the
-                            // user enabled sync for the first time.  Not to be
-                            // confused with FIRST_UPDATE.
-    RECONFIGURATION = 10;   // The client is in configuration mode because the
-                            // user opted to sync a different set of datatypes.
-    DATATYPE_REFRESH = 11;  // A datatype has requested a refresh. This is
-                            // typically used when datatype's have custom
-                            // sync UI, e.g. sessions.
-    RETRY = 13;  // A follow-up GU to pick up updates missed by previous GU.
-    PROGRAMMATIC = 14;  // The client is programmatically enabling/disabling
-                        // a type, typically for error handling purposes.
+    UNKNOWN = 0;
   }
-
   required GetUpdatesSource source = 1 [deprecated = true];
 
-  // True only if notifications were enabled for this GetUpdateMessage.
-  // TODO(crbug.com/510165): Move this bool out of GetUpdatesCallerInfo so that
-  // GetUpdatesCallerInfo can eventually be removed.
+  // True if notifications were enabled for this GetUpdateMessage.
+  // Note: Ideally this would be moved out of GetUpdatesCallerInfo, so that
+  // GetUpdatesCallerInfo itself can be removed.
   optional bool notifications_enabled = 2;
 }
diff --git a/components/sync/protocol/proto_enum_conversions.cc b/components/sync/protocol/proto_enum_conversions.cc
index 3028a93..4c17376 100644
--- a/components/sync/protocol/proto_enum_conversions.cc
+++ b/components/sync/protocol/proto_enum_conversions.cc
@@ -142,21 +142,9 @@
 const char* ProtoEnumToString(
     sync_pb::GetUpdatesCallerInfo::GetUpdatesSource updates_source) {
   ASSERT_ENUM_BOUNDS(sync_pb::GetUpdatesCallerInfo, GetUpdatesSource, UNKNOWN,
-                     PROGRAMMATIC);
+                     UNKNOWN);
   switch (updates_source) {
     ENUM_CASE(sync_pb::GetUpdatesCallerInfo, UNKNOWN);
-    ENUM_CASE(sync_pb::GetUpdatesCallerInfo, FIRST_UPDATE);
-    ENUM_CASE(sync_pb::GetUpdatesCallerInfo, LOCAL);
-    ENUM_CASE(sync_pb::GetUpdatesCallerInfo, NOTIFICATION);
-    ENUM_CASE(sync_pb::GetUpdatesCallerInfo, PERIODIC);
-    ENUM_CASE(sync_pb::GetUpdatesCallerInfo, SYNC_CYCLE_CONTINUATION);
-    ENUM_CASE(sync_pb::GetUpdatesCallerInfo, NEWLY_SUPPORTED_DATATYPE);
-    ENUM_CASE(sync_pb::GetUpdatesCallerInfo, MIGRATION);
-    ENUM_CASE(sync_pb::GetUpdatesCallerInfo, NEW_CLIENT);
-    ENUM_CASE(sync_pb::GetUpdatesCallerInfo, RECONFIGURATION);
-    ENUM_CASE(sync_pb::GetUpdatesCallerInfo, DATATYPE_REFRESH);
-    ENUM_CASE(sync_pb::GetUpdatesCallerInfo, RETRY);
-    ENUM_CASE(sync_pb::GetUpdatesCallerInfo, PROGRAMMATIC);
   }
   NOTREACHED();
   return "";
diff --git a/components/sync/service/sync_auth_manager.cc b/components/sync/service/sync_auth_manager.cc
index 8f5225b..61f23ac 100644
--- a/components/sync/service/sync_auth_manager.cc
+++ b/components/sync/service/sync_auth_manager.cc
@@ -65,7 +65,7 @@
     return SyncAccountInfo();
   }
 
-  // TODO(crbug.com/1462552): Simplify once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Simplify once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   return {.account_info = identity_manager->GetPrimaryAccountInfo(
diff --git a/components/sync/service/sync_internals_util.cc b/components/sync/service/sync_internals_util.cc
index d4fda3f..58e8db2 100644
--- a/components/sync/service/sync_internals_util.cc
+++ b/components/sync/service/sync_internals_util.cc
@@ -447,7 +447,7 @@
                    /*is_good=*/user_actionable_error ==
                        SyncService::UserActionableError::kNone);
   disable_reasons->Set(GetDisableReasonsString(service->GetDisableReasons()));
-  // TODO(crbug.com/1462978): Delete this when ConsentLevel::kSync is deleted.
+  // TODO(crbug.com/40067058): Delete this when ConsentLevel::kSync is deleted.
   // See ConsentLevel::kSync documentation for details.
   feature_enabled->Set(service->IsSyncFeatureEnabled());
   setup_in_progress->Set(service->IsSetupInProgress());
@@ -480,8 +480,8 @@
   }
   if (!is_local_sync_enabled_state) {
     username->Set(service->GetAccountInfo().email);
-    // TODO(crbug.com/1462978): Delete this when ConsentLevel::kSync is deleted.
-    // See ConsentLevel::kSync documentation for details.
+    // TODO(crbug.com/40067058): Delete this when ConsentLevel::kSync is
+    // deleted. See ConsentLevel::kSync documentation for details.
     user_has_consent->Set(service->HasSyncConsent());
   }
 
@@ -502,7 +502,7 @@
           token_status.connection_status == CONNECTION_OK);
   last_synced->Set(
       GetLastSyncedTimeString(service->GetLastSyncedTimeForDebugging()));
-  // TODO(crbug.com/1462978): Delete this when ConsentLevel::kSync is deleted.
+  // TODO(crbug.com/40067058): Delete this when ConsentLevel::kSync is deleted.
   // See ConsentLevel::kSync documentation for details.
   is_setup_complete->Set(
       service->GetUserSettings()->IsInitialSyncFeatureSetupComplete());
diff --git a/components/sync/service/sync_service.h b/components/sync/service/sync_service.h
index c8b22d9..50a0e9f 100644
--- a/components/sync/service/sync_service.h
+++ b/components/sync/service/sync_service.h
@@ -300,7 +300,7 @@
   // Whether the primary account has consented to Sync (see IdentityManager). If
   // this is false, then IsSyncFeatureEnabled will also be false, but
   // Sync-the-transport might still run.
-  // TODO(crbug.com/1462552): Remove once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Remove once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   virtual bool HasSyncConsent() const = 0;
@@ -334,7 +334,7 @@
   // first-time Sync setup has been completed by the user.
   // Note: This does not imply that Sync is actually running. Check
   // IsSyncFeatureActive or GetTransportState to get the current state.
-  // TODO(crbug.com/1462552): Remove once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Remove once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   bool IsSyncFeatureEnabled() const;
@@ -356,7 +356,7 @@
   // even if this is false.
   // TODO(crbug.com/1444344): Remove this API, in favor of
   // IsSyncFeatureEnabled().
-  // TODO(crbug.com/1462552): Remove once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Remove once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   bool CanSyncFeatureStart() const;
@@ -367,7 +367,7 @@
   // To see which datatypes are actually syncing, see GetActiveDataTypes().
   // Note: This refers to Sync-the-feature. Sync-the-transport may be active
   // even if this is false.
-  // TODO(crbug.com/1462552): Remove once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Remove once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   bool IsSyncFeatureActive() const;
diff --git a/components/sync/service/sync_service_impl.cc b/components/sync/service/sync_service_impl.cc
index 66f7bba..1c8f9a0 100644
--- a/components/sync/service/sync_service_impl.cc
+++ b/components/sync/service/sync_service_impl.cc
@@ -1121,7 +1121,7 @@
 #else  // !BUILDFLAG(IS_CHROMEOS_ASH)
       // On every platform except ash, revoke the Sync consent/Clear primary
       // account after a dashboard clear.
-      // TODO(crbug.com/1462552): Simplify once kSync becomes unreachable or is
+      // TODO(crbug.com/40066949): Simplify once kSync becomes unreachable or is
       // deleted from the codebase. See ConsentLevel::kSync documentation for
       // details.
       if (!IsLocalSyncEnabled() &&
diff --git a/components/sync/service/sync_service_impl_startup_unittest.cc b/components/sync/service/sync_service_impl_startup_unittest.cc
index 2ad0463..8a341149 100644
--- a/components/sync/service/sync_service_impl_startup_unittest.cc
+++ b/components/sync/service/sync_service_impl_startup_unittest.cc
@@ -76,7 +76,7 @@
         kEmail, signin::ConsentLevel::kSignin);
   }
 
-  // TODO(crbug.com/1462552): Remove once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Remove once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   void SignInWithSyncConsent() {
@@ -98,7 +98,7 @@
     sync_service_impl_bundle_.identity_test_env()->WaitForRefreshTokensLoaded();
   }
 
-  // TODO(crbug.com/1462552): Remove once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Remove once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   void SignInWithSyncConsentWithoutRefreshToken() {
diff --git a/components/sync/service/sync_service_impl_unittest.cc b/components/sync/service/sync_service_impl_unittest.cc
index 7c828c6..6e545c82 100644
--- a/components/sync/service/sync_service_impl_unittest.cc
+++ b/components/sync/service/sync_service_impl_unittest.cc
@@ -130,7 +130,7 @@
         kTestUser, signin::ConsentLevel::kSignin);
   }
 
-  // TODO(crbug.com/1462552): Remove once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Remove once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   void SignInWithSyncConsent() {
@@ -826,7 +826,7 @@
   ASSERT_EQ(SyncService::TransportState::ACTIVE,
             service()->GetTransportState());
 
-  // TODO(crbug.com/1462552): Update once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Update once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   const CoreAccountId primary_account_id =
@@ -868,7 +868,7 @@
   TestSyncServiceObserver observer;
   service()->AddObserver(&observer);
 
-  // TODO(crbug.com/1462552): Remove once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Remove once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   const CoreAccountId primary_account_id =
@@ -922,7 +922,7 @@
   ASSERT_EQ(SyncService::TransportState::ACTIVE,
             service()->GetTransportState());
 
-  // TODO(crbug.com/1462552): Remove once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Remove once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   const CoreAccountId primary_account_id =
@@ -1056,7 +1056,7 @@
   ASSERT_EQ(SyncService::TransportState::ACTIVE,
             service()->GetTransportState());
 
-  // TODO(crbug.com/1462552): Remove once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Remove once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   const CoreAccountId primary_account_id =
@@ -1116,7 +1116,7 @@
   ASSERT_EQ(SyncService::TransportState::ACTIVE,
             service()->GetTransportState());
 
-  // TODO(crbug.com/1462552): Remove once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Remove once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   const CoreAccountId primary_account_id =
@@ -1231,7 +1231,7 @@
       service()->GetUserSettings()->IsSyncFeatureDisabledViaDashboard());
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-  // TODO(crbug.com/1462552): Update once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Update once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   const std::string primary_account_gaia_id =
@@ -1251,7 +1251,7 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // Ash does not support signout.
-  // TODO(crbug.com/1462552): Remove once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Remove once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   EXPECT_TRUE(
@@ -1278,7 +1278,7 @@
   // On Desktop and Lacros, the sync consent is revoked, but the primary account
   // is left at ConsentLevel::kSignin. Sync will restart in standalone transport
   // mode.
-  // TODO(crbug.com/1462552): Remove once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Remove once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   EXPECT_FALSE(
diff --git a/components/sync/service/sync_session_durations_metrics_recorder.cc b/components/sync/service/sync_session_durations_metrics_recorder.cc
index c9de653a..eed17c07 100644
--- a/components/sync/service/sync_session_durations_metrics_recorder.cc
+++ b/components/sync/service/sync_session_durations_metrics_recorder.cc
@@ -308,7 +308,7 @@
 
 SyncSessionDurationsMetricsRecorder::FeatureState
 SyncSessionDurationsMetricsRecorder::DetermineSyncStatus() const {
-  // TODO(crbug.com/1462552): Simplify once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Simplify once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   if (!sync_service_ || !sync_service_->CanSyncFeatureStart()) {
diff --git a/components/sync/service/sync_session_durations_metrics_recorder_unittest.cc b/components/sync/service/sync_session_durations_metrics_recorder_unittest.cc
index d3cbee9..7cddd494 100644
--- a/components/sync/service/sync_session_durations_metrics_recorder_unittest.cc
+++ b/components/sync/service/sync_session_durations_metrics_recorder_unittest.cc
@@ -38,7 +38,7 @@
   ~SyncSessionDurationsMetricsRecorderTest() override = default;
 
   void EnableSync() {
-    // TODO(crbug.com/1462552): Remove once kSync becomes unreachable or is
+    // TODO(crbug.com/40066949): Remove once kSync becomes unreachable or is
     // deleted from the codebase. See ConsentLevel::kSync documentation for
     // details.
     identity_test_env_.MakePrimaryAccountAvailable("foo@gmail.com",
@@ -54,7 +54,7 @@
     DCHECK_EQ(sync_service_.GetTransportState(),
               SyncService::TransportState::PAUSED);
 
-    // TODO(crbug.com/1462552): Remove once kSync becomes unreachable or is
+    // TODO(crbug.com/40066949): Remove once kSync becomes unreachable or is
     // deleted from the codebase. See ConsentLevel::kSync documentation for
     // details.
     identity_test_env_.UpdatePersistentErrorOfRefreshTokenForAccount(
diff --git a/components/unified_consent/unified_consent_service.cc b/components/unified_consent/unified_consent_service.cc
index f587a2a..f66914b 100644
--- a/components/unified_consent/unified_consent_service.cc
+++ b/components/unified_consent/unified_consent_service.cc
@@ -213,7 +213,7 @@
 
 void UnifiedConsentService::OnPrimaryAccountChanged(
     const signin::PrimaryAccountChangeEvent& event) {
-  // TODO(crbug.com/1462552): Simplify once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Simplify once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   if (event.GetEventTypeFor(signin::ConsentLevel::kSync) ==
diff --git a/components/unified_consent/url_keyed_data_collection_consent_helper.cc b/components/unified_consent/url_keyed_data_collection_consent_helper.cc
index ccc6c58..2b2172e 100644
--- a/components/unified_consent/url_keyed_data_collection_consent_helper.cc
+++ b/components/unified_consent/url_keyed_data_collection_consent_helper.cc
@@ -174,7 +174,7 @@
 
 void SyncBasedUrlKeyedDataCollectionConsentHelper::UpdateSyncDataTypeStates() {
   if (require_sync_feature_enabled_) {
-    // TODO(crbug.com/1462552): Find a replacement once IsSyncFeatureEnabled()
+    // TODO(crbug.com/40066949): Find a replacement once IsSyncFeatureEnabled()
     // starts always returning false.
     sync_feature_state_ =
         sync_service_ && sync_service_->IsSyncFeatureEnabled();
diff --git a/components/user_manager/fake_user_manager.cc b/components/user_manager/fake_user_manager.cc
index d75894e..13bf4c1 100644
--- a/components/user_manager/fake_user_manager.cc
+++ b/components/user_manager/fake_user_manager.cc
@@ -121,6 +121,11 @@
   RemoveUserFromList(account_id);
 }
 
+void FakeUserManager::CleanStaleUserInformationFor(
+    const AccountId& account_id) {
+  RemoveUserFromList(account_id);
+}
+
 const UserList& FakeUserManager::GetUsers() const {
   return users_;
 }
diff --git a/components/user_manager/fake_user_manager.h b/components/user_manager/fake_user_manager.h
index 7ed9ae6..b2568da8 100644
--- a/components/user_manager/fake_user_manager.h
+++ b/components/user_manager/fake_user_manager.h
@@ -85,6 +85,7 @@
                   UserRemovalReason reason) override {}
   void RemoveUserFromList(const AccountId& account_id) override;
   void RemoveUserFromListForRecreation(const AccountId& account_id) override;
+  void CleanStaleUserInformationFor(const AccountId& account_id) override;
   bool IsKnownUser(const AccountId& account_id) const override;
   const User* FindUser(const AccountId& account_id) const override;
   User* FindUserAndModify(const AccountId& account_id) override;
diff --git a/components/user_manager/user_manager.h b/components/user_manager/user_manager.h
index 1d5d4e5..73c7c7538 100644
--- a/components/user_manager/user_manager.h
+++ b/components/user_manager/user_manager.h
@@ -267,6 +267,16 @@
   // better solution.
   virtual void RemoveUserFromListForRecreation(const AccountId& account_id) = 0;
 
+  // Removes the user from the device in case when user's cryptohome is lost
+  // for some reason to ensure that user is correctly re-created.
+  // Does not trigger user removal notification.
+  // This method is similar to `RemoveUserFromListForRecreation`, but is
+  // triggered at different stage of login process, and when absence of user
+  // directory is not anticipated by the flow. This removes the user from the
+  // list synchronously, so the following function calls should have updated
+  // users.
+  virtual void CleanStaleUserInformationFor(const AccountId& account_id) = 0;
+
   // Returns true if a user with the given account id is found in the persistent
   // list or currently logged in as ephemeral.
   virtual bool IsKnownUser(const AccountId& account_id) const = 0;
diff --git a/components/user_manager/user_manager_base.cc b/components/user_manager/user_manager_base.cc
index 1c14493..4e087ddc 100644
--- a/components/user_manager/user_manager_base.cc
+++ b/components/user_manager/user_manager_base.cc
@@ -338,6 +338,15 @@
                          /*trigger_cryptohome_removal=*/false);
 }
 
+void UserManagerBase::CleanStaleUserInformationFor(
+    const AccountId& account_id) {
+  KnownUser known_user(local_state_);
+  if (known_user.UserExists(account_id)) {
+    known_user.RemovePrefs(account_id);
+    known_user.SaveKnownUser(account_id);
+  }
+}
+
 void UserManagerBase::RemoveUserFromListImpl(
     const AccountId& account_id,
     std::optional<UserRemovalReason> reason,
diff --git a/components/user_manager/user_manager_base.h b/components/user_manager/user_manager_base.h
index d07ed0b..afeed00 100644
--- a/components/user_manager/user_manager_base.h
+++ b/components/user_manager/user_manager_base.h
@@ -105,6 +105,7 @@
                   UserRemovalReason reason) override;
   void RemoveUserFromList(const AccountId& account_id) override;
   void RemoveUserFromListForRecreation(const AccountId& account_id) override;
+  void CleanStaleUserInformationFor(const AccountId& account_id) override;
   bool IsKnownUser(const AccountId& account_id) const override;
   const User* FindUser(const AccountId& account_id) const override;
   User* FindUserAndModify(const AccountId& account_id) override;
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index 019506a..bce15644 100644
--- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -1869,8 +1869,16 @@
   RunHtmlTest(FILE_PATH_LITERAL("contenteditable-docs-li.html"));
 }
 
+// TODO(b/324376803): Re-enable flaky test.
+#if BUILDFLAG(IS_MAC)
+#define MAYBE_AccessibilityContenteditableDocsLi \
+  DISABLED_AccessibilityContenteditableDocsLi
+#else
+#define MAYBE_AccessibilityContenteditableDocsLi \
+  AccessibilityContenteditableDocsLi
+#endif
 IN_PROC_BROWSER_TEST_P(YieldingParserDumpAccessibilityTreeTest,
-                       AccessibilityContenteditableDocsLi) {
+                       MAYBE_AccessibilityContenteditableDocsLi) {
   RunHtmlTest(FILE_PATH_LITERAL("contenteditable-docs-li.html"));
 }
 
diff --git a/content/browser/attribution_reporting/attribution_internals_browsertest.cc b/content/browser/attribution_reporting/attribution_internals_browsertest.cc
index d207d0d..3f96109 100644
--- a/content/browser/attribution_reporting/attribution_internals_browsertest.cc
+++ b/content/browser/attribution_reporting/attribution_internals_browsertest.cc
@@ -752,7 +752,7 @@
     // Sort by priority ascending.
     ASSERT_TRUE(ExecJsInWebUI(R"(
       document.querySelector('#reportTable')
-        .shadowRoot.querySelectorAll('th')[5].click();
+        .shadowRoot.querySelector('th:nth-child(6) button').click();
     )"));
     ASSERT_EQ(kCompleteTitle2, title_watcher.WaitAndGetTitle());
   }
@@ -791,7 +791,7 @@
     // Sort by priority descending.
     ASSERT_TRUE(ExecJsInWebUI(R"(
       document.querySelector('#reportTable')
-        .shadowRoot.querySelectorAll('th')[5].click();
+        .shadowRoot.querySelector('th:nth-child(6) button').click();
     )"));
     ASSERT_EQ(kCompleteTitle3, title_watcher.WaitAndGetTitle());
   }
diff --git a/content/browser/network/shared_dictionary_browsertest.cc b/content/browser/network/shared_dictionary_browsertest.cc
index 5794031..f9931f19 100644
--- a/content/browser/network/shared_dictionary_browsertest.cc
+++ b/content/browser/network/shared_dictionary_browsertest.cc
@@ -65,50 +65,47 @@
 
 // Generated by:
 //  tools/origin_trials/generate_token.py --version 3 --expire-days 3650 \
-//      https://shared-dictionary.test CompressionDictionaryTransport
+//      https://shared-dictionary.test CompressionDictionaryTransportV2
 // Token details:
 //  Version: 3
 //  Origin: https://shared-dictionary.test:443
 //  Is Subdomain: None
 //  Is Third Party: None
 //  Usage Restriction: None
-//  Feature: CompressionDictionaryTransportForTest
-//  Expiry: 2021587921 (2034-01-23 00:12:01 UTC)
+//  Feature: CompressionDictionaryTransportV2
+//  Expiry: 2022646497 (2034-02-04 06:14:57 UTC)
 //  Signature (Base64):
-//      Jwep7Wi24cUGZGE97g4mInnJqjlL1vtgc5wzkmA7rgPmVOXvNjijuMCjr/m44anH6sHiDpkG
-//      i3Z4ymlj5OFmAw==
+//      iSWtWCojh+4RRpPFD/sN2iIldcgTAqoVymCrvnJ70GR55Xz454uH4GDxFNHkREXsFwDG0ZPx
+//      llzEtFSCK0uoBQ==
 constexpr std::string_view kOriginTrialToken =
-    "AycHqe1otuHFBmRhPe4OJiJ5yao5S9b7YHOcM5JgO64D5lTl7zY4o7jAo6/5uOGpx+rB4g6ZBo"
-    "t2eMppY+ThZgMAAAB6eyJvcmlnaW4iOiAiaHR0cHM6Ly9zaGFyZWQtZGljdGlvbmFyeS50ZXN0"
-    "OjQ0MyIsICJmZWF0dXJlIjogIkNvbXByZXNzaW9uRGljdGlvbmFyeVRyYW5zcG9ydEZvclRlc3"
-    "QiLCAiZXhwaXJ5IjogMjAyMTU4NzkyMX0=";
+    "A4klrVgqI4fuEUaTxQ/7DdoiJXXIEwKqFcpgq75ye9BkeeV8+OeLh+Bg8RTR5ERF7BcAxtGT8Z"
+    "ZcxLRUgitLqAUAAAB1eyJvcmlnaW4iOiAiaHR0cHM6Ly9zaGFyZWQtZGljdGlvbmFyeS50ZXN0"
+    "OjQ0MyIsICJmZWF0dXJlIjogIkNvbXByZXNzaW9uRGljdGlvbmFyeVRyYW5zcG9ydFYyIiwgIm"
+    "V4cGlyeSI6IDIwMjI2NDY0OTd9";
 
 // Generated by:
 //  tools/origin_trials/generate_token.py --version 3 --expire-days 3650 \
 //      --is-third-party \
-//      https://shared-dictionary.test CompressionDictionaryTransportForTest
+//      https://shared-dictionary.test CompressionDictionaryTransportV2
 // Token details:
 //  Version: 3
 //  Origin: https://shared-dictionary.test:443
 //  Is Subdomain: None
 //  Is Third Party: True
 //  Usage Restriction: None
-//  Feature: CompressionDictionaryTransportForTest
-//  Expiry: 2021587536 (2034-01-23 00:05:36 UTC)
+//  Feature: CompressionDictionaryTransportV2
+//  Expiry: 2022647128 (2034-02-04 06:25:28 UTC)
 //  Signature (Base64):
-//      N4A/mWnaU02PTXa0Sd2TyX1hGhjhJGe/KoH9O0RxJI2OCEIlmZVM8e+AJLpp3D/qNWIfS3oX
-//      dg0sEPDyr/nICQ==
+//      O4XHAT50NH7/v3OTMgrJHRt1UqWEU09IXNRJNmhFfd+S/Q0ysYTX/kjPc+TbH/TnZrb0aXoO
+//      JhpWj/rqE8a6Dw==
 constexpr std::string_view kThirdPartyOriginTrialToken =
-    "AzeAP5lp2lNNj012tEndk8l9YRoY4SRnvyqB/TtEcSSNjghCJZmVTPHvgCS6adw/6jViH0t6F3"
-    "YNLBDw8q/5yAkAAACQeyJvcmlnaW4iOiAiaHR0cHM6Ly9zaGFyZWQtZGljdGlvbmFyeS50ZXN0"
-    "OjQ0MyIsICJmZWF0dXJlIjogIkNvbXByZXNzaW9uRGljdGlvbmFyeVRyYW5zcG9ydEZvclRlc3"
-    "QiLCAiZXhwaXJ5IjogMjAyMTU4NzUzNiwgImlzVGhpcmRQYXJ0eSI6IHRydWV9";
+    "AzuFxwE+dDR+/79zkzIKyR0bdVKlhFNPSFzUSTZoRX3fkv0NMrGE1/5Iz3Pk2x/052a29Gl6Di"
+    "YaVo/66hPGug8AAACLeyJvcmlnaW4iOiAiaHR0cHM6Ly9zaGFyZWQtZGljdGlvbmFyeS50ZXN0"
+    "OjQ0MyIsICJmZWF0dXJlIjogIkNvbXByZXNzaW9uRGljdGlvbmFyeVRyYW5zcG9ydFYyIiwgIm"
+    "V4cGlyeSI6IDIwMjI2NDcxMjgsICJpc1RoaXJkUGFydHkiOiB0cnVlfQ==";
 
-// The SHA256 hash of dictionary
-// (content/test/data/shared_dictionary/test.dict and test_dict.html).
-constexpr std::string_view kExpectedDictionaryHash =
-    "53969bcf5e960e0edbf0a4bdde6b0b3e9381e156de7f5b91ce8391624270f416";
 // The Structured Field sf-binary hash of sha256 of dictionary.
+// (content/test/data/shared_dictionary/test.dict and test_dict.html).
 constexpr std::string_view kExpectedDictionaryHashBase64 =
     ":U5abz16WDg7b8KS93msLPpOB4Vbef1uRzoORYkJw9BY=:";
 constexpr net::SHA256HashValue kExpectedDictionaryHashValue = {
@@ -116,16 +113,6 @@
      0xbd, 0xde, 0x6b, 0x0b, 0x3e, 0x93, 0x81, 0xe1, 0x56, 0xde, 0x7f,
      0x5b, 0x91, 0xce, 0x83, 0x91, 0x62, 0x42, 0x70, 0xf4, 0x16}};
 
-std::string_view GetExpectedDictionaryHashString() {
-  switch (
-      network::features::kCompressionDictionaryTransportBackendVersion.Get()) {
-    case network::features::CompressionDictionaryTransportBackendVersion::kV1:
-      return kExpectedDictionaryHash;
-    case network::features::CompressionDictionaryTransportBackendVersion::kV2:
-      return kExpectedDictionaryHashBase64;
-  }
-}
-
 constexpr std::string_view kUncompressedDataString =
     "test(\"This is uncompressed.\");";
 constexpr std::string_view kErrorInvalidHashString =
@@ -220,16 +207,6 @@
   return true;
 }
 
-std::string ToString(
-    network::features::CompressionDictionaryTransportBackendVersion version) {
-  switch (version) {
-    case network::features::CompressionDictionaryTransportBackendVersion::kV1:
-      return "V1";
-    case network::features::CompressionDictionaryTransportBackendVersion::kV2:
-      return "V2";
-  }
-}
-
 enum class FeatureState {
   kDisabled,
   kBackendOnly,
@@ -416,45 +393,22 @@
 }
 std::optional<std::string> GetAvailableDictionary(
     const net::test_server::HttpRequest::HeaderMap& headers) {
-  switch (
-      network::features::kCompressionDictionaryTransportBackendVersion.Get()) {
-    case network::features::CompressionDictionaryTransportBackendVersion::kV1: {
-      auto it = headers.find("sec-available-dictionary");
-      return it == headers.end() ? std::nullopt
-                                 : std::make_optional(it->second);
-    }
-    case network::features::CompressionDictionaryTransportBackendVersion::kV2: {
       auto it = headers.find("available-dictionary");
       return it == headers.end() ? std::nullopt
                                  : std::make_optional(it->second);
-    }
-  }
 }
 
 bool HasSharedDictionaryAcceptEncoding(
-    const net::test_server::HttpRequest::HeaderMap& headers,
-    network::features::CompressionDictionaryTransportBackendVersion version) {
+    const net::test_server::HttpRequest::HeaderMap& headers) {
   auto it = headers.find(net::HttpRequestHeaders::kAcceptEncoding);
   if (it == headers.end()) {
     return false;
   }
-  switch (version) {
-    case network::features::CompressionDictionaryTransportBackendVersion::kV1: {
-      if (base::FeatureList::IsEnabled(network::features::kSharedZstd)) {
-        return it->second == "sbr, zstd-d" ||
-               base::EndsWith(it->second, ", sbr, zstd-d");
-      } else {
-        return it->second == "sbr" || base::EndsWith(it->second, ", sbr");
-      }
-    }
-    case network::features::CompressionDictionaryTransportBackendVersion::kV2: {
-      if (base::FeatureList::IsEnabled(network::features::kSharedZstd)) {
-        return it->second == "br-d, zstd-d" ||
-               base::EndsWith(it->second, ", br-d, zstd-d");
-      } else {
-        return it->second == "br-d" || base::EndsWith(it->second, ", br-d");
-      }
-    }
+  if (base::FeatureList::IsEnabled(network::features::kSharedZstd)) {
+    return it->second == "br-d, zstd-d" ||
+           base::EndsWith(it->second, ", br-d, zstd-d");
+  } else {
+    return it->second == "br-d" || base::EndsWith(it->second, ", br-d");
   }
 }
 
@@ -598,10 +552,7 @@
 
 class SharedDictionaryBrowserTestBase : public ContentBrowserTest {
  public:
-  explicit SharedDictionaryBrowserTestBase(
-      const network::features::CompressionDictionaryTransportBackendVersion
-          version)
-      : version_(version) {}
+  SharedDictionaryBrowserTestBase() = default;
 
   SharedDictionaryBrowserTestBase(const SharedDictionaryBrowserTestBase&) =
       delete;
@@ -792,8 +743,8 @@
     std::optional<std::string> dict_hash =
         GetAvailableDictionary(request.headers);
     if (dict_hash) {
-      if (*dict_hash == GetExpectedDictionaryHashString()) {
-        if (HasSharedDictionaryAcceptEncoding(request.headers, version_)) {
+      if (*dict_hash == kExpectedDictionaryHashBase64) {
+        if (HasSharedDictionaryAcceptEncoding(request.headers)) {
           response->AddCustomHeader("content-dictionary",
                                     kExpectedDictionaryHashBase64);
           if (base::FeatureList::IsEnabled(network::features::kSharedZstd)) {
@@ -819,9 +770,6 @@
 
     return response;
   }
-
-  const network::features::CompressionDictionaryTransportBackendVersion
-      version_;
 };
 
 // Tests end to end functionality of "compression dictionary transport" feature
@@ -829,13 +777,10 @@
 // TODO(crbug.com/1413922): Remove this when we fully launch this feature.
 class SharedDictionaryFeatureStateBrowserTest
     : public SharedDictionaryBrowserTestBase,
-      public ::testing::WithParamInterface<std::tuple<
-          FeatureState,
-          network::features::CompressionDictionaryTransportBackendVersion>> {
+      public ::testing::WithParamInterface<FeatureState> {
  public:
-  SharedDictionaryFeatureStateBrowserTest()
-      : SharedDictionaryBrowserTestBase(GetVersion()) {
-    std::vector<base::test::FeatureRefAndParams> enabled_features;
+  SharedDictionaryFeatureStateBrowserTest() {
+    std::vector<base::test::FeatureRef> enabled_features;
     std::vector<base::test::FeatureRef> disabled_features;
     switch (GetFeatureState()) {
       case FeatureState::kDisabled:
@@ -846,42 +791,28 @@
         disabled_features.emplace_back(network::features::kSharedZstd);
         break;
       case FeatureState::kBackendOnly:
-        enabled_features.emplace_back(base::test::FeatureRefAndParams(
-            network::features::kCompressionDictionaryTransportBackend,
-            {{network::features::kCompressionDictionaryTransportBackendVersion
-                  .name,
-              network::features::kCompressionDictionaryTransportBackendVersion
-                  .GetName(GetVersion())}}));
+        enabled_features.emplace_back(
+            network::features::kCompressionDictionaryTransportBackend);
         disabled_features.emplace_back(
             network::features::kCompressionDictionaryTransport);
         disabled_features.emplace_back(network::features::kSharedZstd);
         break;
       case FeatureState::kFullyEnabled:
-        enabled_features.emplace_back(base::test::FeatureRefAndParams(
-            network::features::kCompressionDictionaryTransportBackend,
-            {{network::features::kCompressionDictionaryTransportBackendVersion
-                  .name,
-              network::features::kCompressionDictionaryTransportBackendVersion
-                  .GetName(GetVersion())}}));
-        enabled_features.emplace_back(base::test::FeatureRefAndParams(
-            network::features::kCompressionDictionaryTransport, {}));
+        enabled_features.emplace_back(
+            network::features::kCompressionDictionaryTransportBackend);
+        enabled_features.emplace_back(
+            network::features::kCompressionDictionaryTransport);
         disabled_features.emplace_back(network::features::kSharedZstd);
         break;
       case FeatureState::kFullyEnabledWithZstd:
-        enabled_features.emplace_back(base::test::FeatureRefAndParams(
-            network::features::kCompressionDictionaryTransportBackend,
-            {{network::features::kCompressionDictionaryTransportBackendVersion
-                  .name,
-              network::features::kCompressionDictionaryTransportBackendVersion
-                  .GetName(GetVersion())}}));
-        enabled_features.emplace_back(base::test::FeatureRefAndParams(
-            network::features::kCompressionDictionaryTransport, {}));
-        enabled_features.emplace_back(base::test::FeatureRefAndParams(
-            network::features::kSharedZstd, {}));
+        enabled_features.emplace_back(
+            network::features::kCompressionDictionaryTransportBackend);
+        enabled_features.emplace_back(
+            network::features::kCompressionDictionaryTransport);
+        enabled_features.emplace_back(network::features::kSharedZstd);
         break;
     }
-    scoped_feature_list_.InitWithFeaturesAndParameters(enabled_features,
-                                                       disabled_features);
+    scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
   }
   SharedDictionaryFeatureStateBrowserTest(
       const SharedDictionaryFeatureStateBrowserTest&) = delete;
@@ -907,11 +838,7 @@
   void TearDownOnMainThread() override { url_loader_interceptor_.reset(); }
 
  protected:
-  FeatureState GetFeatureState() const { return std::get<0>(GetParam()); }
-  network::features::CompressionDictionaryTransportBackendVersion GetVersion()
-      const {
-    return std::get<1>(GetParam());
-  }
+  FeatureState GetFeatureState() const { return GetParam(); }
   net::EmbeddedTestServer* https_server() { return https_server_.get(); }
 
   bool FeatureIsFullyEnabled() const {
@@ -1024,25 +951,15 @@
   std::optional<URLLoaderInterceptor> url_loader_interceptor_;
 };
 
-INSTANTIATE_TEST_SUITE_P(
-    All,
-    SharedDictionaryFeatureStateBrowserTest,
-    ::testing::Combine(
-        testing::Values(FeatureState::kDisabled,
-                        FeatureState::kBackendOnly,
-                        FeatureState::kFullyEnabled,
-                        FeatureState::kFullyEnabledWithZstd),
-        testing::Values(network::features::
-                            CompressionDictionaryTransportBackendVersion::kV1,
-                        network::features::
-                            CompressionDictionaryTransportBackendVersion::kV2)),
-    [](const testing::TestParamInfo<std::tuple<
-           FeatureState,
-           network::features::CompressionDictionaryTransportBackendVersion>>&
-           info) {
-      return ToString(std::get<0>(info.param)) + "_" +
-             ToString(std::get<1>(info.param));
-    });
+INSTANTIATE_TEST_SUITE_P(All,
+                         SharedDictionaryFeatureStateBrowserTest,
+                         testing::Values(FeatureState::kDisabled,
+                                         FeatureState::kBackendOnly,
+                                         FeatureState::kFullyEnabled,
+                                         FeatureState::kFullyEnabledWithZstd),
+                         [](const testing::TestParamInfo<FeatureState>& info) {
+                           return ToString(info.param);
+                         });
 
 IN_PROC_BROWSER_TEST_P(SharedDictionaryFeatureStateBrowserTest,
                        LinkRelDictionary) {
@@ -1190,16 +1107,6 @@
       base::BindLambdaForTesting(
           [&](std::vector<network::mojom::SharedDictionaryInfoPtr> result) {
             ASSERT_EQ(1u, result.size());
-            switch (GetVersion()) {
-              case network::features::
-                  CompressionDictionaryTransportBackendVersion::kV1:
-                EXPECT_EQ(GetFeatureState() == FeatureState::kBackendOnly
-                              ? base::Days(30)
-                              : base::Seconds(31536000),
-                          result[0]->expiration);
-                break;
-              case network::features::
-                  CompressionDictionaryTransportBackendVersion::kV2:
                 // The dictionary response was treated as somewhat aged
                 // (response time - request time). So the expiration is a bit
                 // smaller than 3600 seconds which is set in the Cache-Control
@@ -1208,8 +1115,6 @@
                 EXPECT_GT(result[0]->expiration,
                           base::Seconds(3600) -
                               (result[0]->response_time - test_start_time));
-                break;
-            }
             loop.Quit();
           }));
   loop.Run();
@@ -1266,23 +1171,14 @@
 // with fully enabled features.
 class SharedDictionaryBrowserTest
     : public SharedDictionaryBrowserTestBase,
-      public ::testing::WithParamInterface<std::tuple<
-          BrowserType,
-          network::features::CompressionDictionaryTransportBackendVersion>> {
+      public ::testing::WithParamInterface<BrowserType> {
  public:
-  SharedDictionaryBrowserTest()
-      : SharedDictionaryBrowserTestBase(GetVersion()) {
-    scoped_feature_list_.InitWithFeaturesAndParameters(
+  SharedDictionaryBrowserTest() {
+    scoped_feature_list_.InitWithFeatures(
         /*enabled_features=*/
-        {base::test::FeatureRefAndParams(
-             network::features::kCompressionDictionaryTransportBackend,
-             {{network::features::kCompressionDictionaryTransportBackendVersion
-                   .name,
-               network::features::kCompressionDictionaryTransportBackendVersion
-                   .GetName(GetVersion())}}),
-         base::test::FeatureRefAndParams(
-             network::features::kCompressionDictionaryTransport, {}),
-         base::test::FeatureRefAndParams(network::features::kSharedZstd, {})},
+        {network::features::kCompressionDictionaryTransportBackend,
+         network::features::kCompressionDictionaryTransport,
+         network::features::kSharedZstd},
         /*disabled_features=*/{});
   }
   SharedDictionaryBrowserTest(const SharedDictionaryBrowserTest&) = delete;
@@ -1380,11 +1276,7 @@
   }
 
  protected:
-  BrowserType GetBrowserType() const { return std::get<0>(GetParam()); }
-  network::features::CompressionDictionaryTransportBackendVersion GetVersion()
-      const {
-    return std::get<1>(GetParam());
-  }
+  BrowserType GetBrowserType() const { return GetParam(); }
   net::EmbeddedTestServer* cross_origin_server() const {
     return cross_origin_server_.get();
   }
@@ -1498,21 +1390,11 @@
       std::optional<std::string> dict_hash =
           GetAvailableDictionary(request.headers);
       if (dict_hash) {
-        if (*dict_hash == GetExpectedDictionaryHashString()) {
-          if (HasSharedDictionaryAcceptEncoding(request.headers,
-                                                GetVersion())) {
-            switch (GetVersion()) {
-              case network::features::
-                  CompressionDictionaryTransportBackendVersion::kV1:
-                response->AddCustomHeader("content-encoding", "sbr");
-                break;
-              case network::features::
-                  CompressionDictionaryTransportBackendVersion::kV2:
-                response->AddCustomHeader("content-encoding", "br-d");
-                response->AddCustomHeader("content-dictionary",
-                                          kExpectedDictionaryHashBase64);
-                break;
-            }
+        if (*dict_hash == kExpectedDictionaryHashBase64) {
+          if (HasSharedDictionaryAcceptEncoding(request.headers)) {
+            response->AddCustomHeader("content-encoding", "br-d");
+            response->AddCustomHeader("content-dictionary",
+                                      kExpectedDictionaryHashBase64);
             response->set_content(kBrotliCompressedDataString);
           } else {
             response->set_content(kErrorNoSharedDictionaryAcceptEncodingString);
@@ -1536,22 +1418,13 @@
   base::test::ScopedFeatureList scoped_feature_list_;
 };
 
-INSTANTIATE_TEST_SUITE_P(
-    All,
-    SharedDictionaryBrowserTest,
-    ::testing::Combine(
-        testing::Values(BrowserType::kNormal, BrowserType::kOffTheRecord),
-        testing::Values(network::features::
-                            CompressionDictionaryTransportBackendVersion::kV1,
-                        network::features::
-                            CompressionDictionaryTransportBackendVersion::kV2)),
-    [](const testing::TestParamInfo<std::tuple<
-           BrowserType,
-           network::features::CompressionDictionaryTransportBackendVersion>>&
-           info) {
-      return ToString(std::get<0>(info.param)) + "_" +
-             ToString(std::get<1>(info.param));
-    });
+INSTANTIATE_TEST_SUITE_P(All,
+                         SharedDictionaryBrowserTest,
+                         testing::Values(BrowserType::kNormal,
+                                         BrowserType::kOffTheRecord),
+                         [](const testing::TestParamInfo<BrowserType>& info) {
+                           return ToString(info.param);
+                         });
 
 IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest,
                        LinkRelDictionarySecureContext) {
@@ -2063,18 +1936,9 @@
                    FetchTargetDataScript(dictionary_url))
                 .ExtractString());
 
-  switch (GetVersion()) {
-    case network::features::CompressionDictionaryTransportBackendVersion::kV1:
-      // Check that Chrome uses the dictionary while fetching a script.
-      EXPECT_EQ(kCompressedDataResultString,
-                LoadTestScript(GetURL(kTestPath + "?for_script")));
-      break;
-    case network::features::CompressionDictionaryTransportBackendVersion::kV2:
-      // Check that Chrome doesn't use the dictionary while fetching a script.
-      EXPECT_EQ(kUncompressedDataResultString,
-                LoadTestScript(GetURL(kTestPath + "?for_script")));
-      break;
-  }
+  // Check that Chrome doesn't use the dictionary while fetching a script.
+  EXPECT_EQ(kUncompressedDataResultString,
+            LoadTestScript(GetURL(kTestPath + "?for_script")));
 }
 
 IN_PROC_BROWSER_TEST_P(SharedDictionaryBrowserTest, MatchDestScript) {
@@ -2098,24 +1962,12 @@
   EXPECT_EQ(kCompressedDataResultString,
             LoadTestScript(GetURL(kTestPath + "?for_script")));
 
-  switch (GetVersion()) {
-    case network::features::CompressionDictionaryTransportBackendVersion::kV1:
-      // Check that Chrome uses the dictionary while fetching the resource using
-      // Fetch API.
-      EXPECT_EQ(kCompressedDataOriginalString,
-                EvalJs(shell->web_contents()->GetPrimaryMainFrame(),
-                       FetchTargetDataScript(dictionary_url))
-                    .ExtractString());
-      break;
-    case network::features::CompressionDictionaryTransportBackendVersion::kV2:
-      // Check that Chrome doesn't use the dictionary while fetching the
-      // resource using Fetch API.
-      EXPECT_EQ(kUncompressedDataString,
-                EvalJs(shell->web_contents()->GetPrimaryMainFrame(),
-                       FetchTargetDataScript(dictionary_url))
-                    .ExtractString());
-      break;
-  }
+  // Check that Chrome doesn't use the dictionary while fetching the resource
+  // using Fetch API.
+  EXPECT_EQ(kUncompressedDataString,
+            EvalJs(shell->web_contents()->GetPrimaryMainFrame(),
+                   FetchTargetDataScript(dictionary_url))
+                .ExtractString());
 }
 
 IN_PROC_BROWSER_TEST_P(
diff --git a/content/browser/resources/attribution_reporting/attribution_internals.ts b/content/browser/resources/attribution_reporting/attribution_internals.ts
index f253808..cfe5261 100644
--- a/content/browser/resources/attribution_reporting/attribution_internals.ts
+++ b/content/browser/resources/attribution_reporting/attribution_internals.ts
@@ -106,9 +106,12 @@
 }
 
 function dateColumn<T>(header: string, getValue: (row: T) => Date): Column<T> {
-  return new ComparableColumn(
-      header, getValue, compareDefault,
-      (td, v) => td.innerText = v.toLocaleString());
+  return new ComparableColumn(header, getValue, compareDefault, (td, v) => {
+    const time = td.ownerDocument.createElement('time');
+    time.dateTime = v.toISOString();
+    td.innerText = v.toLocaleString();
+    td.append(time);
+  });
 }
 
 const numberClass: string = 'number';
@@ -248,6 +251,7 @@
   constructor() {
     this.input = document.createElement('input');
     this.input.type = 'checkbox';
+    this.input.title = 'Select';
   }
 }
 
@@ -259,6 +263,7 @@
   constructor(private readonly model: TableModel<T>) {
     this.selectAll = document.createElement('input');
     this.selectAll.type = 'checkbox';
+    this.selectAll.title = 'Select All';
     this.selectAll.addEventListener('input', () => {
       const checked = this.selectAll.checked;
       this.model.getRows().forEach((row) => {
diff --git a/content/browser/resources/attribution_reporting/attribution_internals_table.html b/content/browser/resources/attribution_reporting/attribution_internals_table.html
index 6a1b5fdc..b20fc61b 100644
--- a/content/browser/resources/attribution_reporting/attribution_internals_table.html
+++ b/content/browser/resources/attribution_reporting/attribution_internals_table.html
@@ -12,6 +12,12 @@
   table {
     border: 0;
     border-collapse: collapse;
+    /* Per
+     * https://limebrains.com/blog/2021-03-02T13:00-heigh-100-inside-table-td
+     * this forces the header buttons to expand vertically, making them easier
+     * to click on.
+     */
+    height: 1px;
   }
 
   tbody tr {
@@ -24,25 +30,40 @@
     border: 0;
   }
 
-  table td,
-  table th {
-    padding-inline-end: 16px;
-    padding-inline-start: 16px;
+  td, th {
+    padding-inline: 16px;
   }
 
   th[aria-sort] {
-    cursor: pointer;
+    padding: 0;
   }
 
-  th[aria-sort='none']::after {
+  th[aria-sort] button {
+    background: none;
+    border: none;
+    color: inherit;
+    cursor: pointer;
+    font: inherit;
+    height: 100%;
+    outline: none;
+    padding-inline: 16px;
+    height: 100%;
+    width: 100%;
+  }
+
+  th[aria-sort] button:hover {
+    background: rgba(0,0,0,.12);
+  }
+
+  th[aria-sort='none'] button::after {
     content: '⬍';
   }
 
-  th[aria-sort='ascending']::after {
+  th[aria-sort='ascending'] button::after {
     content: '⬆';
   }
 
-  th[aria-sort='descending']::after {
+  th[aria-sort='descending'] button::after {
     content: '⬇';
   }
 
diff --git a/content/browser/resources/attribution_reporting/attribution_internals_table.ts b/content/browser/resources/attribution_reporting/attribution_internals_table.ts
index 088be2faf..9af35e0 100644
--- a/content/browser/resources/attribution_reporting/attribution_internals_table.ts
+++ b/content/browser/resources/attribution_reporting/attribution_internals_table.ts
@@ -23,8 +23,8 @@
     nextDir = 'descending';
   }
 
-  th.title = `Sort by ${th.innerText} ${nextDir}`;
-  th.ariaLabel = th.title;
+  const button = th.querySelector('button')!;
+  button.title = `Sort by ${button.innerText} ${nextDir}`;
 }
 
 /**
@@ -49,12 +49,15 @@
     model.cols.forEach((col, idx) => {
       const th = document.createElement('th');
       th.scope = 'col';
-      col.renderHeader(th);
 
       if (col.compare) {
-        th.setAttribute('role', 'button');
+        const button = document.createElement('button');
+        col.renderHeader(button);
+        th.append(button);
         setSortAttrs(th, idx === model.sortIdx ? this.sortDesc_ : null);
-        th.addEventListener('click', () => this.changeSortHeader_(idx));
+        button.addEventListener('click', () => this.changeSortHeader_(idx));
+      } else {
+        col.renderHeader(th);
       }
 
       tr.append(th);
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
index 1715b38..c5cc1cc9 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -556,8 +556,6 @@
 crbug.com/1421437 [ mac amd-0x67ef angle-metal ] conformance2/extensions/webgl-shader-pixel-local-storage.html [ Failure ]
 crbug.com/1487266 [ amd-0x679e angle-metal monterey passthrough release ] deqp/functional/gles3/texturefiltering/2d_array_combinations_05.html [ Failure ]
 
-crbug.com/1513193 [ amd-0x67ef angle-metal passthrough ventura graphite-enabled ] conformance2/textures/webgl_canvas/tex-3d-* [ RetryOnFailure ]
-
 # NOTE: When removing this line, the suppression for the same test above
 # should have `graphite-disabled` removed.
 crbug.com/1511051 [ mac angle-metal graphite-enabled amd ] conformance/textures/misc/texture-active-bind-2.html [ Failure ]
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
index f59da7b..5042237 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -560,10 +560,6 @@
 
 ## SkiaGraphite ##
 
-crbug.com/1513193 [ mac amd angle-metal graphite-enabled ] conformance/canvas/draw-webgl-to-canvas-test.html [ RetryOnFailure ]
-crbug.com/1513193 [ amd angle-metal graphite-enabled mac no-clang-coverage release ] conformance/canvas/to-data-url-test.html [ RetryOnFailure ]
-crbug.com/1491023 [ mac angle-metal graphite-enabled amd ] conformance/canvas/draw-static-webgl-to-multiple-canvas-test.html [ Failure ]
-
 ## Mac Intel ##
 
 ## Mac Retina NVidia failures / flakes ##
@@ -633,7 +629,6 @@
 crbug.com/1294071 [ android-pie android-shield-android-tv ] conformance/glsl/bugs/vector-matrix-constructor-scalarization.html [ Failure ]
 # Flakily returning RGBA(0,0,0,0) for all pixels
 crbug.com/1357064 [ android android-shield-android-tv no-passthrough ] conformance/rendering/blending.html [ Failure ]
-crbug.com/1516836 [ android android-shield-android-tv no-passthrough renderer-skia-gl ] conformance/extensions/oes-texture-half-float-with-video.html [ RetryOnFailure ]
 
 ## Pixel 4 ##
 
diff --git a/content/test/gpu/gpu_tests/webcodecs_integration_test.py b/content/test/gpu/gpu_tests/webcodecs_integration_test.py
index 4f85d11..e09a721 100644
--- a/content/test/gpu/gpu_tests/webcodecs_integration_test.py
+++ b/content/test/gpu/gpu_tests/webcodecs_integration_test.py
@@ -6,6 +6,7 @@
 import sys
 import json
 import itertools
+import platform
 from typing import Any, List, Set
 import unittest
 
@@ -48,6 +49,20 @@
       }
     return serial_globs
 
+  def _GetSerialTests(self) -> Set[str]:
+    serial_tests = set()
+    # TODO(crbug.com/324293876): Move this check to wherever the host-side
+    # information collection ends up living.
+    # We can't rely on directly checking platform.machine() since it is
+    # possible that we're using emulated Python on arm64 devices.
+    if sys.platform == 'win32' and 'armv8' in platform.processor().lower():
+      serial_tests |= {
+          # Checking whether serialization improves stability for
+          # crbug.com/323824490.
+          'WebCodecs_FrameSizeChange_vp09.00.10.08_hw_decoder',
+      }
+    return serial_tests
+
 # pylint: disable=too-many-branches
 
   @classmethod
@@ -247,9 +262,8 @@
 
     # If we don't call CustomizeBrowserArgs cls.platform is None
     cls.CustomizeBrowserArgs(args)
-    platform = cls.platform
 
-    if cls.CameraCanShowFourColors(platform.GetOSName()):
+    if cls.CameraCanShowFourColors(cls.platform.GetOSName()):
       args.append('--use-file-for-fake-video-capture=' + four_colors_img_path)
       cls.CustomizeBrowserArgs(args)
 
diff --git a/docs/experiments/compression-dictionary-transport.md b/docs/experiments/compression-dictionary-transport.md
index 985231a..4597a340 100644
--- a/docs/experiments/compression-dictionary-transport.md
+++ b/docs/experiments/compression-dictionary-transport.md
@@ -193,34 +193,21 @@
 - [cbrbug.com/1479809](crbug.com/1479809): Can't use large (>8MB) dictionaries
   for Shared Zstd. Fixed in M118.
 
-## Following spec changes
+## Changes in M123
 
-Currently there are two backend implementations, V1 and V2. V2 is under active
-construction to catch up the following spec changes:
+The following changes have been made to Chrome since M123 to keep up with the
+changes in specifications.
 
-- Change Content-Encoding name "br-d" "zstd-d"
-  - Status: Implemented by https://crrev.com/c/5185977.
+- Changed Content-Encoding name "br-d" "zstd-d"
 - Changed match to use URLPattern
-  - Status: Implemented by https://crrev.com/c/5232339.
 - Added support for a server-provided dictionary id
-  - Status: Implemented by https://crrev.com/c/5271881.
 - Stop using "expires" value of "Use-As-Dictionary" header, and use the cache
   expiration time calculated from the response's freshness instead.
-  - Status: Removed by https://crrev.com/c/5227360.
 - Removed support for hash negotiation and force use of sha-256
-  - Status: Removed by https://crrev.com/c/5223985.
 - Added the dictionary hash to the compressed response
-  - Status: Implemented by https://crrev.com/c/5226641.
 - Dictionary hashes changed to sf-binary
-  - Status: Implemented by https://crrev.com/c/5224886.
 - Use "Available-Dictionary" header instead of "Sec-Available-Dictionary"
-  - Status: Implemented by https://crrev.com/c/5224886.
 - Added support for match-dest option
-  - Status: Implemented by https://crrev.com/c/5271881.
-
-You can try the experimental V2 implementation by selecting
-"Enabled experimental V2" in
-[chrome://flags/#enable-compression-dictionary-transport-backend][backend-flag].
 
 ## Demo sites
 
diff --git a/gpu/command_buffer/service/abstract_texture.cc b/gpu/command_buffer/service/abstract_texture.cc
index f25b3bb..5e568bd7 100644
--- a/gpu/command_buffer/service/abstract_texture.cc
+++ b/gpu/command_buffer/service/abstract_texture.cc
@@ -47,18 +47,10 @@
   gl_api_->glTexParameteriFn(texture_passthrough_->target(), pname, param);
 }
 
-void AbstractTexture::SetCleared() {
-  // The passthrough decoder has no notion of 'cleared', so do nothing.
-}
-
 void AbstractTexture::SetCleanupCallback(CleanupCallback cb) {
   cleanup_cb_ = std::move(cb);
 }
 
-void AbstractTexture::NotifyOnContextLost() {
-  NOTIMPLEMENTED();
-}
-
 scoped_refptr<TexturePassthrough>
 AbstractTexture::OnDecoderWillDestroy() {
   // Make sure that destruction_cb_ does nothing when destroyed, since
diff --git a/gpu/command_buffer/service/abstract_texture.h b/gpu/command_buffer/service/abstract_texture.h
index 39c07a8..a90825c 100644
--- a/gpu/command_buffer/service/abstract_texture.h
+++ b/gpu/command_buffer/service/abstract_texture.h
@@ -60,11 +60,6 @@
   // Set a texture parameter.  The GL context must be current.
   void SetParameteri(GLenum pname, GLint param);
 
-  // Marks the texture as cleared, to help prevent sending an uninitialized
-  // texture to the (untrusted) renderer.  One should call this only when one
-  // has actually initialized the texture.
-  void SetCleared();
-
   // Set a callback that will be called when the AbstractTexture is going to
   // drop its reference to the underlying TextureBase.  We can't guarantee that
   // the TextureBase will be destroyed, but it is the last time that we can
@@ -74,9 +69,6 @@
   // has a current context.
   void SetCleanupCallback(CleanupCallback cleanup_callback);
 
-  // Used to notify the AbstractTexture if the context is lost.
-  void NotifyOnContextLost();
-
   unsigned int service_id() const { return GetTextureBase()->service_id(); }
 
   // Called when our decoder is going away, so that we can try to clean up.
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index f75ae9f3..919f15e 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -3261,6 +3261,7 @@
   GLint alpha_bits = 0;
 
   if (offscreen) {
+    // NOTE: `attrib_helper.need_alpha` is defined only on Android.
 #if BUILDFLAG(IS_ANDROID)
     offscreen_buffer_should_have_alpha_ = attrib_helper.need_alpha;
 #else
@@ -5129,15 +5130,6 @@
     }
   }
 
-#if BUILDFLAG(IS_MAC)
-  // Aggressively call glFlush on macOS. This is the only fix that has been
-  // found so far to avoid crashes on Intel drivers. The workaround
-  // isn't needed for WebGL contexts, though.
-  // https://crbug.com/863817
-  if (!feature_info_->IsWebGLContext())
-    context_->FlushForDriverCrashWorkaround();
-#endif
-
   *entries_processed = process_pos;
 
   if (error::IsError(result)) {
@@ -12893,10 +12885,6 @@
   // https://crbug.com/848952 (slow uploads on macOS)
   // https://crbug.com/883276 (buggy clears on Android)
   bool prefer_use_gl_clear = false;
-#if BUILDFLAG(IS_MAC)
-  const uint32_t kMinSizeForGLClear = 4 * 1024;
-  prefer_use_gl_clear = size > kMinSizeForGLClear;
-#endif
   if (must_use_gl_clear || prefer_use_gl_clear) {
     if (ClearLevelUsingGL(texture, channels, target, level, xoffset, yoffset,
                           width, height)) {
@@ -16773,18 +16761,6 @@
       source_type, dest_binding_target, dest_level, dest_internal_format,
       unpack_flip_y == GL_TRUE, unpack_premultiply_alpha == GL_TRUE,
       unpack_unmultiply_alpha == GL_TRUE);
-#if BUILDFLAG(IS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
-  // glDrawArrays is faster than glCopyTexSubImage2D on IA Mesa driver,
-  // although opposite in Android.
-  // TODO(dshwang): After Mesa fixes this issue, remove this hack.
-  // https://bugs.freedesktop.org/show_bug.cgi?id=98478,
-  // https://crbug.com/535198.
-  if (Texture::ColorRenderable(GetFeatureInfo(), dest_internal_format,
-                               dest_texture->IsImmutable()) &&
-      method == CopyTextureMethod::DIRECT_COPY) {
-    method = CopyTextureMethod::DIRECT_DRAW;
-  }
-#endif
 
   // Use DRAW instead of COPY if the workaround is enabled.
   if (method == CopyTextureMethod::DIRECT_COPY &&
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing.h b/gpu/command_buffer/service/shared_image/iosurface_image_backing.h
index 8cb0b14..9c607a5 100644
--- a/gpu/command_buffer/service/shared_image/iosurface_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing.h
@@ -11,6 +11,7 @@
 #include "build/build_config.h"
 #include "gpu/command_buffer/service/shared_image/shared_image_backing.h"
 #include "gpu/command_buffer/service/texture_manager.h"
+#include "gpu/config/gpu_preferences.h"
 #include "gpu/gpu_gles2_export.h"
 #include "ui/gl/buildflags.h"
 #include "ui/gl/gl_context.h"
@@ -117,7 +118,7 @@
       GLenum gl_target,
       bool framebuffer_attachment_angle,
       bool is_cleared,
-      bool retain_gl_texture,
+      GrContextType gr_context_type,
       std::optional<gfx::BufferUsage> buffer_usage = std::nullopt);
   IOSurfaceImageBacking(const IOSurfaceImageBacking& other) = delete;
   IOSurfaceImageBacking& operator=(const IOSurfaceImageBacking& other) = delete;
@@ -247,7 +248,10 @@
 
   // This map tracks all IOSurfaceBackingEGLState instances that exist.
   std::map<EGLDisplay, IOSurfaceBackingEGLState*> egl_state_map_;
-  scoped_refptr<IOSurfaceBackingEGLState> egl_state_for_legacy_mailbox_;
+
+  // If Skia is using GL, this object creates a GL texture at construction time
+  // for the Skia GL context and reuses it (for that context) for its lifetime.
+  scoped_refptr<IOSurfaceBackingEGLState> egl_state_for_skia_gl_context_;
 
   std::unique_ptr<gl::GLFence> last_write_gl_fence_;
 
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm b/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm
index c5706519..1a4a6595 100644
--- a/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm
+++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm
@@ -877,7 +877,7 @@
     GLenum gl_target,
     bool framebuffer_attachment_angle,
     bool is_cleared,
-    bool retain_gl_texture,
+    GrContextType gr_context_type,
     std::optional<gfx::BufferUsage> buffer_usage)
     : SharedImageBacking(mailbox,
                          format,
@@ -910,17 +910,18 @@
     return;
   }
 
-  // NOTE: Mac currently retains GLTexture and reuses it. Not sure if this is
-  // best approach as it can lead to issues with context losses.
-  if (retain_gl_texture) {
-    egl_state_for_legacy_mailbox_ = RetainGLTexture();
+  // NOTE: Mac currently retains GLTexture and reuses it. This might lead to
+  // issues with context losses, but is also beneficial to performance at
+  // least on perf benchmarks.
+  if (gr_context_type == GrContextType::kGL) {
+    egl_state_for_skia_gl_context_ = RetainGLTexture();
   }
 }
 
 IOSurfaceImageBacking::~IOSurfaceImageBacking() {
-  if (egl_state_for_legacy_mailbox_) {
-    egl_state_for_legacy_mailbox_->WillRelease(have_context());
-    egl_state_for_legacy_mailbox_ = nullptr;
+  if (egl_state_for_skia_gl_context_) {
+    egl_state_for_skia_gl_context_->WillRelease(have_context());
+    egl_state_for_skia_gl_context_ = nullptr;
   }
   DCHECK(egl_state_map_.empty());
 }
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.mm b/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.mm
index bd012277..6fefbec 100644
--- a/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.mm
+++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.mm
@@ -418,13 +418,12 @@
   const bool framebuffer_attachment_angle =
       for_framebuffer_attachment && angle_texture_usage_;
   const GLenum texture_target = gpu::GetPlatformSpecificTextureTarget();
-  const bool retain_gl_texture = gr_context_type_ == GrContextType::kGL;
 
   auto backing = std::make_unique<IOSurfaceImageBacking>(
       io_surface, io_surface_plane, io_surface_id, mailbox, format, size,
       color_space, surface_origin, alpha_type, usage, std::move(debug_label),
       texture_target, framebuffer_attachment_angle, is_cleared,
-      retain_gl_texture);
+      gr_context_type_);
   if (!pixel_data.empty()) {
     gl::ScopedProgressReporter scoped_progress_reporter(progress_reporter_);
     backing->InitializePixels(pixel_data);
@@ -500,7 +499,6 @@
       UsageWillResultInGLWrite(usage, gr_context_type_);
   const bool framebuffer_attachment_angle =
       for_framebuffer_attachment && angle_texture_usage_;
-  const bool retain_gl_texture = gr_context_type_ == GrContextType::kGL;
 
   if (is_plane_format) {
     const gfx::Size plane_size = gpu::GetPlaneSize(buffer_plane, size);
@@ -510,14 +508,14 @@
         io_surface, io_surface_plane, io_surface_id, mailbox, plane_format,
         plane_size, color_space, surface_origin, alpha_type, usage,
         std::move(debug_label), target, framebuffer_attachment_angle,
-        /*is_cleared=*/true, retain_gl_texture, std::move(buffer_usage));
+        /*is_cleared=*/true, gr_context_type_, std::move(buffer_usage));
   }
 
   return std::make_unique<IOSurfaceImageBacking>(
       io_surface, /*io_surface_plane=*/0, io_surface_id, mailbox, format, size,
       color_space, surface_origin, alpha_type, usage, std::move(debug_label),
       target, framebuffer_attachment_angle, /*is_cleared=*/true,
-      retain_gl_texture, std::move(buffer_usage));
+      gr_context_type_, std::move(buffer_usage));
 }
 
 }  // namespace gpu
diff --git a/internal b/internal
index 7dad41b4..8ca742c 160000
--- a/internal
+++ b/internal
@@ -1 +1 @@
-Subproject commit 7dad41b491ac6ef10b238af85d0cfe5a91124393
+Subproject commit 8ca742cefe79b6c919d7f9a13a41e050a5ef62d1
diff --git a/ios/chrome/browser/autocomplete/model/autocomplete_provider_client_impl.mm b/ios/chrome/browser/autocomplete/model/autocomplete_provider_client_impl.mm
index 7894826..3d3b5bb 100644
--- a/ios/chrome/browser/autocomplete/model/autocomplete_provider_client_impl.mm
+++ b/ios/chrome/browser/autocomplete/model/autocomplete_provider_client_impl.mm
@@ -284,7 +284,7 @@
 bool AutocompleteProviderClientImpl::IsSyncActive() const {
   syncer::SyncService* sync =
       SyncServiceFactory::GetForBrowserState(browser_state_);
-  // TODO(crbug.com/1462552): Remove usage of IsSyncFeatureActive() after kSync
+  // TODO(crbug.com/40066949): Remove usage of IsSyncFeatureActive() after kSync
   // users are migrated to kSignin in phase 3. See ConsentLevel::kSync
   // documentation for details.
   return sync && sync->IsSyncFeatureActive();
diff --git a/ios/chrome/browser/browsing_data/model/browsing_data_counter_wrapper.cc b/ios/chrome/browser/browsing_data/model/browsing_data_counter_wrapper.cc
index ddcd0d2..59f5b52 100644
--- a/ios/chrome/browser/browsing_data/model/browsing_data_counter_wrapper.cc
+++ b/ios/chrome/browser/browsing_data/model/browsing_data_counter_wrapper.cc
@@ -52,6 +52,7 @@
             browser_state, ServiceAccessType::EXPLICIT_ACCESS),
         IOSChromeAccountPasswordStoreFactory::GetForBrowserState(
             browser_state, ServiceAccessType::EXPLICIT_ACCESS),
+        browser_state->GetPrefs(),
         SyncServiceFactory::GetForBrowserState(browser_state));
   }
 
diff --git a/ios/chrome/browser/device_sharing/model/device_sharing_browser_agent_unittest.mm b/ios/chrome/browser/device_sharing/model/device_sharing_browser_agent_unittest.mm
index acbbf62..73b1c40 100644
--- a/ios/chrome/browser/device_sharing/model/device_sharing_browser_agent_unittest.mm
+++ b/ios/chrome/browser/device_sharing/model/device_sharing_browser_agent_unittest.mm
@@ -49,19 +49,15 @@
     return [sharing_manager->handoff_manager_ userActivityWebpageURL];
   }
 
-  web::FakeWebState* AppendNewWebState(Browser* browser, const GURL url) {
-    return AppendNewWebState(browser, url, WebStateList::INSERT_ACTIVATE);
-  }
-
   web::FakeWebState* AppendNewWebState(Browser* browser,
                                        const GURL url,
-                                       WebStateList::InsertionFlags flags) {
+                                       bool activate = true) {
     auto fake_web_state = std::make_unique<web::FakeWebState>();
     fake_web_state->SetCurrentURL(url);
     web::FakeWebState* inserted_web_state = fake_web_state.get();
-    browser->GetWebStateList()->InsertWebState(WebStateList::kInvalidIndex,
-                                               std::move(fake_web_state), flags,
-                                               WebStateOpener());
+    browser->GetWebStateList()->InsertWebState(
+        std::move(fake_web_state),
+        WebStateList::InsertionParams::Automatic().Activate(activate));
     return inserted_web_state;
   }
 
@@ -106,7 +102,7 @@
   AppendNewWebState(browser_.get(), url_1_);
   EXPECT_NSEQ(ActiveHandoffUrl(), net::NSURLWithGURL(url_1_));
   // Appending a web state without activating will not change the active URL.
-  AppendNewWebState(browser_.get(), url_2_, WebStateList::INSERT_NO_FLAGS);
+  AppendNewWebState(browser_.get(), url_2_, /*activate=*/false);
   EXPECT_NSEQ(ActiveHandoffUrl(), net::NSURLWithGURL(url_1_));
 }
 
@@ -126,7 +122,7 @@
 TEST_F(DeviceSharingBrowserAgentTest, NavigateInactiveInBrowser) {
   DeviceSharingBrowserAgent::CreateForBrowser(browser_.get());
   web::FakeWebState* web_state =
-      AppendNewWebState(browser_.get(), url_1_, WebStateList::INSERT_NO_FLAGS);
+      AppendNewWebState(browser_.get(), url_1_, /*activate=*/false);
   AppendNewWebState(browser_.get(), url_2_);
 
   DeviceSharingBrowserAgent::FromBrowser(browser_.get())
diff --git a/ios/chrome/browser/iph_for_new_chrome_user/model/tab_based_iph_browser_agent.mm b/ios/chrome/browser/iph_for_new_chrome_user/model/tab_based_iph_browser_agent.mm
index 4c04c77..267d25c 100644
--- a/ios/chrome/browser/iph_for_new_chrome_user/model/tab_based_iph_browser_agent.mm
+++ b/ios/chrome/browser/iph_for_new_chrome_user/model/tab_based_iph_browser_agent.mm
@@ -98,7 +98,7 @@
   // here. In case the user navigates away when `multi_gesture_refresh_` is
   // called, it would be handled by `DidStopLoading`.
   if (!multi_gesture_refresh_) {
-    [HelpHandler() hideAllGestureInProductHelpViews];
+    [HelpHandler() handleTapOutsideOfVisibleGestureInProductHelp];
   }
 }
 
@@ -141,7 +141,10 @@
 void TabBasedIPHBrowserAgent::ResetFeatureStatesAndRemoveIPHViews() {
   multi_gesture_refresh_ = false;
   back_forward_button_tapped_ = false;
-  [HelpHandler() hideAllGestureInProductHelpViews];
+  // Invocation of this method is usually caused by manually triggered changes
+  // to the web state, which is a result of the user tapping the location bar or
+  // toolbar, both outside of the gestural IPH.
+  [HelpHandler() handleTapOutsideOfVisibleGestureInProductHelp];
 }
 
 id<HelpCommands> TabBasedIPHBrowserAgent::HelpHandler() {
diff --git a/ios/chrome/browser/overlays/model/overlay_presenter_impl_unittest.mm b/ios/chrome/browser/overlays/model/overlay_presenter_impl_unittest.mm
index 5991d0c..88c8789 100644
--- a/ios/chrome/browser/overlays/model/overlay_presenter_impl_unittest.mm
+++ b/ios/chrome/browser/overlays/model/overlay_presenter_impl_unittest.mm
@@ -116,8 +116,8 @@
 TEST_F(OverlayPresenterImplTest, PresentAfterSettingPresentationContext) {
   // Add a WebState to the list and add a request to that WebState's queue.
   web_state_list()->InsertWebState(
-      /*index=*/0, std::make_unique<web::FakeWebState>(),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::make_unique<web::FakeWebState>(),
+      WebStateList::InsertionParams::Automatic().Activate());
   OverlayRequest* request = AddRequest(active_web_state());
   ASSERT_EQ(FakeOverlayPresentationContext::PresentationState::kNotPresented,
             presentation_context().GetPresentationState(request));
@@ -135,8 +135,8 @@
   // Add a WebState to the list and add a request to that WebState's queue.
   presenter().SetPresentationContext(&presentation_context());
   web_state_list()->InsertWebState(
-      /*index=*/0, std::make_unique<web::FakeWebState>(),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::make_unique<web::FakeWebState>(),
+      WebStateList::InsertionParams::Automatic().Activate());
   OverlayRequest* request = AddRequest(active_web_state());
   // Verify that the requested overlay has been presented.
   EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
@@ -151,8 +151,8 @@
   // Add a WebState to the list and add a request to that WebState's queue.
   presenter().SetPresentationContext(&presentation_context());
   web_state_list()->InsertWebState(
-      /*index=*/0, std::make_unique<web::FakeWebState>(),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::make_unique<web::FakeWebState>(),
+      WebStateList::InsertionParams::Automatic().Activate());
   OverlayRequest* request = AddRequest(active_web_state());
   // Verify that the requested overlay has been presented.
   EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
@@ -190,8 +190,8 @@
       OverlayPresentationContext::UIPresentationCapabilities::kNone);
   presenter().SetPresentationContext(&presentation_context());
   web_state_list()->InsertWebState(
-      /*index=*/0, std::make_unique<web::FakeWebState>(),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::make_unique<web::FakeWebState>(),
+      WebStateList::InsertionParams::Automatic().Activate());
   OverlayRequest* request = AddRequest(active_web_state());
   ASSERT_EQ(FakeOverlayPresentationContext::PresentationState::kNotPresented,
             presentation_context().GetPresentationState(request));
@@ -210,8 +210,8 @@
   // Add a WebState to the list and add a request to that WebState's queue.
   presenter().SetPresentationContext(&presentation_context());
   web_state_list()->InsertWebState(
-      /*index=*/0, std::make_unique<web::FakeWebState>(),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::make_unique<web::FakeWebState>(),
+      WebStateList::InsertionParams::Automatic().Activate());
   OverlayRequest* request = AddRequest(active_web_state());
   ASSERT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
             presentation_context().GetPresentationState(request));
@@ -231,8 +231,8 @@
   // Add a WebState to the list and add a request to that WebState's queue.
   presenter().SetPresentationContext(&presentation_context());
   web_state_list()->InsertWebState(
-      /*index=*/0, std::make_unique<web::FakeWebState>(),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::make_unique<web::FakeWebState>(),
+      WebStateList::InsertionParams::Automatic().Activate());
   web::WebState* web_state = active_web_state();
   OverlayRequest* request = AddRequest(web_state);
   OverlayRequestQueueImpl* queue = GetQueueForWebState(web_state);
@@ -271,8 +271,8 @@
   // Add a WebState to the list and activate it.
   presenter().SetPresentationContext(&presentation_context());
   web_state_list()->InsertWebState(
-      /*index=*/0, std::make_unique<web::FakeWebState>(),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::make_unique<web::FakeWebState>(),
+      WebStateList::InsertionParams::Automatic().Activate());
 
   // Create a new WebState with a queued request and add it as the new active
   // WebState.
@@ -280,8 +280,8 @@
   web::WebState* second_web_state = passed_web_state.get();
   OverlayRequest* request = AddRequest(second_web_state);
   web_state_list()->InsertWebState(
-      /*index=*/1, std::move(passed_web_state),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::move(passed_web_state),
+      WebStateList::InsertionParams::Automatic().Activate());
 
   // Verify that the new active WebState's overlay is being presented.
   EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
@@ -294,8 +294,8 @@
   // Add a WebState to the list and add a request to that WebState's queue.
   presenter().SetPresentationContext(&presentation_context());
   web_state_list()->InsertWebState(
-      /*index=*/0, std::make_unique<web::FakeWebState>(),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::make_unique<web::FakeWebState>(),
+      WebStateList::InsertionParams::Automatic().Activate());
   web::WebState* first_web_state = active_web_state();
   OverlayRequest* first_request = AddRequest(first_web_state);
   ASSERT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
@@ -309,8 +309,8 @@
   OverlayRequest* second_request = AddRequest(second_web_state);
   EXPECT_CALL(observer(), DidHideOverlay(&presenter(), first_request));
   web_state_list()->InsertWebState(
-      /*index=*/1, std::move(passed_web_state),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::move(passed_web_state),
+      WebStateList::InsertionParams::Automatic().Activate());
 
   // Verify that the previously shown overlay is hidden and that the overlay for
   // the new active WebState is presented.
@@ -338,8 +338,8 @@
   // Add a WebState to the list and add a request to that WebState's queue.
   presenter().SetPresentationContext(&presentation_context());
   web_state_list()->InsertWebState(
-      /*index=*/0, std::make_unique<web::FakeWebState>(),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::make_unique<web::FakeWebState>(),
+      WebStateList::InsertionParams::Automatic().Activate());
   web::WebState* first_web_state = active_web_state();
   OverlayRequest* first_request = AddRequest(first_web_state);
   ASSERT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
@@ -367,8 +367,8 @@
   // Add a WebState to the list and add a request to that WebState's queue.
   presenter().SetPresentationContext(&presentation_context());
   web_state_list()->InsertWebState(
-      /*index=*/0, std::make_unique<web::FakeWebState>(),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::make_unique<web::FakeWebState>(),
+      WebStateList::InsertionParams::Automatic().Activate());
   web::WebState* web_state = active_web_state();
   OverlayRequest* request = AddRequest(web_state);
   EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
@@ -388,8 +388,8 @@
   // Add a WebState to the list and add a request to that WebState's queue.
   presenter().SetPresentationContext(&presentation_context());
   web_state_list()->InsertWebState(
-      /*index=*/0, std::make_unique<web::FakeWebState>(),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::make_unique<web::FakeWebState>(),
+      WebStateList::InsertionParams::Automatic().Activate());
   web::WebState* web_state = active_web_state();
   OverlayRequest* request = AddRequest(web_state);
   EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
@@ -415,8 +415,8 @@
   // Add a WebState to the list and add a request to that WebState's queue.
   presenter().SetPresentationContext(&presentation_context());
   web_state_list()->InsertWebState(
-      /*index=*/0, std::make_unique<web::FakeWebState>(),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::make_unique<web::FakeWebState>(),
+      WebStateList::InsertionParams::Automatic().Activate());
   web::WebState* web_state = active_web_state();
   OverlayRequest* request = AddRequest(web_state);
   EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
@@ -439,8 +439,8 @@
   // Add a WebState to the list and add a request to that WebState's queue.
   presenter().SetPresentationContext(&presentation_context());
   web_state_list()->InsertWebState(
-      /*index=*/0, std::make_unique<web::FakeWebState>(),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::make_unique<web::FakeWebState>(),
+      WebStateList::InsertionParams::Automatic().Activate());
   web::WebState* web_state = active_web_state();
   OverlayRequest* request = AddRequest(web_state);
   EXPECT_EQ(FakeOverlayPresentationContext::PresentationState::kPresented,
@@ -460,8 +460,8 @@
   // Add a WebState to the list and add two request to that WebState's queue.
   presenter().SetPresentationContext(&presentation_context());
   web_state_list()->InsertWebState(
-      /*index=*/0, std::make_unique<web::FakeWebState>(),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::make_unique<web::FakeWebState>(),
+      WebStateList::InsertionParams::Automatic().Activate());
   web::WebState* web_state = active_web_state();
   OverlayRequestQueueImpl* queue = GetQueueForWebState(web_state);
   OverlayRequest* first_request = AddRequest(web_state);
@@ -493,8 +493,8 @@
   // Add a WebState to the list and a request to that WebState's queue.
   presenter().SetPresentationContext(&presentation_context());
   web_state_list()->InsertWebState(
-      0, std::make_unique<web::FakeWebState>(),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::make_unique<web::FakeWebState>(),
+      WebStateList::InsertionParams::Automatic().Activate());
   OverlayRequestQueueImpl* queue = GetQueueForWebState(active_web_state());
   OverlayRequest* active_request = AddRequest(active_web_state());
   OverlayRequest* queued_request =
@@ -521,16 +521,16 @@
   // Insert an activated WebState to the list and add a request.
   presenter().SetPresentationContext(&presentation_context());
   web_state_list()->InsertWebState(
-      0, std::make_unique<web::FakeWebState>(),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::make_unique<web::FakeWebState>(),
+      WebStateList::InsertionParams::Automatic().Activate());
   OverlayRequest* request = AddRequest(active_web_state());
 
   // Disable dismissal callbacks in the fake context and activate a new
   // WebState.
   presentation_context().SetDismissalCallbacksEnabled(false);
   web_state_list()->InsertWebState(
-      1, std::make_unique<web::FakeWebState>(),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::make_unique<web::FakeWebState>(),
+      WebStateList::InsertionParams::Automatic().Activate());
 
   // Reset the presentation capabilities to kNone.  Since the context can no
   // longer support presenting `request`, it will be hidden.
@@ -553,8 +553,8 @@
   // Insert an activated WebState to the list.
   presenter().SetPresentationContext(&presentation_context());
   web_state_list()->InsertWebState(
-      0, std::make_unique<web::FakeWebState>(),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::make_unique<web::FakeWebState>(),
+      WebStateList::InsertionParams::Automatic().Activate());
   OverlayRequestQueueImpl* queue = GetQueueForWebState(active_web_state());
 
   // Add a request with a fake cancel handler.
diff --git a/ios/chrome/browser/passwords/model/password_controller_js_unittest.mm b/ios/chrome/browser/passwords/model/password_controller_js_unittest.mm
index 337058f..1ceeff3 100644
--- a/ios/chrome/browser/passwords/model/password_controller_js_unittest.mm
+++ b/ios/chrome/browser/passwords/model/password_controller_js_unittest.mm
@@ -1330,8 +1330,7 @@
   auto expected_form = base::Value::Dict()
                            .Set("name", "")
                            .Set("origin", BaseUrl())
-                           .Set("action", "")
-                           .Set("is_form_tag", false);
+                           .Set("action", "");
   base::Value::Dict expected_username_field =
       ParsedField(/*renderer_id=*/"1", /*contole_type=*/"text",
                   /*identifier=*/"gChrome~field~~INPUT~0", /*value=*/"",
diff --git a/ios/chrome/browser/search_engine_choice/model/search_engine_choice_util.mm b/ios/chrome/browser/search_engine_choice/model/search_engine_choice_util.mm
index 33d0cad..db838153 100644
--- a/ios/chrome/browser/search_engine_choice/model/search_engine_choice_util.mm
+++ b/ios/chrome/browser/search_engine_choice/model/search_engine_choice_util.mm
@@ -42,16 +42,19 @@
     // This build is not eligible for the choice screen.
     return false;
   }
-
+  ChromeBrowserState* original_browser_state =
+      browser_state.GetOriginalChromeBrowserState();
   // Getting data needed to check condition.
   search_engines::SearchEngineChoiceService* search_engine_choice_service =
-      ios::SearchEngineChoiceServiceFactory::GetForBrowserState(&browser_state);
+      ios::SearchEngineChoiceServiceFactory::GetForBrowserState(
+          original_browser_state);
   BrowserStatePolicyConnector* policy_connector =
-      browser_state.GetPolicyConnector();
+      original_browser_state->GetPolicyConnector();
   const policy::PolicyService& policy_service =
       *policy_connector->GetPolicyService();
   TemplateURLService* template_url_service =
-      ios::TemplateURLServiceFactory::GetForBrowserState(&browser_state);
+      ios::TemplateURLServiceFactory::GetForBrowserState(
+          original_browser_state);
 
   // Checking whether the user is eligible for the screen.
   auto condition =
diff --git a/ios/chrome/browser/search_engine_choice/model/search_engine_choice_util_unittest.mm b/ios/chrome/browser/search_engine_choice/model/search_engine_choice_util_unittest.mm
index bfc46139..752ccb0 100644
--- a/ios/chrome/browser/search_engine_choice/model/search_engine_choice_util_unittest.mm
+++ b/ios/chrome/browser/search_engine_choice/model/search_engine_choice_util_unittest.mm
@@ -22,7 +22,6 @@
 #import "ios/chrome/browser/search_engines/model/template_url_service_factory.h"
 #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h"
 #import "ios/chrome/browser/signin/model/authentication_service_factory.h"
-#import "ios/chrome/browser/ui/search_engine_choice/search_engine_choice_constants.h"
 #import "ios/web/public/test/web_task_environment.h"
 #import "testing/gtest/include/gtest/gtest.h"
 #import "testing/platform_test.h"
@@ -58,7 +57,7 @@
     template_url_service_ = ios::TemplateURLServiceFactory::GetForBrowserState(
         browser_state_.get());
     base::CommandLine::ForCurrentProcess()->AppendSwitch(
-        kSearchEngineForceEnabled);
+        switches::kForceSearchEngineChoiceScreen);
   }
 
   TestChromeBrowserState& browser_state() { return *browser_state_; }
diff --git a/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent_unittest.mm b/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent_unittest.mm
index 9e3f865..1d4106f8 100644
--- a/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent_unittest.mm
+++ b/ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent_unittest.mm
@@ -109,14 +109,9 @@
             ->GetSendTabToSelfModel());
   }
 
-  web::FakeWebState* AppendNewWebState(const GURL& url) {
-    return AppendNewWebState(url, WebStateList::INSERT_ACTIVATE,
-                             /*is_visible=*/true);
-  }
-
   web::FakeWebState* AppendNewWebState(const GURL& url,
-                                       WebStateList::InsertionFlags flags,
-                                       bool is_visible) {
+                                       bool activate = true,
+                                       bool is_visible = true) {
     auto fake_web_state = std::make_unique<web::FakeWebState>();
     fake_web_state->SetCurrentURL(url);
     // Create a navigation item to match the URL and give it a title.
@@ -133,9 +128,9 @@
     // Capture a pointer to the created web state to return.
     web::FakeWebState* inserted_web_state = fake_web_state.get();
     InfoBarManagerImpl::CreateForWebState(inserted_web_state);
-    browser_->GetWebStateList()->InsertWebState(WebStateList::kInvalidIndex,
-                                                std::move(fake_web_state),
-                                                flags, WebStateOpener());
+    browser_->GetWebStateList()->InsertWebState(
+        std::move(fake_web_state),
+        WebStateList::InsertionParams::Automatic().Activate(activate));
 
     if (is_visible) {
       inserted_web_state->WasShown();
@@ -191,7 +186,7 @@
   // Add a web state, not visible.
   web::WebState* web_state =
       AppendNewWebState(GURL("http://www.blank.com"),
-                        WebStateList::INSERT_ACTIVATE, /*visible=*/false);
+                        /*activate=*/true, /*is_visible=*/false);
   InfoBarManagerImpl* infobar_manager =
       InfoBarManagerImpl::FromWebState(web_state);
   EXPECT_EQ(0UL, infobar_manager->infobars().size());
@@ -216,7 +211,7 @@
   // Add a web state, not visible or active.
   web::WebState* web_state =
       AppendNewWebState(GURL("http://www.blank.com"),
-                        WebStateList::INSERT_NO_FLAGS, /*visible=*/false);
+                        /*activate=*/false, /*is_visible=*/false);
   InfoBarManagerImpl* infobar_manager =
       InfoBarManagerImpl::FromWebState(web_state);
   EXPECT_EQ(0UL, infobar_manager->infobars().size());
@@ -244,7 +239,7 @@
   // Add a web state, active but not visible.
   web::WebState* web_state =
       AppendNewWebState(GURL("http://www.blank.com"),
-                        WebStateList::INSERT_ACTIVATE, /*visible=*/false);
+                        /*activate=*/true, /*is_visible=*/false);
   InfoBarManagerImpl* infobar_manager =
       InfoBarManagerImpl::FromWebState(web_state);
   EXPECT_EQ(0UL, infobar_manager->infobars().size());
diff --git a/ios/chrome/browser/sessions/session_restoration_browser_agent_unittest.mm b/ios/chrome/browser/sessions/session_restoration_browser_agent_unittest.mm
index 61781cf..657e875 100644
--- a/ios/chrome/browser/sessions/session_restoration_browser_agent_unittest.mm
+++ b/ios/chrome/browser/sessions/session_restoration_browser_agent_unittest.mm
@@ -193,15 +193,12 @@
                                    bool background) {
     std::unique_ptr<web::WebState> web_state = CreateWebState();
 
-    int insertion_flags = WebStateList::INSERT_FORCE_INDEX;
-    if (!background) {
-      insertion_flags |= WebStateList::INSERT_ACTIVATE;
-    }
-    if (pinned) {
-      insertion_flags |= WebStateList::INSERT_PINNED;
-    }
-    browser_->GetWebStateList()->InsertWebState(
-        index, std::move(web_state), insertion_flags, WebStateOpener(parent));
+    const WebStateList::InsertionParams params =
+        WebStateList::InsertionParams::AtIndex(index)
+            .Pinned(pinned)
+            .Activate(!background)
+            .WithOpener(WebStateOpener(parent));
+    browser_->GetWebStateList()->InsertWebState(std::move(web_state), params);
     return browser_->GetWebStateList()->GetWebStateAt(index);
   }
 
diff --git a/ios/chrome/browser/sessions/session_restoration_service_impl_unittest.mm b/ios/chrome/browser/sessions/session_restoration_service_impl_unittest.mm
index a5d87ac..f50e272 100644
--- a/ios/chrome/browser/sessions/session_restoration_service_impl_unittest.mm
+++ b/ios/chrome/browser/sessions/session_restoration_service_impl_unittest.mm
@@ -1028,8 +1028,8 @@
   // Insert the WebState into the Browser's WebStateList and then wait for
   // the session to be saved to storage.
   browser.GetWebStateList()->InsertWebState(
-      WebStateList::kInvalidIndex, std::move(web_state),
-      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+      std::move(web_state),
+      WebStateList::InsertionParams::Automatic().Activate());
   WaitForSessionSaveComplete();
 
   // Check that the data for the WebState has been saved to disk.
diff --git a/ios/chrome/browser/sessions/web_state_list_serialization.mm b/ios/chrome/browser/sessions/web_state_list_serialization.mm
index 4a6699065..6a8ad7a1 100644
--- a/ios/chrome/browser/sessions/web_state_list_serialization.mm
+++ b/ios/chrome/browser/sessions/web_state_list_serialization.mm
@@ -276,14 +276,6 @@
       item_storage.metadata());
 }
 
-// Returns the flags used to insert a WebState at `index`, possibly marking
-// it as `pinned` or `active`.
-int WebStateInsertionFlags(int index, bool pinned, bool active) {
-  return WebStateList::INSERT_FORCE_INDEX |
-         (pinned ? WebStateList::INSERT_PINNED : 0) |
-         (active ? WebStateList::INSERT_ACTIVATE : 0);
-}
-
 // Helper function that deserialize into a WebStateList using a deserializer.
 // Used by the two implementation of `DeserializeWebStateList(...)`.
 std::vector<web::WebState*> DeserializeWebStateListInternal(
@@ -334,11 +326,10 @@
       max_identifier = std::max(max_identifier, web_state_id.identifier());
     }
 
-    const int insertion_flags = WebStateInsertionFlags(
-        index, index < restored_pinned_tabs_count, index == active_index);
-
     const int inserted_index = web_state_list->InsertWebState(
-        index, std::move(web_state), insertion_flags, WebStateOpener{});
+        std::move(web_state), WebStateList::InsertionParams::AtIndex(index)
+                                  .Pinned(index < restored_pinned_tabs_count)
+                                  .Activate(index == active_index));
 
     DCHECK_EQ(inserted_index, index);
   }
diff --git a/ios/chrome/browser/sessions/web_state_list_serialization_unittest.mm b/ios/chrome/browser/sessions/web_state_list_serialization_unittest.mm
index b91680d..f852ddc 100644
--- a/ios/chrome/browser/sessions/web_state_list_serialization_unittest.mm
+++ b/ios/chrome/browser/sessions/web_state_list_serialization_unittest.mm
@@ -201,19 +201,19 @@
   FakeWebStateListDelegate delegate;
   WebStateList web_state_list(&delegate);
   web_state_list.InsertWebState(
-      0, CreateWebState(),
-      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_PINNED,
-      WebStateOpener());
+      CreateWebState(), WebStateList::InsertionParams::AtIndex(0).Pinned());
   web_state_list.InsertWebState(
-      1, CreateWebState(),
-      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_ACTIVATE,
-      WebStateOpener(web_state_list.GetWebStateAt(0), 3));
+      CreateWebState(),
+      WebStateList::InsertionParams::AtIndex(1).Activate().WithOpener(
+          WebStateOpener(web_state_list.GetWebStateAt(0), 3)));
   web_state_list.InsertWebState(
-      2, CreateWebState(), WebStateList::INSERT_FORCE_INDEX,
-      WebStateOpener(web_state_list.GetWebStateAt(0), 2));
+      CreateWebState(),
+      WebStateList::InsertionParams::AtIndex(2).WithOpener(
+          WebStateOpener(web_state_list.GetWebStateAt(0), 2)));
   web_state_list.InsertWebState(
-      3, CreateWebState(), WebStateList::INSERT_FORCE_INDEX,
-      WebStateOpener(web_state_list.GetWebStateAt(1), 1));
+      CreateWebState(),
+      WebStateList::InsertionParams::AtIndex(3).WithOpener(
+          WebStateOpener(web_state_list.GetWebStateAt(1), 1)));
 
   // Serialize the session and check the serialized data is correct.
   SessionWindowIOS* session_window = SerializeWebStateList(&web_state_list);
@@ -268,26 +268,25 @@
   FakeWebStateListDelegate delegate;
   WebStateList web_state_list(&delegate);
   web_state_list.InsertWebState(
-      0, CreateWebStateRestoreSessionInProgress(),
-      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_PINNED,
-      WebStateOpener());
+      CreateWebStateRestoreSessionInProgress(),
+      WebStateList::InsertionParams::AtIndex(0).Pinned());
   web_state_list.InsertWebState(
-      0, CreateWebStateWithNoNavigation(),
-      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_PINNED,
-      WebStateOpener());
+      CreateWebStateWithNoNavigation(),
+      WebStateList::InsertionParams::AtIndex(0).Pinned());
   web_state_list.InsertWebState(
-      1, CreateWebStateWithNoNavigation(),
-      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_ACTIVATE,
-      WebStateOpener(web_state_list.GetWebStateAt(0), 3));
+      CreateWebStateWithNoNavigation(),
+      WebStateList::InsertionParams::AtIndex(1).Activate().WithOpener(
+          WebStateOpener(web_state_list.GetWebStateAt(0), 3)));
   web_state_list.InsertWebState(
-      2, CreateWebStateWithNoNavigation(), WebStateList::INSERT_FORCE_INDEX,
-      WebStateOpener(web_state_list.GetWebStateAt(0), 2));
+      CreateWebStateWithNoNavigation(),
+      WebStateList::InsertionParams::AtIndex(2).WithOpener(
+          WebStateOpener(web_state_list.GetWebStateAt(0), 2)));
+  web_state_list.InsertWebState(CreateWebState(),
+                                WebStateList::InsertionParams::AtIndex(3));
   web_state_list.InsertWebState(
-      3, CreateWebState(), WebStateList::INSERT_FORCE_INDEX, WebStateOpener());
-  web_state_list.InsertWebState(
-      4, CreateWebStateWithPendingNavigation(pending_item.get()),
-      WebStateList::INSERT_FORCE_INDEX,
-      WebStateOpener(web_state_list.GetWebStateAt(2), 1));
+      CreateWebStateWithPendingNavigation(pending_item.get()),
+      WebStateList::InsertionParams::AtIndex(4).WithOpener(
+          WebStateOpener(web_state_list.GetWebStateAt(2), 1)));
 
   // Serialize the session and check the serialized data is correct.
   SessionWindowIOS* session_window = SerializeWebStateList(&web_state_list);
@@ -309,36 +308,26 @@
   FakeWebStateListDelegate delegate;
   WebStateList web_state_list(&delegate);
   web_state_list.InsertWebState(
-      0,
       CreateWebStateWithWebStateID(web::WebStateID::FromSerializedValue(4444)),
-      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_PINNED,
-      WebStateOpener());
+      WebStateList::InsertionParams::AtIndex(0).Pinned());
   web_state_list.InsertWebState(
-      1,
       CreateWebStateWithWebStateID(web::WebStateID::FromSerializedValue(4444)),
-      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_PINNED,
-      WebStateOpener());
+      WebStateList::InsertionParams::AtIndex(1).Pinned());
   web_state_list.InsertWebState(
-      2,
       CreateWebStateWithWebStateID(web::WebStateID::FromSerializedValue(2222)),
-      WebStateList::INSERT_FORCE_INDEX, WebStateOpener());
+      WebStateList::InsertionParams::AtIndex(2));
   web_state_list.InsertWebState(
-      3,
       CreateWebStateWithWebStateID(web::WebStateID::FromSerializedValue(4444)),
-      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_ACTIVATE,
-      WebStateOpener());
+      WebStateList::InsertionParams::AtIndex(3).Activate());
   web_state_list.InsertWebState(
-      4,
       CreateWebStateWithWebStateID(web::WebStateID::FromSerializedValue(4444)),
-      WebStateList::INSERT_FORCE_INDEX, WebStateOpener());
+      WebStateList::InsertionParams::AtIndex(4));
   web_state_list.InsertWebState(
-      5,
       CreateWebStateWithWebStateID(web::WebStateID::FromSerializedValue(2222)),
-      WebStateList::INSERT_FORCE_INDEX, WebStateOpener());
+      WebStateList::InsertionParams::AtIndex(5));
   web_state_list.InsertWebState(
-      6,
       CreateWebStateWithWebStateID(web::WebStateID::FromSerializedValue(1111)),
-      WebStateList::INSERT_FORCE_INDEX, WebStateOpener());
+      WebStateList::InsertionParams::AtIndex(6));
 
   // Serialize the session and check the serialized data is correct.
   SessionWindowIOS* session_window = SerializeWebStateList(&web_state_list);
@@ -363,14 +352,10 @@
   WebStateList web_state_list(&delegate);
   web::WebStateID same_web_state_id = web::WebStateID::NewUnique();
   web_state_list.InsertWebState(
-      0, CreateWebStateWithNoNavigation(same_web_state_id),
-      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_PINNED |
-          WebStateList::INSERT_ACTIVATE,
-      WebStateOpener());
-  web_state_list.InsertWebState(
-      1, CreateWebStateWithWebStateID(same_web_state_id),
-      WebStateList::INSERT_FORCE_INDEX, WebStateOpener());
-
+      CreateWebStateWithNoNavigation(same_web_state_id),
+      WebStateList::InsertionParams::AtIndex(0).Pinned().Activate());
+  web_state_list.InsertWebState(CreateWebStateWithWebStateID(same_web_state_id),
+                                WebStateList::InsertionParams::AtIndex(1));
   // Serialize the session and check the serialized data is correct.
   SessionWindowIOS* session_window = SerializeWebStateList(&web_state_list);
 
@@ -415,19 +400,19 @@
   FakeWebStateListDelegate delegate;
   WebStateList web_state_list(&delegate);
   web_state_list.InsertWebState(
-      0, CreateWebState(),
-      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_PINNED,
-      WebStateOpener());
+      CreateWebState(), WebStateList::InsertionParams::AtIndex(0).Pinned());
   web_state_list.InsertWebState(
-      1, CreateWebState(),
-      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_ACTIVATE,
-      WebStateOpener(web_state_list.GetWebStateAt(0), 3));
+      CreateWebState(),
+      WebStateList::InsertionParams::AtIndex(1).Activate().WithOpener(
+          WebStateOpener(web_state_list.GetWebStateAt(0), 3)));
   web_state_list.InsertWebState(
-      2, CreateWebState(), WebStateList::INSERT_FORCE_INDEX,
-      WebStateOpener(web_state_list.GetWebStateAt(0), 2));
+      CreateWebState(),
+      WebStateList::InsertionParams::AtIndex(2).WithOpener(
+          WebStateOpener(web_state_list.GetWebStateAt(0), 2)));
   web_state_list.InsertWebState(
-      3, CreateWebState(), WebStateList::INSERT_FORCE_INDEX,
-      WebStateOpener(web_state_list.GetWebStateAt(1), 1));
+      CreateWebState(),
+      WebStateList::InsertionParams::AtIndex(3).WithOpener(
+          WebStateOpener(web_state_list.GetWebStateAt(1), 1)));
 
   // Serialize the session and check the serialized data is correct.
   ios::proto::WebStateListStorage storage;
@@ -472,26 +457,25 @@
   FakeWebStateListDelegate delegate;
   WebStateList web_state_list(&delegate);
   web_state_list.InsertWebState(
-      0, CreateWebStateRestoreSessionInProgress(),
-      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_PINNED,
-      WebStateOpener());
+      CreateWebStateRestoreSessionInProgress(),
+      WebStateList::InsertionParams::AtIndex(0).Pinned());
   web_state_list.InsertWebState(
-      0, CreateWebStateWithNoNavigation(),
-      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_PINNED,
-      WebStateOpener());
+      CreateWebStateWithNoNavigation(),
+      WebStateList::InsertionParams::AtIndex(0).Pinned());
   web_state_list.InsertWebState(
-      1, CreateWebStateWithNoNavigation(),
-      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_ACTIVATE,
-      WebStateOpener(web_state_list.GetWebStateAt(0), 3));
+      CreateWebStateWithNoNavigation(),
+      WebStateList::InsertionParams::AtIndex(1).Activate().WithOpener(
+          WebStateOpener(web_state_list.GetWebStateAt(0), 3)));
   web_state_list.InsertWebState(
-      2, CreateWebStateWithNoNavigation(), WebStateList::INSERT_FORCE_INDEX,
-      WebStateOpener(web_state_list.GetWebStateAt(0), 2));
+      CreateWebStateWithNoNavigation(),
+      WebStateList::InsertionParams::AtIndex(2).WithOpener(
+          WebStateOpener(web_state_list.GetWebStateAt(0), 2)));
+  web_state_list.InsertWebState(CreateWebState(),
+                                WebStateList::InsertionParams::AtIndex(3));
   web_state_list.InsertWebState(
-      3, CreateWebState(), WebStateList::INSERT_FORCE_INDEX, WebStateOpener());
-  web_state_list.InsertWebState(
-      4, CreateWebStateWithPendingNavigation(pending_item.get()),
-      WebStateList::INSERT_FORCE_INDEX,
-      WebStateOpener(web_state_list.GetWebStateAt(2), 1));
+      CreateWebStateWithPendingNavigation(pending_item.get()),
+      WebStateList::InsertionParams::AtIndex(4).WithOpener(
+          WebStateOpener(web_state_list.GetWebStateAt(2), 1)));
 
   // Serialize the session and check the serialized data is correct.
   ios::proto::WebStateListStorage storage;
@@ -515,36 +499,26 @@
   FakeWebStateListDelegate delegate;
   WebStateList web_state_list(&delegate);
   web_state_list.InsertWebState(
-      0,
       CreateWebStateWithWebStateID(web::WebStateID::FromSerializedValue(4444)),
-      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_PINNED,
-      WebStateOpener());
+      WebStateList::InsertionParams::AtIndex(0).Pinned());
   web_state_list.InsertWebState(
-      1,
       CreateWebStateWithWebStateID(web::WebStateID::FromSerializedValue(4444)),
-      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_PINNED,
-      WebStateOpener());
+      WebStateList::InsertionParams::AtIndex(1).Pinned());
   web_state_list.InsertWebState(
-      2,
       CreateWebStateWithWebStateID(web::WebStateID::FromSerializedValue(2222)),
-      WebStateList::INSERT_FORCE_INDEX, WebStateOpener());
+      WebStateList::InsertionParams::AtIndex(2));
   web_state_list.InsertWebState(
-      3,
       CreateWebStateWithWebStateID(web::WebStateID::FromSerializedValue(4444)),
-      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_ACTIVATE,
-      WebStateOpener());
+      WebStateList::InsertionParams::AtIndex(3).Activate());
   web_state_list.InsertWebState(
-      4,
       CreateWebStateWithWebStateID(web::WebStateID::FromSerializedValue(4444)),
-      WebStateList::INSERT_FORCE_INDEX, WebStateOpener());
+      WebStateList::InsertionParams::AtIndex(4));
   web_state_list.InsertWebState(
-      5,
       CreateWebStateWithWebStateID(web::WebStateID::FromSerializedValue(2222)),
-      WebStateList::INSERT_FORCE_INDEX, WebStateOpener());
+      WebStateList::InsertionParams::AtIndex(5));
   web_state_list.InsertWebState(
-      6,
       CreateWebStateWithWebStateID(web::WebStateID::FromSerializedValue(1111)),
-      WebStateList::INSERT_FORCE_INDEX, WebStateOpener());
+      WebStateList::InsertionParams::AtIndex(6));
 
   // Serialize the session and check the serialized data is correct.
   ios::proto::WebStateListStorage storage;
@@ -571,14 +545,10 @@
   WebStateList web_state_list(&delegate);
   web::WebStateID same_web_state_id = web::WebStateID::NewUnique();
   web_state_list.InsertWebState(
-      0, CreateWebStateWithNoNavigation(same_web_state_id),
-      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_PINNED |
-          WebStateList::INSERT_ACTIVATE,
-      WebStateOpener());
-  web_state_list.InsertWebState(
-      1, CreateWebStateWithWebStateID(same_web_state_id),
-      WebStateList::INSERT_FORCE_INDEX, WebStateOpener());
-
+      CreateWebStateWithNoNavigation(same_web_state_id),
+      WebStateList::InsertionParams::AtIndex(0).Pinned().Activate());
+  web_state_list.InsertWebState(CreateWebStateWithWebStateID(same_web_state_id),
+                                WebStateList::InsertionParams::AtIndex(1));
   // Serialize the session and check the serialized data is correct.
   ios::proto::WebStateListStorage storage;
   SerializeWebStateList(web_state_list, storage);
@@ -604,19 +574,19 @@
   {
     WebStateList web_state_list(&delegate);
     web_state_list.InsertWebState(
-        0, CreateWebState(),
-        WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_PINNED,
-        WebStateOpener());
+        CreateWebState(), WebStateList::InsertionParams::AtIndex(0).Pinned());
     web_state_list.InsertWebState(
-        1, CreateWebState(),
-        WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_ACTIVATE,
-        WebStateOpener(web_state_list.GetWebStateAt(0), 3));
+        CreateWebState(),
+        WebStateList::InsertionParams::AtIndex(1).Activate().WithOpener(
+            WebStateOpener(web_state_list.GetWebStateAt(0), 3)));
     web_state_list.InsertWebState(
-        2, CreateWebState(), WebStateList::INSERT_FORCE_INDEX,
-        WebStateOpener(web_state_list.GetWebStateAt(0), 2));
+        CreateWebState(),
+        WebStateList::InsertionParams::AtIndex(2).WithOpener(
+            WebStateOpener(web_state_list.GetWebStateAt(0), 2)));
     web_state_list.InsertWebState(
-        3, CreateWebState(), WebStateList::INSERT_FORCE_INDEX,
-        WebStateOpener(web_state_list.GetWebStateAt(1), 1));
+        CreateWebState(),
+        WebStateList::InsertionParams::AtIndex(3).WithOpener(
+            WebStateOpener(web_state_list.GetWebStateAt(1), 1)));
 
     session_window = SerializeWebStateList(&web_state_list);
 
@@ -662,19 +632,19 @@
   {
     WebStateList web_state_list(&delegate);
     web_state_list.InsertWebState(
-        0, CreateWebState(),
-        WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_PINNED,
-        WebStateOpener());
+        CreateWebState(), WebStateList::InsertionParams::AtIndex(0).Pinned());
     web_state_list.InsertWebState(
-        1, CreateWebState(),
-        WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_ACTIVATE,
-        WebStateOpener(web_state_list.GetWebStateAt(0), 3));
+        CreateWebState(),
+        WebStateList::InsertionParams::AtIndex(1).Activate().WithOpener(
+            WebStateOpener(web_state_list.GetWebStateAt(0), 3)));
     web_state_list.InsertWebState(
-        2, CreateWebState(), WebStateList::INSERT_FORCE_INDEX,
-        WebStateOpener(web_state_list.GetWebStateAt(0), 2));
+        CreateWebState(),
+        WebStateList::InsertionParams::AtIndex(2).WithOpener(
+            WebStateOpener(web_state_list.GetWebStateAt(0), 2)));
     web_state_list.InsertWebState(
-        3, CreateWebState(), WebStateList::INSERT_FORCE_INDEX,
-        WebStateOpener(web_state_list.GetWebStateAt(1), 1));
+        CreateWebState(),
+        WebStateList::InsertionParams::AtIndex(3).WithOpener(
+            WebStateOpener(web_state_list.GetWebStateAt(1), 1)));
 
     session_window = SerializeWebStateList(&web_state_list);
 
@@ -720,19 +690,19 @@
   {
     WebStateList web_state_list(&delegate);
     web_state_list.InsertWebState(
-        0, CreateWebState(),
-        WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_PINNED,
-        WebStateOpener());
+        CreateWebState(), WebStateList::InsertionParams::AtIndex(0).Pinned());
     web_state_list.InsertWebState(
-        1, CreateWebState(),
-        WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_ACTIVATE,
-        WebStateOpener(web_state_list.GetWebStateAt(0), 3));
+        CreateWebState(),
+        WebStateList::InsertionParams::AtIndex(1).Activate().WithOpener(
+            WebStateOpener(web_state_list.GetWebStateAt(0), 3)));
     web_state_list.InsertWebState(
-        2, CreateWebState(), WebStateList::INSERT_FORCE_INDEX,
-        WebStateOpener(web_state_list.GetWebStateAt(0), 2));
+        CreateWebState(),
+        WebStateList::InsertionParams::AtIndex(2).WithOpener(
+            WebStateOpener(web_state_list.GetWebStateAt(0), 2)));
     web_state_list.InsertWebState(
-        3, CreateWebState(), WebStateList::INSERT_FORCE_INDEX,
-        WebStateOpener(web_state_list.GetWebStateAt(1), 1));
+        CreateWebState(),
+        WebStateList::InsertionParams::AtIndex(3).WithOpener(
+            WebStateOpener(web_state_list.GetWebStateAt(1), 1)));
 
     SerializeWebStateList(web_state_list, storage);
 
@@ -778,19 +748,19 @@
   {
     WebStateList web_state_list(&delegate);
     web_state_list.InsertWebState(
-        0, CreateWebState(),
-        WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_PINNED,
-        WebStateOpener());
+        CreateWebState(), WebStateList::InsertionParams::AtIndex(0).Pinned());
     web_state_list.InsertWebState(
-        1, CreateWebState(),
-        WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_ACTIVATE,
-        WebStateOpener(web_state_list.GetWebStateAt(0), 3));
+        CreateWebState(),
+        WebStateList::InsertionParams::AtIndex(1).Activate().WithOpener(
+            WebStateOpener(web_state_list.GetWebStateAt(0), 3)));
     web_state_list.InsertWebState(
-        2, CreateWebState(), WebStateList::INSERT_FORCE_INDEX,
-        WebStateOpener(web_state_list.GetWebStateAt(0), 2));
+        CreateWebState(),
+        WebStateList::InsertionParams::AtIndex(2).WithOpener(
+            WebStateOpener(web_state_list.GetWebStateAt(0), 2)));
     web_state_list.InsertWebState(
-        3, CreateWebState(), WebStateList::INSERT_FORCE_INDEX,
-        WebStateOpener(web_state_list.GetWebStateAt(1), 1));
+        CreateWebState(),
+        WebStateList::InsertionParams::AtIndex(3).WithOpener(
+            WebStateOpener(web_state_list.GetWebStateAt(1), 1)));
 
     SerializeWebStateList(web_state_list, storage);
 
@@ -843,19 +813,19 @@
   {
     WebStateList web_state_list(&delegate);
     web_state_list.InsertWebState(
-        0, CreateWebState(),
-        WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_PINNED,
-        WebStateOpener());
+        CreateWebState(), WebStateList::InsertionParams::AtIndex(0).Pinned());
     web_state_list.InsertWebState(
-        1, CreateWebState(),
-        WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_ACTIVATE,
-        WebStateOpener(web_state_list.GetWebStateAt(0), 3));
+        CreateWebState(),
+        WebStateList::InsertionParams::AtIndex(1).Activate().WithOpener(
+            WebStateOpener(web_state_list.GetWebStateAt(0), 3)));
     web_state_list.InsertWebState(
-        2, CreateWebState(), WebStateList::INSERT_FORCE_INDEX,
-        WebStateOpener(web_state_list.GetWebStateAt(0), 2));
+        CreateWebState(),
+        WebStateList::InsertionParams::AtIndex(2).WithOpener(
+            WebStateOpener(web_state_list.GetWebStateAt(0), 2)));
     web_state_list.InsertWebState(
-        3, CreateWebState(), WebStateList::INSERT_FORCE_INDEX,
-        WebStateOpener(web_state_list.GetWebStateAt(1), 1));
+        CreateWebState(),
+        WebStateList::InsertionParams::AtIndex(3).WithOpener(
+            WebStateOpener(web_state_list.GetWebStateAt(1), 1)));
 
     SerializeWebStateList(web_state_list, storage);
 
diff --git a/ios/chrome/browser/settings/model/sync/utils/identity_error_util.mm b/ios/chrome/browser/settings/model/sync/utils/identity_error_util.mm
index 7f4d478e..6d631b4 100644
--- a/ios/chrome/browser/settings/model/sync/utils/identity_error_util.mm
+++ b/ios/chrome/browser/settings/model/sync/utils/identity_error_util.mm
@@ -92,7 +92,7 @@
 AccountErrorUIInfo* GetAccountErrorUIInfo(syncer::SyncService* sync_service) {
   DCHECK(sync_service);
 
-  // TODO(crbug.com/1462552): Remove usage of IsSyncFeatureEnabled() after
+  // TODO(crbug.com/40066949): Remove usage of IsSyncFeatureEnabled() after
   // kSync users are migrated to kSignin in phase 3. See ConsentLevel::kSync
   // documentation for details.
   if (sync_service->IsSyncFeatureEnabled()) {
@@ -124,7 +124,7 @@
   return nil;
 }
 
-// TODO(crbug.com/1462552): Remove this function after kSync users are migrated
+// TODO(crbug.com/40066949): Remove this function after kSync users are migrated
 // to kSignin in phase 3. See ConsentLevel::kSync documentation for details.
 SyncState GetSyncFeatureState(syncer::SyncService* sync_service) {
   syncer::SyncService::UserActionableError error_state =
diff --git a/ios/chrome/browser/settings/model/sync/utils/sync_util.mm b/ios/chrome/browser/settings/model/sync/utils/sync_util.mm
index a95be06..a24fc51f 100644
--- a/ios/chrome/browser/settings/model/sync/utils/sync_util.mm
+++ b/ios/chrome/browser/settings/model/sync/utils/sync_util.mm
@@ -300,7 +300,7 @@
 
     signin::IdentityManager* identityManager =
         IdentityManagerFactory::GetForBrowserState(browser_state);
-    // TODO(crbug.com/1462552): Simplify this (remove the whole
+    // TODO(crbug.com/40066949): Simplify this (remove the whole
     // `if (!UseIdentityErrorInfobar(syncService)) {...}`) after kSync users are
     // migrated to kSignin in phase 3. See ConsentLevel::kSync documentation for
     // details.
diff --git a/ios/chrome/browser/shared/model/web_state_list/web_state_list.h b/ios/chrome/browser/shared/model/web_state_list/web_state_list.h
index 61d4aaa..e339cd0 100644
--- a/ios/chrome/browser/shared/model/web_state_list/web_state_list.h
+++ b/ios/chrome/browser/shared/model/web_state_list/web_state_list.h
@@ -269,12 +269,6 @@
   int InsertWebState(std::unique_ptr<web::WebState> web_state,
                      InsertionParams params = InsertionParams::Automatic());
 
-  // Deprecated. Use the variant with InsertionParams.
-  int InsertWebState(int index,
-                     std::unique_ptr<web::WebState> web_state,
-                     int insertion_flags,
-                     WebStateOpener opener);
-
   // Moves the WebState at the specified index to another index.
   void MoveWebStateAt(int from_index, int to_index);
 
diff --git a/ios/chrome/browser/shared/model/web_state_list/web_state_list.mm b/ios/chrome/browser/shared/model/web_state_list/web_state_list.mm
index b1a53853..f2ce6f9b 100644
--- a/ios/chrome/browser/shared/model/web_state_list/web_state_list.mm
+++ b/ios/chrome/browser/shared/model/web_state_list/web_state_list.mm
@@ -346,16 +346,6 @@
   return InsertWebStateImpl(std::move(web_state), params);
 }
 
-int WebStateList::InsertWebState(int index,
-                                 std::unique_ptr<web::WebState> web_state,
-                                 int insertion_flags,
-                                 WebStateOpener opener) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  InsertionParams params =
-      InsertionParams::ForDeprecationMigration(insertion_flags, index, opener);
-  return InsertWebState(std::move(web_state), params);
-}
-
 void WebStateList::MoveWebStateAt(int from_index, int to_index) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   auto lock = LockForMutation();
diff --git a/ios/chrome/browser/shared/model/web_state_list/web_state_list_unittest.mm b/ios/chrome/browser/shared/model/web_state_list/web_state_list_unittest.mm
index ec0aeb7..7e867b0 100644
--- a/ios/chrome/browser/shared/model/web_state_list/web_state_list_unittest.mm
+++ b/ios/chrome/browser/shared/model/web_state_list/web_state_list_unittest.mm
@@ -1175,69 +1175,26 @@
   EXPECT_EQ(web_state_list_.SetWebStatePinnedAt(2, true), 2);
 
   // Insert a WebState into pinned WebStates range.
-  web_state_list_.InsertWebState(0, CreateWebState(testURL0),
-                                 WebStateList::INSERT_NO_FLAGS,
-                                 WebStateOpener());
+  web_state_list_.InsertWebState(CreateWebState(testURL0),
+                                 WebStateList::InsertionParams::AtIndex(0));
   // Expect a WebState to be added at the end of the WebStateList.
   EXPECT_EQ(web_state_list_.GetWebStateAt(4)->GetVisibleURL().spec(), testURL0);
 
   // Insert a WebState into pinned WebStates range.
-  web_state_list_.InsertWebState(2, CreateWebState(testURL1),
-                                 WebStateList::INSERT_NO_FLAGS,
-                                 WebStateOpener());
+  web_state_list_.InsertWebState(CreateWebState(testURL1),
+                                 WebStateList::InsertionParams::AtIndex(2));
   // Expect a WebState to be added at the end of the WebStateList.
   EXPECT_EQ(web_state_list_.GetWebStateAt(5)->GetVisibleURL().spec(), testURL1);
 
   // Insert a WebState into pinned WebStates range.
-  web_state_list_.InsertWebState(1, CreateWebState(testURL2),
-                                 WebStateList::INSERT_NO_FLAGS,
-                                 WebStateOpener());
+  web_state_list_.InsertWebState(CreateWebState(testURL2),
+                                 WebStateList::InsertionParams::AtIndex(1));
   // Expect a WebState to be added at the end of the WebStateList.
   EXPECT_EQ(web_state_list_.GetWebStateAt(6)->GetVisibleURL().spec(), testURL2);
 }
 
-// Tests InsertWebState method correctly updates insertion index if it is in the
-// pinned WebStates range and the flag is INSERT_FORCE_INDEX.
-TEST_F(WebStateListTest, InsertWebState_ForceInsertionInPinnedRange) {
-  const char testURL0[] = "https://chromium.org/test_0";
-  const char testURL1[] = "https://chromium.org/test_1";
-  const char testURL2[] = "https://chromium.org/test_2";
-
-  EXPECT_TRUE(web_state_list_.empty());
-
-  AppendNewWebState(kURL0);
-  AppendNewWebState(kURL1);
-  AppendNewWebState(kURL2);
-  AppendNewWebState(kURL3);
-
-  EXPECT_EQ(web_state_list_.SetWebStatePinnedAt(0, true), 0);
-  EXPECT_EQ(web_state_list_.SetWebStatePinnedAt(1, true), 1);
-  EXPECT_EQ(web_state_list_.SetWebStatePinnedAt(2, true), 2);
-
-  // Insert a WebState into pinned WebStates range.
-  web_state_list_.InsertWebState(0, CreateWebState(testURL0),
-                                 WebStateList::INSERT_FORCE_INDEX,
-                                 WebStateOpener());
-  // Expect a WebState to be added at the end of WebStates list.
-  EXPECT_EQ(web_state_list_.GetWebStateAt(4)->GetVisibleURL().spec(), testURL0);
-
-  // Insert a WebState into pinned WebStates range.
-  web_state_list_.InsertWebState(2, CreateWebState(testURL1),
-                                 WebStateList::INSERT_FORCE_INDEX,
-                                 WebStateOpener());
-  // Expect a WebState to be added at the end of WebStates list.
-  EXPECT_EQ(web_state_list_.GetWebStateAt(5)->GetVisibleURL().spec(), testURL1);
-
-  // Insert a WebState into pinned WebStates range.
-  web_state_list_.InsertWebState(1, CreateWebState(testURL2),
-                                 WebStateList::INSERT_FORCE_INDEX,
-                                 WebStateOpener());
-  // Expect a WebState to be added at the end of WebStates list.
-  EXPECT_EQ(web_state_list_.GetWebStateAt(6)->GetVisibleURL().spec(), testURL2);
-}
-
-// Tests InsertWebState method correctly updates insertion index when the flag
-// is INSERT_PINNED.
+// Tests InsertWebState method correctly updates insertion index when the params
+// specify it should be pinned.
 TEST_F(WebStateListTest, InsertWebState_InsertWebStatePinned) {
   const char testURL0[] = "https://chromium.org/test_0";
   const char testURL1[] = "https://chromium.org/test_1";
@@ -1250,57 +1207,10 @@
   AppendNewWebState(kURL2);
   AppendNewWebState(kURL3);
 
-  // Insert a pinned WebState at invalid index.
-  web_state_list_.InsertWebState(WebStateList::kInvalidIndex,
-                                 CreateWebState(testURL0),
-                                 WebStateList::INSERT_PINNED, WebStateOpener());
-  // Expect a WebState to be added into pinned WebStates range.
-  EXPECT_EQ(web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec(), testURL0);
-  // Expect a WebState to be pinned.
-  EXPECT_TRUE(web_state_list_.IsWebStatePinnedAt(0));
-
-  // Insert a pinned WebState to the non-pinned WebStates range.
-  web_state_list_.InsertWebState(2, CreateWebState(testURL1),
-                                 WebStateList::INSERT_PINNED, WebStateOpener());
-  // Expect a WebState to be added at the end of the pinned WebStates range.
-  EXPECT_EQ(web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec(), testURL1);
-  // Expect a WebState to be pinned.
-  EXPECT_TRUE(web_state_list_.IsWebStatePinnedAt(1));
-
-  // Insert a pinned WebState to the pinned WebStates range.
-  web_state_list_.InsertWebState(0, CreateWebState(testURL2),
-                                 WebStateList::INSERT_PINNED, WebStateOpener());
-  // Expect a WebState to be added at the end of the pinned WebStates range.
-  EXPECT_EQ(web_state_list_.GetWebStateAt(2)->GetVisibleURL().spec(), testURL2);
-  // Expect a WebState to be pinned.
-  EXPECT_TRUE(web_state_list_.IsWebStatePinnedAt(2));
-
-  // Final check that only first three WebStates were pinned.
-  EXPECT_TRUE(web_state_list_.IsWebStatePinnedAt(0));
-  EXPECT_TRUE(web_state_list_.IsWebStatePinnedAt(1));
-  EXPECT_TRUE(web_state_list_.IsWebStatePinnedAt(2));
-  EXPECT_FALSE(web_state_list_.IsWebStatePinnedAt(3));
-}
-
-// Tests InsertWebState method correctly updates insertion index when the flags
-// are INSERT_PINNED and INSERT_FORCE_INDEX.
-TEST_F(WebStateListTest, InsertWebState_InsertWebStatePinnedForceIndex) {
-  const char testURL0[] = "https://chromium.org/test_0";
-  const char testURL1[] = "https://chromium.org/test_1";
-  const char testURL2[] = "https://chromium.org/test_2";
-
-  EXPECT_TRUE(web_state_list_.empty());
-
-  AppendNewWebState(kURL0);
-  AppendNewWebState(kURL1);
-  AppendNewWebState(kURL2);
-  AppendNewWebState(kURL3);
-
-  // Insert a pinned WebState at invalid index.
+  // Insert a pinned WebState without specifying an index.
   web_state_list_.InsertWebState(
-      WebStateList::kInvalidIndex, CreateWebState(testURL0),
-      WebStateList::INSERT_PINNED | WebStateList::INSERT_FORCE_INDEX,
-      WebStateOpener());
+      CreateWebState(testURL0),
+      WebStateList::InsertionParams::Automatic().Pinned());
   // Expect a WebState to be added into pinned WebStates range.
   EXPECT_EQ(web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec(), testURL0);
   // Expect a WebState to be pinned.
@@ -1308,9 +1218,8 @@
 
   // Insert a pinned WebState to the non-pinned WebStates range.
   web_state_list_.InsertWebState(
-      2, CreateWebState(testURL1),
-      WebStateList::INSERT_PINNED | WebStateList::INSERT_FORCE_INDEX,
-      WebStateOpener());
+      CreateWebState(testURL1),
+      WebStateList::InsertionParams::AtIndex(2).Pinned());
   // Expect a WebState to be added at the end of the pinned WebStates range.
   EXPECT_EQ(web_state_list_.GetWebStateAt(1)->GetVisibleURL().spec(), testURL1);
   // Expect a WebState to be pinned.
@@ -1318,10 +1227,9 @@
 
   // Insert a pinned WebState to the pinned WebStates range.
   web_state_list_.InsertWebState(
-      0, CreateWebState(testURL2),
-      WebStateList::INSERT_PINNED | WebStateList::INSERT_FORCE_INDEX,
-      WebStateOpener());
-  // Expect a WebState to be added at the same index.
+      CreateWebState(testURL2),
+      WebStateList::InsertionParams::AtIndex(0).Pinned());
+  // Expect a WebState to be added at the end of the pinned WebStates range.
   EXPECT_EQ(web_state_list_.GetWebStateAt(0)->GetVisibleURL().spec(), testURL2);
   // Expect a WebState to be pinned.
   EXPECT_TRUE(web_state_list_.IsWebStatePinnedAt(0));
diff --git a/ios/chrome/browser/shared/public/commands/help_commands.h b/ios/chrome/browser/shared/public/commands/help_commands.h
index 138f27a..c7d6a91 100644
--- a/ios/chrome/browser/shared/public/commands/help_commands.h
+++ b/ios/chrome/browser/shared/public/commands/help_commands.h
@@ -11,10 +11,9 @@
 // Dismisses all bubbles.
 - (void)hideAllHelpBubbles;
 
-// If any gesture IPH visible, remove it; does nothing otherwise. The presenter
-// of any gesture IPH should make sure it's called when the user leaves the
-// refreshed website, especially while the IPH is still visible.
-- (void)hideAllGestureInProductHelpViews;
+// Invoked when a gestural in-product help view is visible but the user has
+// tapped outside of it. Do nothing if invoked when there is no IPH view.
+- (void)handleTapOutsideOfVisibleGestureInProductHelp;
 
 // Shows a help bubble for the share button, if eligible.
 // The eligibility can depend on the UI hierarchy at the moment, the
diff --git a/ios/chrome/browser/signin/model/authentication_service.h b/ios/chrome/browser/signin/model/authentication_service.h
index 966f97ea..e026082 100644
--- a/ios/chrome/browser/signin/model/authentication_service.h
+++ b/ios/chrome/browser/signin/model/authentication_service.h
@@ -124,7 +124,7 @@
   // `access_point`. This starts setting up Sync-the-feature, but the setup will
   // only complete once SyncUserSettings::SetInitialSyncFeatureSetupComplete()
   // is called. This method is used for testing. Virtual for testing.
-  // TODO(crbug.com/1462858): Delete this method after Phase 2 on iOS is
+  // TODO(crbug.com/40067025): Delete this method after Phase 2 on iOS is
   // launched. See ConsentLevel::kSync documentation for details.
   virtual void GrantSyncConsent(id<SystemIdentity> identity,
                                 signin_metrics::AccessPoint access_point);
diff --git a/ios/chrome/browser/signin/model/authentication_service.mm b/ios/chrome/browser/signin/model/authentication_service.mm
index bd6ce23..bd1d9b9c 100644
--- a/ios/chrome/browser/signin/model/authentication_service.mm
+++ b/ios/chrome/browser/signin/model/authentication_service.mm
@@ -344,7 +344,7 @@
     signin_metrics::AccessPoint access_point) {
   if (base::FeatureList::IsEnabled(
           syncer::kReplaceSyncPromosWithSignInPromos)) {
-    // TODO(crbug.com/1462858): Turn sync on was deprecated. Remove
+    // TODO(crbug.com/40067025): Turn sync on was deprecated. Remove
     // `GrantSyncConsent()` as it is obsolete.
     DUMP_WILL_BE_CHECK(access_point !=
                        signin_metrics::AccessPoint::
diff --git a/ios/chrome/browser/signin/model/authentication_service_unittest.mm b/ios/chrome/browser/signin/model/authentication_service_unittest.mm
index 091ac1f..30eb830 100644
--- a/ios/chrome/browser/signin/model/authentication_service_unittest.mm
+++ b/ios/chrome/browser/signin/model/authentication_service_unittest.mm
@@ -743,7 +743,7 @@
   EXPECT_EQ(invocation_counter, 1u);
 }
 
-// TODO(crbug.com/1462552): Remove this test after kSync users are migrated in
+// TODO(crbug.com/40066949): Remove this test after kSync users are migrated in
 // phase 3. See ConsentLevel::kSync documentation for details.
 TEST_F(AuthenticationServiceTest, SigninAndSyncDecoupled) {
   // Sign in.
diff --git a/ios/chrome/browser/signin/model/constants.h b/ios/chrome/browser/signin/model/constants.h
index e365c11..a970053 100644
--- a/ios/chrome/browser/signin/model/constants.h
+++ b/ios/chrome/browser/signin/model/constants.h
@@ -36,7 +36,7 @@
   kNone,
   // Shows a snackbar displaying the account that just signed-in.
   kShowSnackbar,
-  // TODO(crbug.com/1462858): Turn on sync was deprecated. Delete this enum
+  // TODO(crbug.com/40067025): Turn on sync was deprecated. Delete this enum
   // after phase 2 launches on iOS. See ConsentLevel::kSync documentation for
   // details.
   // Starts sign-in flow for a sync consent.
diff --git a/ios/chrome/browser/sync/model/sync_setup_service.cc b/ios/chrome/browser/sync/model/sync_setup_service.cc
index 3848300..c298d89 100644
--- a/ios/chrome/browser/sync/model/sync_setup_service.cc
+++ b/ios/chrome/browser/sync/model/sync_setup_service.cc
@@ -30,7 +30,7 @@
   CHECK(sync_blocker_);
   // Turn on the sync setup completed flag only if the user did not turn sync
   // off.
-  // TODO(crbug.com/1462858): Remove this code once
+  // TODO(crbug.com/40067025): Remove this code once
   // kReplaceSyncPromosWithSignInPromos launches.
   if (sync_service_->CanSyncFeatureStart()) {
     sync_service_->GetUserSettings()->SetInitialSyncFeatureSetupComplete(
diff --git a/ios/chrome/browser/tab_insertion/model/tab_insertion_browser_agent.mm b/ios/chrome/browser/tab_insertion/model/tab_insertion_browser_agent.mm
index f25379f9..a419d7a3 100644
--- a/ios/chrome/browser/tab_insertion/model/tab_insertion_browser_agent.mm
+++ b/ios/chrome/browser/tab_insertion/model/tab_insertion_browser_agent.mm
@@ -117,10 +117,12 @@
     web_state->GetNavigationManager()->LoadURLWithParams(web_load_params);
   }
 
+  const WebStateList::InsertionParams params =
+      WebStateList::InsertionParams::ForDeprecationMigration(
+          insertion_flags, insertion_index,
+          WebStateOpener(tab_insertion_params.parent));
   web::WebState* web_state_ptr = web_state.get();
-  web_state_list->InsertWebState(insertion_index, std::move(web_state),
-                                 insertion_flags,
-                                 WebStateOpener(tab_insertion_params.parent));
+  web_state_list->InsertWebState(std::move(web_state), params);
   return web_state_ptr;
 }
 
diff --git a/ios/chrome/browser/tabs/model/tab_helper_delegate_installer_unittest.mm b/ios/chrome/browser/tabs/model/tab_helper_delegate_installer_unittest.mm
index 62ec1b4..b52d654 100644
--- a/ios/chrome/browser/tabs/model/tab_helper_delegate_installer_unittest.mm
+++ b/ios/chrome/browser/tabs/model/tab_helper_delegate_installer_unittest.mm
@@ -142,8 +142,7 @@
 
   // Insert a WebState into the WebStateList.
   browser_->GetWebStateList()->InsertWebState(
-      0, std::make_unique<web::FakeWebState>(), WebStateList::INSERT_NO_FLAGS,
-      WebStateOpener());
+      std::make_unique<web::FakeWebState>());
   FakeTabHelper* tab_helper = FakeTabHelper::FromWebState(
       browser_->GetWebStateList()->GetWebStateAt(0));
 
@@ -156,8 +155,7 @@
 TEST_F(TabHelperDelegateInstallerTest, InstallDelegatesForReplacedWebStates) {
   // Insert a WebState into the WebStateList before the installer is created.
   browser_->GetWebStateList()->InsertWebState(
-      0, std::make_unique<web::FakeWebState>(), WebStateList::INSERT_NO_FLAGS,
-      WebStateOpener());
+      std::make_unique<web::FakeWebState>());
   FakeTabHelper* tab_helper = FakeTabHelper::FromWebState(
       browser_->GetWebStateList()->GetWebStateAt(0));
 
@@ -188,8 +186,7 @@
        UninstallDelegatesFromDetachedWebStates) {
   // Insert a WebState into the WebStateList before the installer is created.
   browser_->GetWebStateList()->InsertWebState(
-      0, std::make_unique<web::FakeWebState>(), WebStateList::INSERT_NO_FLAGS,
-      WebStateOpener());
+      std::make_unique<web::FakeWebState>());
   FakeTabHelper* tab_helper = FakeTabHelper::FromWebState(
       browser_->GetWebStateList()->GetWebStateAt(0));
 
@@ -213,8 +210,7 @@
        UninstallDelegatesForBrowserDestruction) {
   // Insert a WebState into the WebStateList before the installer is created.
   browser_->GetWebStateList()->InsertWebState(
-      0, std::make_unique<web::FakeWebState>(), WebStateList::INSERT_NO_FLAGS,
-      WebStateOpener());
+      std::make_unique<web::FakeWebState>());
 
   Delegate* set_delegate = nullptr;
   SecondDelegate* set_second_delegate = nullptr;
@@ -254,8 +250,7 @@
        UninstallDelegatesForInstallerDestruction) {
   // Insert a WebState into the WebStateList before the installer is created.
   browser_->GetWebStateList()->InsertWebState(
-      0, std::make_unique<web::FakeWebState>(), WebStateList::INSERT_NO_FLAGS,
-      WebStateOpener());
+      std::make_unique<web::FakeWebState>());
   FakeTabHelper* tab_helper = FakeTabHelper::FromWebState(
       browser_->GetWebStateList()->GetWebStateAt(0));
 
diff --git a/ios/chrome/browser/tabs/model/tabs_closer.mm b/ios/chrome/browser/tabs/model/tabs_closer.mm
index b940155..e24fcc53 100644
--- a/ios/chrome/browser/tabs/model/tabs_closer.mm
+++ b/ios/chrome/browser/tabs/model/tabs_closer.mm
@@ -44,13 +44,13 @@
     const bool is_pinned = start + n < old_pinned_count;
     std::unique_ptr<web::WebState> web_state = source->DetachWebStateAt(start);
 
-    const int insertion_flags =
-        (is_pinned ? WebStateList::INSERT_PINNED : 0) |
-        (start + n == old_active_index ? WebStateList::INSERT_ACTIVATE : 0);
+    const WebStateList::InsertionParams params =
+        WebStateList::InsertionParams::AtIndex(n + offset)
+            .Pinned(is_pinned)
+            .Activate(start + n == old_active_index);
 
-    const int insertion_index = target->InsertWebState(
-        n + offset, std::move(web_state), insertion_flags, WebStateOpener());
-
+    const int insertion_index =
+        target->InsertWebState(std::move(web_state), params);
     DCHECK_EQ(n + offset, insertion_index);
   }
 }
diff --git a/ios/chrome/browser/tabs/model/tabs_closer_unittest.mm b/ios/chrome/browser/tabs/model/tabs_closer_unittest.mm
index 27b7153..0fc8195 100644
--- a/ios/chrome/browser/tabs/model/tabs_closer_unittest.mm
+++ b/ios/chrome/browser/tabs/model/tabs_closer_unittest.mm
@@ -119,8 +119,8 @@
         browser_state_.get());
   }
 
-  // Creates an insert a fake WebState in `browser` using `policy` and `opener`.
-  web::WebState* InsertWebState(InsertionPolicy policy, WebStateOpener opener) {
+  // Appends a fake WebState in `browser_` using `policy` and `opener`.
+  web::WebState* AppendWebState(InsertionPolicy policy, WebStateOpener opener) {
     const GURL url = GURL("https://example.com");
     auto navigation_manager = std::make_unique<web::FakeNavigationManager>();
     navigation_manager->AddItem(url, ui::PAGE_TRANSITION_LINK);
@@ -139,13 +139,15 @@
           content_world, std::make_unique<web::FakeWebFramesManager>());
     }
 
-    const int flags =
-        WebStateList::INSERT_FORCE_INDEX |
-        (policy == InsertionPolicy::kPinned ? WebStateList::INSERT_PINNED : 0);
-
     WebStateList* web_state_list = browser_->GetWebStateList();
-    const int insertion_index = web_state_list->InsertWebState(
-        web_state_list->count(), std::move(web_state), flags, opener);
+    // Force the insertion at the end. Otherwise, the opener will trigger logic
+    // to move an inserted WebState close to its opener.
+    const WebStateList::InsertionParams params =
+        WebStateList::InsertionParams::AtIndex(web_state_list->count())
+            .Pinned(policy == InsertionPolicy::kPinned)
+            .WithOpener(opener);
+    const int insertion_index =
+        web_state_list->InsertWebState(std::move(web_state), params);
 
     return web_state_list->GetWebStateAt(insertion_index);
   }
@@ -186,11 +188,11 @@
   WebStateList* web_state_list = browser()->GetWebStateList();
 
   web::WebState* web_state0 =
-      InsertWebState(InsertionPolicy::kRegular, WebStateOpener{});
+      AppendWebState(InsertionPolicy::kRegular, WebStateOpener{});
   web::WebState* web_state1 =
-      InsertWebState(InsertionPolicy::kRegular, WebStateOpener{});
+      AppendWebState(InsertionPolicy::kRegular, WebStateOpener{});
   web::WebState* web_state2 =
-      InsertWebState(InsertionPolicy::kRegular, WebStateOpener{web_state1, 0});
+      AppendWebState(InsertionPolicy::kRegular, WebStateOpener{web_state1, 0});
 
   ASSERT_EQ(web_state_list->count(), 3);
   ASSERT_EQ(web_state_list->GetWebStateAt(0), web_state0);
@@ -249,11 +251,11 @@
   WebStateList* web_state_list = browser()->GetWebStateList();
 
   web::WebState* web_state0 =
-      InsertWebState(InsertionPolicy::kRegular, WebStateOpener{});
+      AppendWebState(InsertionPolicy::kRegular, WebStateOpener{});
   web::WebState* web_state1 =
-      InsertWebState(InsertionPolicy::kRegular, WebStateOpener{});
+      AppendWebState(InsertionPolicy::kRegular, WebStateOpener{});
   web::WebState* web_state2 =
-      InsertWebState(InsertionPolicy::kRegular, WebStateOpener{web_state1, 0});
+      AppendWebState(InsertionPolicy::kRegular, WebStateOpener{web_state1, 0});
 
   ASSERT_EQ(web_state_list->count(), 3);
   ASSERT_EQ(web_state_list->GetWebStateAt(0), web_state0);
@@ -312,9 +314,9 @@
   WebStateList* web_state_list = browser()->GetWebStateList();
 
   web::WebState* web_state0 =
-      InsertWebState(InsertionPolicy::kPinned, WebStateOpener{});
+      AppendWebState(InsertionPolicy::kPinned, WebStateOpener{});
   web::WebState* web_state1 =
-      InsertWebState(InsertionPolicy::kPinned, WebStateOpener{web_state0, 0});
+      AppendWebState(InsertionPolicy::kPinned, WebStateOpener{web_state0, 0});
 
   ASSERT_EQ(web_state_list->count(), 2);
   ASSERT_EQ(web_state_list->GetWebStateAt(0), web_state0);
@@ -371,9 +373,9 @@
   WebStateList* web_state_list = browser()->GetWebStateList();
 
   web::WebState* web_state0 =
-      InsertWebState(InsertionPolicy::kPinned, WebStateOpener{});
+      AppendWebState(InsertionPolicy::kPinned, WebStateOpener{});
   web::WebState* web_state1 =
-      InsertWebState(InsertionPolicy::kPinned, WebStateOpener{web_state0, 0});
+      AppendWebState(InsertionPolicy::kPinned, WebStateOpener{web_state0, 0});
 
   ASSERT_EQ(web_state_list->count(), 2);
   ASSERT_EQ(web_state_list->GetWebStateAt(0), web_state0);
@@ -395,15 +397,15 @@
   WebStateList* web_state_list = browser()->GetWebStateList();
 
   web::WebState* web_state0 =
-      InsertWebState(InsertionPolicy::kPinned, WebStateOpener{});
+      AppendWebState(InsertionPolicy::kPinned, WebStateOpener{});
   web::WebState* web_state1 =
-      InsertWebState(InsertionPolicy::kPinned, WebStateOpener{web_state0, 0});
+      AppendWebState(InsertionPolicy::kPinned, WebStateOpener{web_state0, 0});
   web::WebState* web_state2 =
-      InsertWebState(InsertionPolicy::kRegular, WebStateOpener{});
+      AppendWebState(InsertionPolicy::kRegular, WebStateOpener{});
   web::WebState* web_state3 =
-      InsertWebState(InsertionPolicy::kRegular, WebStateOpener{web_state1, 0});
+      AppendWebState(InsertionPolicy::kRegular, WebStateOpener{web_state1, 0});
   web::WebState* web_state4 =
-      InsertWebState(InsertionPolicy::kRegular, WebStateOpener{web_state3, 0});
+      AppendWebState(InsertionPolicy::kRegular, WebStateOpener{web_state3, 0});
 
   ASSERT_EQ(web_state_list->count(), 5);
   ASSERT_EQ(web_state_list->GetWebStateAt(0), web_state0);
@@ -468,15 +470,15 @@
   WebStateList* web_state_list = browser()->GetWebStateList();
 
   web::WebState* web_state0 =
-      InsertWebState(InsertionPolicy::kPinned, WebStateOpener{});
+      AppendWebState(InsertionPolicy::kPinned, WebStateOpener{});
   web::WebState* web_state1 =
-      InsertWebState(InsertionPolicy::kPinned, WebStateOpener{web_state0, 0});
+      AppendWebState(InsertionPolicy::kPinned, WebStateOpener{web_state0, 0});
   web::WebState* web_state2 =
-      InsertWebState(InsertionPolicy::kRegular, WebStateOpener{});
+      AppendWebState(InsertionPolicy::kRegular, WebStateOpener{});
   web::WebState* web_state3 =
-      InsertWebState(InsertionPolicy::kRegular, WebStateOpener{web_state1, 0});
+      AppendWebState(InsertionPolicy::kRegular, WebStateOpener{web_state1, 0});
   web::WebState* web_state4 =
-      InsertWebState(InsertionPolicy::kRegular, WebStateOpener{web_state3, 0});
+      AppendWebState(InsertionPolicy::kRegular, WebStateOpener{web_state3, 0});
 
   ASSERT_EQ(web_state_list->count(), 5);
   ASSERT_EQ(web_state_list->GetWebStateAt(0), web_state0);
@@ -544,15 +546,15 @@
   WebStateList* web_state_list = browser()->GetWebStateList();
 
   web::WebState* web_state0 =
-      InsertWebState(InsertionPolicy::kPinned, WebStateOpener{});
+      AppendWebState(InsertionPolicy::kPinned, WebStateOpener{});
   web::WebState* web_state1 =
-      InsertWebState(InsertionPolicy::kPinned, WebStateOpener{web_state0, 0});
+      AppendWebState(InsertionPolicy::kPinned, WebStateOpener{web_state0, 0});
   web::WebState* web_state2 =
-      InsertWebState(InsertionPolicy::kRegular, WebStateOpener{});
+      AppendWebState(InsertionPolicy::kRegular, WebStateOpener{});
   web::WebState* web_state3 =
-      InsertWebState(InsertionPolicy::kRegular, WebStateOpener{web_state1, 0});
+      AppendWebState(InsertionPolicy::kRegular, WebStateOpener{web_state1, 0});
   web::WebState* web_state4 =
-      InsertWebState(InsertionPolicy::kRegular, WebStateOpener{web_state3, 0});
+      AppendWebState(InsertionPolicy::kRegular, WebStateOpener{web_state3, 0});
 
   ASSERT_EQ(web_state_list->count(), 5);
   ASSERT_EQ(web_state_list->GetWebStateAt(0), web_state0);
@@ -605,15 +607,15 @@
   WebStateList* web_state_list = browser()->GetWebStateList();
 
   web::WebState* web_state0 =
-      InsertWebState(InsertionPolicy::kPinned, WebStateOpener{});
+      AppendWebState(InsertionPolicy::kPinned, WebStateOpener{});
   web::WebState* web_state1 =
-      InsertWebState(InsertionPolicy::kPinned, WebStateOpener{web_state0, 0});
+      AppendWebState(InsertionPolicy::kPinned, WebStateOpener{web_state0, 0});
   web::WebState* web_state2 =
-      InsertWebState(InsertionPolicy::kRegular, WebStateOpener{});
+      AppendWebState(InsertionPolicy::kRegular, WebStateOpener{});
   web::WebState* web_state3 =
-      InsertWebState(InsertionPolicy::kRegular, WebStateOpener{web_state1, 0});
+      AppendWebState(InsertionPolicy::kRegular, WebStateOpener{web_state1, 0});
   web::WebState* web_state4 =
-      InsertWebState(InsertionPolicy::kRegular, WebStateOpener{web_state3, 0});
+      AppendWebState(InsertionPolicy::kRegular, WebStateOpener{web_state3, 0});
 
   ASSERT_EQ(web_state_list->count(), 5);
   ASSERT_EQ(web_state_list->GetWebStateAt(0), web_state0);
diff --git a/ios/chrome/browser/ui/authentication/authentication_flow.mm b/ios/chrome/browser/ui/authentication/authentication_flow.mm
index c0863a23..7a376bc 100644
--- a/ios/chrome/browser/ui/authentication/authentication_flow.mm
+++ b/ios/chrome/browser/ui/authentication/authentication_flow.mm
@@ -514,7 +514,7 @@
     bool isManagedAccount = _identityToSignInHostedDomain.length > 0;
     signin_metrics::RecordSigninAccountType(signin::ConsentLevel::kSignin,
                                             isManagedAccount);
-    // TODO(crbug.com/1462858): Turn sync on was deprecated. Remove this branch
+    // TODO(crbug.com/40067025): Turn sync on was deprecated. Remove this branch
     // after phase 2 on iOS is launched. See ConsentLevel::kSync documentation
     // for details.
     if (self.postSignInAction == PostSignInAction::kCommitSync) {
diff --git a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
index 05ce48c..3a259fa 100644
--- a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
+++ b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
@@ -222,7 +222,7 @@
       IdentityManagerFactory::GetForBrowserState(browserState);
   AuthenticationService* authenticationService =
       AuthenticationServiceFactory::GetForBrowserState(browserState);
-  // TODO(crbug.com/1462552): After phase 3 migration usage of
+  // TODO(crbug.com/40066949): After phase 3 migration usage of
   // `lastSyncingEmail` to avoid cross-sync incidents should become obsolete.
   // Delete the usage of ConsentLevel::kSync in this method afterwards.
   // See ConsentLevel::kSync documentation for more details.
diff --git a/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_mediator.mm b/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_mediator.mm
index 48b0729e..ce4a5f2 100644
--- a/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_mediator.mm
+++ b/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_mediator.mm
@@ -104,7 +104,6 @@
     case signin_metrics::AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN:
     case signin_metrics::AccessPoint::ACCESS_POINT_USER_MANAGER:
     case signin_metrics::AccessPoint::ACCESS_POINT_DEVICES_PAGE:
-    case signin_metrics::AccessPoint::ACCESS_POINT_CLOUD_PRINT:
     case signin_metrics::AccessPoint::ACCESS_POINT_SIGNIN_PROMO:
     case signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN:
     case signin_metrics::AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE:
diff --git a/ios/chrome/browser/ui/authentication/signin/signin_constants.h b/ios/chrome/browser/ui/authentication/signin/signin_constants.h
index 89a2961..7377a0c 100644
--- a/ios/chrome/browser/ui/authentication/signin/signin_constants.h
+++ b/ios/chrome/browser/ui/authentication/signin/signin_constants.h
@@ -23,8 +23,7 @@
 };
 
 // User's signed-in state as defined by AuthenticationService.
-// TODO(crbug.com/1462552): After phase 3 migration of syncing users, remove
-// `Sync` from enum name and refactor.
+// TODO(crbug.com/40066949): Revisit after phase 3 migration of syncing users.
 typedef NS_ENUM(NSUInteger, IdentitySigninState) {
   IdentitySigninStateSignedOut,
   IdentitySigninStateSignedInWithSyncDisabled,
diff --git a/ios/chrome/browser/ui/authentication/signin/signin_utils.mm b/ios/chrome/browser/ui/authentication/signin/signin_utils.mm
index bfc9f78..c032428 100644
--- a/ios/chrome/browser/ui/authentication/signin/signin_utils.mm
+++ b/ios/chrome/browser/ui/authentication/signin/signin_utils.mm
@@ -266,7 +266,7 @@
       AuthenticationServiceFactory::GetForBrowserState(browser_state);
   syncer::SyncService* syncService =
       SyncServiceFactory::GetForBrowserState(browser_state);
-  // TODO(crbug.com/1462552): After phase 3 migration of kSync users, Remove
+  // TODO(crbug.com/40066949): After phase 3 migration of kSync users, Remove
   // this usage.
   if (auth_service->HasPrimaryIdentity(signin::ConsentLevel::kSync) &&
       syncService->GetUserSettings()->IsInitialSyncFeatureSetupComplete()) {
diff --git a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm
index d7e2475..094d402 100644
--- a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm
+++ b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm
@@ -77,7 +77,6 @@
     case signin_metrics::AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN:
     case signin_metrics::AccessPoint::ACCESS_POINT_USER_MANAGER:
     case signin_metrics::AccessPoint::ACCESS_POINT_DEVICES_PAGE:
-    case signin_metrics::AccessPoint::ACCESS_POINT_CLOUD_PRINT:
     case signin_metrics::AccessPoint::ACCESS_POINT_SIGNIN_PROMO:
     case signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN:
     case signin_metrics::AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE:
@@ -159,7 +158,6 @@
     case signin_metrics::AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN:
     case signin_metrics::AccessPoint::ACCESS_POINT_USER_MANAGER:
     case signin_metrics::AccessPoint::ACCESS_POINT_DEVICES_PAGE:
-    case signin_metrics::AccessPoint::ACCESS_POINT_CLOUD_PRINT:
     case signin_metrics::AccessPoint::ACCESS_POINT_SIGNIN_PROMO:
     case signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN:
     case signin_metrics::AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE:
@@ -245,7 +243,6 @@
     case signin_metrics::AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN:
     case signin_metrics::AccessPoint::ACCESS_POINT_USER_MANAGER:
     case signin_metrics::AccessPoint::ACCESS_POINT_DEVICES_PAGE:
-    case signin_metrics::AccessPoint::ACCESS_POINT_CLOUD_PRINT:
     case signin_metrics::AccessPoint::ACCESS_POINT_SIGNIN_PROMO:
     case signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN:
     case signin_metrics::AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE:
@@ -331,7 +328,6 @@
     case signin_metrics::AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN:
     case signin_metrics::AccessPoint::ACCESS_POINT_USER_MANAGER:
     case signin_metrics::AccessPoint::ACCESS_POINT_DEVICES_PAGE:
-    case signin_metrics::AccessPoint::ACCESS_POINT_CLOUD_PRINT:
     case signin_metrics::AccessPoint::ACCESS_POINT_SIGNIN_PROMO:
     case signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN:
     case signin_metrics::AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE:
@@ -404,7 +400,6 @@
     case signin_metrics::AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN:
     case signin_metrics::AccessPoint::ACCESS_POINT_USER_MANAGER:
     case signin_metrics::AccessPoint::ACCESS_POINT_DEVICES_PAGE:
-    case signin_metrics::AccessPoint::ACCESS_POINT_CLOUD_PRINT:
     case signin_metrics::AccessPoint::ACCESS_POINT_SIGNIN_PROMO:
     case signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN:
     case signin_metrics::AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE:
@@ -477,7 +472,6 @@
     case signin_metrics::AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN:
     case signin_metrics::AccessPoint::ACCESS_POINT_USER_MANAGER:
     case signin_metrics::AccessPoint::ACCESS_POINT_DEVICES_PAGE:
-    case signin_metrics::AccessPoint::ACCESS_POINT_CLOUD_PRINT:
     case signin_metrics::AccessPoint::ACCESS_POINT_SIGNIN_PROMO:
     case signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN:
     case signin_metrics::AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE:
@@ -1079,7 +1073,7 @@
   // If the sign-in view is removed when the user is authenticated, then the
   // sign-in for sync has been done by another view, and this mediator cannot be
   // counted as being dismissed.
-  // TODO(crbug.com/1462858): Once new sync opt-ins are deprecated this usage
+  // TODO(crbug.com/40067025): Once new sync opt-ins are deprecated this usage
   // of kSync will become obsolete. Delete this code after phase 2.
   if (self.authService->HasPrimaryIdentity(signin::ConsentLevel::kSync))
     return;
diff --git a/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_coordinator.mm b/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_coordinator.mm
index 03427e58..d0ab934 100644
--- a/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_coordinator.mm
+++ b/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_coordinator.mm
@@ -158,7 +158,7 @@
   DCHECK(self.browser);
   syncer::SyncService* syncService =
       SyncServiceFactory::GetForBrowserState(self.browser->GetBrowserState());
-  // TODO(crbug.com/1462552): Simplify once ConsentLevel::kSync and
+  // TODO(crbug.com/40066949): Simplify once ConsentLevel::kSync and
   // SyncService::IsSyncFeatureEnabled() are deleted from the codebase.
   if (!self.authenticationService->HasPrimaryIdentity(
           signin::ConsentLevel::kSync) &&
diff --git a/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_coordinator_unittest.mm b/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_coordinator_unittest.mm
index 9b8f5153..29e1b6d 100644
--- a/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_coordinator_unittest.mm
@@ -122,7 +122,7 @@
 
 // Tests that a signed-in user with Sync enabled will have an action sheet with
 // a sign-out title.
-// TODO(crbug.com/1462552): Remove this test once ConsentLevel::kSync does not
+// TODO(crbug.com/40066949): Remove this test once ConsentLevel::kSync does not
 // exist on iOS anymore.
 TEST_F(SignoutActionSheetCoordinatorTest, SignedInUserWithSync) {
   authentication_service()->SignIn(
@@ -141,7 +141,7 @@
 
 // Tests that a signed-in user with Sync disabled will have an action sheet with
 // no title.
-// TODO(crbug.com/1462858): Remove this test once
+// TODO(crbug.com/40067025): Remove this test once
 // kReplaceSyncPromosWithSignInPromos is launched - with that feature, signed-in
 // non-syncing users do *not* get a signout action sheet anymore.
 TEST_F(SignoutActionSheetCoordinatorTest, SignedInUserWithoutSync) {
@@ -163,7 +163,7 @@
 
 // Tests that a signed-in user with the forced sign-in policy enabled will have
 // an action sheet with a title and a message.
-// TODO(crbug.com/1462858): Remove this test once
+// TODO(crbug.com/40067025): Remove this test once
 // kReplaceSyncPromosWithSignInPromos is launched - with that feature, signed-in
 // non-syncing users do *not* get a signout action sheet anymore.
 TEST_F(SignoutActionSheetCoordinatorTest, SignedInUserWithForcedSignin) {
@@ -190,7 +190,7 @@
 
 // Tests that a signed-in managed user with Sync enabled will have an action
 // sheet with a sign-out title.
-// TODO(crbug.com/1462552): Remove this test once ConsentLevel::kSync does not
+// TODO(crbug.com/40066949): Remove this test once ConsentLevel::kSync does not
 // exist on iOS anymore.
 TEST_F(SignoutActionSheetCoordinatorTest, SignedInManagedUserWithSync) {
   authentication_service()->SignIn(
@@ -211,7 +211,7 @@
 
 // Tests that a signed-in managed user with Sync disabled will have an action
 // sheet with no title.
-// TODO(crbug.com/1462858): Remove this test once
+// TODO(crbug.com/40067025): Remove this test once
 // kReplaceSyncPromosWithSignInPromos is launched - with that feature, signed-in
 // non-syncing users do *not* get a signout action sheet anymore.
 TEST_F(SignoutActionSheetCoordinatorTest, SignedInManagedUserWithoutSync) {
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm
index 563cff74..d4fe965 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm
@@ -181,7 +181,7 @@
   if (sync_service->GetAccountInfo().IsEmpty()) {
     return false;
   }
-  // TODO(crbug.com/1462552): Remove this after UNO phase 3. See
+  // TODO(crbug.com/40066949): Remove this after UNO phase 3. See
   // ConsentLevel::kSync documentation for more details.
   if (sync_service->HasSyncConsent()) {
     return false;
@@ -277,7 +277,7 @@
     bookmarks::StorageType storageType,
     base::WeakPtr<AuthenticationService> authenticationService,
     raw_ptr<syncer::SyncService> syncService) {
-  // TODO(crbug.com/1462552): Simplify once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Simplify once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   BOOL hasSyncConsent =
diff --git a/ios/chrome/browser/ui/bookmarks/home/bookmark_promo_controller.mm b/ios/chrome/browser/ui/bookmarks/home/bookmark_promo_controller.mm
index 02f5fac..59bd920 100644
--- a/ios/chrome/browser/ui/bookmarks/home/bookmark_promo_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/home/bookmark_promo_controller.mm
@@ -121,7 +121,7 @@
       return;
     }
   } else if (identityManager->HasPrimaryAccount(signin::ConsentLevel::kSync)) {
-    // TODO(crbug.com/1462552): Simplify once kSync becomes unreachable or is
+    // TODO(crbug.com/40066949): Simplify once kSync becomes unreachable or is
     // deleted from the codebase. See ConsentLevel::kSync documentation for
     // details.
     // If the user is already syncing, the promo should not be visible.
diff --git a/ios/chrome/browser/ui/bubble/bubble_presenter.mm b/ios/chrome/browser/ui/bubble/bubble_presenter.mm
index fcfe31c..292f2fe 100644
--- a/ios/chrome/browser/ui/bubble/bubble_presenter.mm
+++ b/ios/chrome/browser/ui/bubble/bubble_presenter.mm
@@ -170,15 +170,13 @@
   [self.lensKeyboardPresenter dismissAnimated:NO];
   [self.defaultPageModeTipBubblePresenter dismissAnimated:NO];
   [self.parcelTrackingTipBubblePresenter dismissAnimated:NO];
-  [self hideAllGestureInProductHelpViews];
+  [self hideAllGestureInProductHelpViewsForReason:IPHDismissalReasonType::
+                                                      kUnknown];
 }
 
-- (void)hideAllGestureInProductHelpViews {
-  // TODO(crbug.com/1467873): Add a new reason type and use that.
-  [self.pullToRefreshGestureIPH
-      dismissWithReason:IPHDismissalReasonType::kUnknown];
-  [self.swipeBackForwardGestureIPH
-      dismissWithReason:IPHDismissalReasonType::kUnknown];
+- (void)handleTapOutsideOfVisibleGestureInProductHelp {
+  [self hideAllGestureInProductHelpViewsForReason:
+            IPHDismissalReasonType::kTappedOutsideIPHAndAnchorView];
 }
 
 - (void)presentShareButtonHelpBubbleIfEligible {
@@ -710,6 +708,16 @@
   return presenter;
 }
 
+// If any gesture IPH visible, remove it and log the `reason` why it should be
+// removed on UMA. Otherwise, do nothing. The presenter of any gesture IPH
+// should make sure it's called when the user leaves the refreshed website,
+// especially while the IPH is still visible.
+- (void)hideAllGestureInProductHelpViewsForReason:
+    (IPHDismissalReasonType)reason {
+  [self.pullToRefreshGestureIPH dismissWithReason:reason];
+  [self.swipeBackForwardGestureIPH dismissWithReason:reason];
+}
+
 #pragma mark - Private Utils
 
 // Returns the anchor point for a bubble with an `arrowDirection` pointing to a
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm
index 4c6b179..6012ae8 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm
@@ -260,7 +260,8 @@
     // Returns sufficient vertical space for the Identity Disc to be
     // displayed.
     return ntp_home::kIdentityAvatarDimension +
-           2 * ntp_home::kIdentityAvatarMargin;
+           2 * (ntp_home::kIdentityAvatarMargin +
+                ntp_home::kIdentityAvatarPadding);
   }
 
   header_height += kTopSpacingMaterial;
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h b/ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h
index 398b9a51..2aa331f 100644
--- a/ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h
+++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h
@@ -38,6 +38,8 @@
 extern const CGFloat kIdentityAvatarDimension;
 // Margin around user's identity avatar.
 extern const CGFloat kIdentityAvatarMargin;
+// Padding around user's identity avatar and its margin.
+extern const CGFloat kIdentityAvatarPadding;
 // Dimension of signed-out identity icon.
 extern const CGFloat kSignedOutIdentityIconDimension;
 
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_constant.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_constant.mm
index 4a84acf..8e8e3e78 100644
--- a/ios/chrome/browser/ui/content_suggestions/ntp_home_constant.mm
+++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_constant.mm
@@ -24,7 +24,8 @@
 const CGFloat kSuggestionPeekingHeight = 60;
 
 const CGFloat kIdentityAvatarDimension = 32;
-const CGFloat kIdentityAvatarMargin = 16;
+const CGFloat kIdentityAvatarMargin = 8;
+const CGFloat kIdentityAvatarPadding = 8;
 const CGFloat kSignedOutIdentityIconDimension = 24;
 
 UIColor* NTPBackgroundColor() {
diff --git a/ios/chrome/browser/ui/download/download_manager_view_controller.mm b/ios/chrome/browser/ui/download/download_manager_view_controller.mm
index ba9fce66..833b739a 100644
--- a/ios/chrome/browser/ui/download/download_manager_view_controller.mm
+++ b/ios/chrome/browser/ui/download/download_manager_view_controller.mm
@@ -370,7 +370,7 @@
 #pragma mark - DownloadManagerViewControllerProtocol
 
 - (UIView*)openInSourceView {
-  return nil;
+  return self.openInButton;
 }
 
 - (void)setFullscreenController:(FullscreenController*)fullscreenController {
diff --git a/ios/chrome/browser/ui/first_run/BUILD.gn b/ios/chrome/browser/ui/first_run/BUILD.gn
index 5f72e61..8058ed7 100644
--- a/ios/chrome/browser/ui/first_run/BUILD.gn
+++ b/ios/chrome/browser/ui/first_run/BUILD.gn
@@ -249,6 +249,7 @@
     "//ios/chrome/browser/shared/model/application_context",
     "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/sync/model",
+    "//ios/chrome/browser/ui/first_run/omnibox_position:omnibox_position_ui",
     "//ios/chrome/test/app:test_support",
     "//ios/third_party/earl_grey2:app_framework+link",
   ]
diff --git a/ios/chrome/browser/ui/first_run/first_run_app_interface.mm b/ios/chrome/browser/ui/first_run/first_run_app_interface.mm
index 67b5865..41cab6e 100644
--- a/ios/chrome/browser/ui/first_run/first_run_app_interface.mm
+++ b/ios/chrome/browser/ui/first_run/first_run_app_interface.mm
@@ -15,6 +15,7 @@
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/sync/model/sync_service_factory.h"
+#import "ios/chrome/browser/ui/first_run/omnibox_position/omnibox_position_choice_util.h"
 #import "ios/chrome/test/app/chrome_test_util.h"
 
 @implementation FirstRunAppInterface
@@ -43,7 +44,9 @@
 }
 
 + (BOOL)isOmniboxPositionChoiceEnabled {
-  return IsBottomOmniboxPromoFlagEnabled(BottomOmniboxPromoType::kFRE);
+  return IsBottomOmniboxPromoFlagEnabled(BottomOmniboxPromoType::kFRE) &&
+         ShouldShowOmniboxPositionChoiceInFRE(
+             chrome_test_util::GetOriginalBrowserState());
 }
 
 @end
diff --git a/ios/chrome/browser/ui/first_run/first_run_egtest.mm b/ios/chrome/browser/ui/first_run/first_run_egtest.mm
index cbc8a81..3220810 100644
--- a/ios/chrome/browser/ui/first_run/first_run_egtest.mm
+++ b/ios/chrome/browser/ui/first_run/first_run_egtest.mm
@@ -1537,8 +1537,8 @@
   config.additional_args.push_back(
       "--" + std::string(switches::kSearchEngineChoiceCountry) + "=FR");
   config.features_enabled.push_back(switches::kSearchEngineChoiceTrigger);
-  config.additional_args.push_back("--" +
-                                   std::string(kSearchEngineForceEnabled));
+  config.additional_args.push_back(
+      "--" + std::string(switches::kForceSearchEngineChoiceScreen));
   config.additional_args.push_back("true");
   return config;
 }
@@ -1557,8 +1557,7 @@
 // Tests that the Search Engine Choice screen is displayed, that the primary
 // button is correctly updated when the user selects a search engine then
 // scrolls down and that it correctly sets the default search engine.
-// TODO(crbug.com/1523586): Re-enable the test.
-- (void)DISABLED_testSearchEngineChoiceScreenSelectThenScroll {
+- (void)testSearchEngineChoiceScreenSelectThenScroll {
   // Skips sign-in.
   [[self elementInteractionWithGreyMatcher:
              chrome_test_util::PromoStyleSecondaryActionButtonMatcher()
@@ -1605,8 +1604,7 @@
 // Tests that the Search Engine Choice screen is displayed, that the
 // primary button is correctly updated when the user scrolls down then selects a
 // search engine and that it correctly sets the default search engine.
-// TODO(crbug.com/1523586): Re-enable the test.
-- (void)DISABLED_testSearchEngineChoiceScreenScrollThenSelect {
+- (void)testSearchEngineChoiceScreenScrollThenSelect {
   // Skips sign-in.
   [[self elementInteractionWithGreyMatcher:
              chrome_test_util::PromoStyleSecondaryActionButtonMatcher()
diff --git a/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm b/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm
index 06d827f..9850f6c 100644
--- a/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm
+++ b/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm
@@ -211,6 +211,8 @@
   self.infobarButton.accessibilityIdentifier =
       kInfobarBannerAcceptButtonIdentifier;
   self.infobarButton.pointerInteractionEnabled = YES;
+  self.infobarButton.layer.cornerRadius = kBannerViewCornerRadius;
+  self.infobarButton.clipsToBounds = YES;
   self.infobarButton.pointerStyleProvider =
       ^UIPointerStyle*(UIButton* button, UIPointerEffect* proposedEffect,
                        UIPointerShape* proposedShape) {
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm b/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm
index 20c03bc..5def98d 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm
@@ -259,9 +259,11 @@
     [self.identityDiscView.heightAnchor constraintEqualToConstant:dimension],
     [self.identityDiscView.widthAnchor constraintEqualToConstant:dimension],
     [self.identityDiscView.trailingAnchor
-        constraintEqualToAnchor:self.safeAreaLayoutGuide.trailingAnchor],
+        constraintEqualToAnchor:self.safeAreaLayoutGuide.trailingAnchor
+                       constant:-ntp_home::kIdentityAvatarPadding],
     [self.identityDiscView.topAnchor
-        constraintEqualToAnchor:self.toolBarView.topAnchor],
+        constraintEqualToAnchor:self.toolBarView.topAnchor
+                       constant:ntp_home::kIdentityAvatarPadding],
   ]];
 }
 
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm b/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm
index 5a4b8dd8..f8a66ca 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm
@@ -446,6 +446,9 @@
   self.identityDiscButton.imageView.layer.cornerRadius =
       self.identityDiscImage.size.width / 2;
   self.identityDiscButton.imageView.layer.masksToBounds = YES;
+  self.identityDiscButton.layer.cornerRadius =
+      self.identityDiscImage.size.width;
+  self.identityDiscButton.clipsToBounds = YES;
 }
 
 - (void)openLens {
diff --git a/ios/chrome/browser/ui/policy/user_policy_util.mm b/ios/chrome/browser/ui/policy/user_policy_util.mm
index 1876af2d..822c553 100644
--- a/ios/chrome/browser/ui/policy/user_policy_util.mm
+++ b/ios/chrome/browser/ui/policy/user_policy_util.mm
@@ -76,7 +76,7 @@
     return false;
   }
 
-  // TODO(crbug.com/1462552): Remove kSync usage after users are migrated to
+  // TODO(crbug.com/40066949): Remove kSync usage after users are migrated to
   // kSignin only after kSync sunset. See ConsentLevel::kSync for more details.
 
   bool enabled_for_sync =
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
index 053a9aa..7a8a88f5 100644
--- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
+++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
@@ -1574,8 +1574,7 @@
     } else {
       self.webStateList->InsertWebState(
           std::move(web_state),
-          WebStateList::InsertionParams::AtIndex(self.webStateList->count())
-              .Activate());
+          WebStateList::InsertionParams::Automatic().Activate());
     }
   }
   [self.presentationDelegate showActiveRegularTabFromRecentTabs];
@@ -1650,8 +1649,7 @@
 
   self.webStateList->InsertWebState(
       std::move(webState),
-      WebStateList::InsertionParams::AtIndex(self.webStateList->count())
-          .Activate());
+      WebStateList::InsertionParams::Automatic().Activate());
   webStatePtr->OpenURL(web::WebState::OpenURLParams(
       searchUrl, web::Referrer(), WindowOpenDisposition::CURRENT_TAB,
       ui::PAGE_TRANSITION_GENERATED, /*is_renderer_initiated=*/false));
diff --git a/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_constants.h b/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_constants.h
index 6361846..c8ad7e61 100644
--- a/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_constants.h
+++ b/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_constants.h
@@ -39,7 +39,4 @@
 // `More` button accessibility identifier.
 extern NSString* const kSearchEngineMoreButtonIdentifier;
 
-// Flags that allow to enable the search engine choice in tests.
-extern const char* const kSearchEngineForceEnabled;
-
 #endif  // IOS_CHROME_BROWSER_UI_SEARCH_ENGINE_CHOICE_SEARCH_ENGINE_CHOICE_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_constants.mm b/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_constants.mm
index facc8dc..cd853c9 100644
--- a/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_constants.mm
+++ b/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_constants.mm
@@ -24,5 +24,3 @@
     @"SearchEngineTableViewIdentifier";
 NSString* const kSearchEngineMoreButtonIdentifier =
     @"SearchEngineMoreButtonIdentifier";
-
-const char* const kSearchEngineForceEnabled = "search-engine-force-enabled";
diff --git a/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_egtest.mm b/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_egtest.mm
index 6632fd8..84e3231 100644
--- a/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_egtest.mm
+++ b/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_egtest.mm
@@ -48,8 +48,8 @@
   config.additional_args.push_back(
       "--enable-features=SearchEngineChoiceTrigger:for_tagged_profiles_only/"
       "false");
-  config.additional_args.push_back("--" +
-                                   std::string(kSearchEngineForceEnabled));
+  config.additional_args.push_back(
+      "--" + std::string(switches::kForceSearchEngineChoiceScreen));
   // Relaunches the app at each test to re-display the choice screen.
   config.relaunch_policy = ForceRelaunchByKilling;
 
diff --git a/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_ui_util.mm b/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_ui_util.mm
index 8358939..59cac14 100644
--- a/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_ui_util.mm
+++ b/ios/chrome/browser/ui/search_engine_choice/search_engine_choice_ui_util.mm
@@ -9,6 +9,7 @@
 #import "base/strings/sys_string_conversions.h"
 #import "base/strings/utf_string_conversions.h"
 #import "components/search_engines/search_engine_choice_utils.h"
+#import "components/search_engines/search_engines_switches.h"
 #import "components/search_engines/template_url.h"
 #import "components/strings/grit/components_strings.h"
 #import "ios/chrome/browser/shared/ui/symbols/symbols.h"
@@ -141,5 +142,5 @@
 
 bool IsSearchEngineForceEnabled() {
   return base::CommandLine::ForCurrentProcess()->HasSwitch(
-      kSearchEngineForceEnabled);
+      switches::kForceSearchEngineChoiceScreen);
 }
diff --git a/ios/chrome/browser/ui/settings/cells/settings_search_engine_item.h b/ios/chrome/browser/ui/settings/cells/settings_search_engine_item.h
index cc9f7b4..9a3e502 100644
--- a/ios/chrome/browser/ui/settings/cells/settings_search_engine_item.h
+++ b/ios/chrome/browser/ui/settings/cells/settings_search_engine_item.h
@@ -11,6 +11,7 @@
 
 @class FaviconAttributes;
 @class FaviconView;
+class TemplateURL;
 
 // SettingsSearchEngineItem contains the model data for a TableViewURLCell.
 @interface SettingsSearchEngineItem : TableViewItem
@@ -24,6 +25,8 @@
 @property(nonatomic, readwrite, copy) NSString* detailText;
 // Sets the favicon.
 @property(nonatomic, strong) FaviconAttributes* faviconAttributes;
+// Template URL.
+@property(nonatomic, assign) const TemplateURL* templateURL;
 
 @end
 
diff --git a/ios/chrome/browser/ui/settings/cells/settings_search_engine_item.mm b/ios/chrome/browser/ui/settings/cells/settings_search_engine_item.mm
index fc43acf..6ac495a 100644
--- a/ios/chrome/browser/ui/settings/cells/settings_search_engine_item.mm
+++ b/ios/chrome/browser/ui/settings/cells/settings_search_engine_item.mm
@@ -28,7 +28,9 @@
 
 }  // namespace
 
-@implementation SettingsSearchEngineItem
+@implementation SettingsSearchEngineItem {
+  raw_ptr<const TemplateURL> _templateURL;
+}
 
 @synthesize enabled = _enabled;
 @synthesize text = _text;
@@ -67,6 +69,14 @@
   cell.detailTextLabel.textColor = [UIColor colorNamed:kTextSecondaryColor];
 }
 
+- (void)setTemplateURL:(const TemplateURL*)templateURL {
+  _templateURL = templateURL;
+}
+
+- (const TemplateURL*)templateURL {
+  return _templateURL;
+}
+
 @end
 
 @implementation SettingsSearchEngineCell {
diff --git a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm
index 528364d..d785a873 100644
--- a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm
@@ -328,7 +328,7 @@
   [model addItem:[self signOutItem]
       toSectionWithIdentifier:SectionIdentifierSignOut];
 
-  // TODO(crbug.com/1462552): Simplify once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Simplify once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   BOOL hasSyncConsent =
@@ -1004,7 +1004,7 @@
 
 // Returns YES if the account is signed in not syncing, NO otherwise.
 - (BOOL)isAccountSignedInNotSyncing {
-  // TODO(crbug.com/1462552): Simplify once kSync becomes unreachable or is
+  // TODO(crbug.com/40066949): Simplify once kSync becomes unreachable or is
   // deleted from the codebase. See ConsentLevel::kSync documentation for
   // details.
   return base::FeatureList::IsEnabled(
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm b/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm
index 8c037513..e0c74382 100644
--- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm
@@ -192,7 +192,7 @@
                   }
                   // Provide additional data retention options if the user is
                   // syncing their data.
-                  // TODO(crbug.com/1462552): Simplify once kSync becomes
+                  // TODO(crbug.com/40066949): Simplify once kSync becomes
                   // unreachable or is deleted from the codebase. See
                   // ConsentLevel::kSync documentation for details.
                   if (weakSelf.identityManager->HasPrimaryAccount(
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_constants.h b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_constants.h
index d8cee15..821aa82 100644
--- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_constants.h
+++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_constants.h
@@ -116,12 +116,12 @@
 // States for Sync Settings page to be in.
 enum class SyncSettingsAccountState {
   // The user clicked "settings" in the Sync opt-in screen.
-  // TODO(crbug.com/1462552): Remove usage of kAdvancedInitialSyncSetup
+  // TODO(crbug.com/40066949): Remove usage of kAdvancedInitialSyncSetup
   // after kSync users are migrated to kSignin in phase 3. See
   // ConsentLevel::kSync documentation for details.
   kAdvancedInitialSyncSetup,
   // The user is viewing sync settings page when Sync-the-feature is on.
-  // TODO(crbug.com/1462552): Remove usage of kSyncing after kSync users are
+  // TODO(crbug.com/40066949): Remove usage of kSyncing after kSync users are
   // migrated to kSignin in phase 3. See ConsentLevel::kSync documentation for
   // details.
   kSyncing,
diff --git a/ios/chrome/browser/ui/settings/password/account_storage_utils.cc b/ios/chrome/browser/ui/settings/password/account_storage_utils.cc
index 3cc9a750..3bd9a22 100644
--- a/ios/chrome/browser/ui/settings/password/account_storage_utils.cc
+++ b/ios/chrome/browser/ui/settings/password/account_storage_utils.cc
@@ -30,8 +30,8 @@
   }
 
   // Syncing and signed-out users shouldn't see the icon.
-  // TODO(crbug.com/1462552): Remove usage of IsSyncFeatureEnabled() after kSync
-  // users are migrated to kSignin in phase 3. See ConsentLevel::kSync
+  // TODO(crbug.com/40066949): Remove usage of IsSyncFeatureEnabled() after
+  // kSync users are migrated to kSignin in phase 3. See ConsentLevel::kSync
   // documentation for details.
   if (sync_service->IsSyncFeatureEnabled() ||
       sync_service->HasDisableReason(
diff --git a/ios/chrome/browser/ui/settings/password/password_settings/password_settings_mediator.mm b/ios/chrome/browser/ui/settings/password/password_settings/password_settings_mediator.mm
index 015c184..417a3e4 100644
--- a/ios/chrome/browser/ui/settings/password/password_settings/password_settings_mediator.mm
+++ b/ios/chrome/browser/ui/settings/password/password_settings/password_settings_mediator.mm
@@ -399,7 +399,7 @@
 }
 
 - (AccountStorageSwitchState)computeAccountStorageSwitchState {
-  // TODO(crbug.com/1462858): Delete the usage of IsSyncFeatureEnabled() after
+  // TODO(crbug.com/40067025): Delete the usage of IsSyncFeatureEnabled() after
   // Phase 2 on iOS is launched. See ConsentLevel::kSync documentation for
   // details.
   if (_syncService->GetAccountInfo().IsEmpty() ||
diff --git a/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller.mm b/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller.mm
index a317aae..6cd7fc49 100644
--- a/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller.mm
@@ -356,7 +356,7 @@
       SyncServiceFactory::GetInstance()->GetForBrowserState(_browserState);
 
   NSMutableArray* urls = [[NSMutableArray alloc] init];
-  // TODO(crbug.com/1462552): Remove IsSyncFeatureEnabled() usage after kSync
+  // TODO(crbug.com/40066949): Remove IsSyncFeatureEnabled() usage after kSync
   // users are migrated to kSignin in phase 3. See ConsentLevel::kSync for more
   // details.
   if (syncService->IsSyncFeatureEnabled()) {
diff --git a/ios/chrome/browser/ui/settings/search_engine_table_view_controller.mm b/ios/chrome/browser/ui/settings/search_engine_table_view_controller.mm
index a74af530..b1474eb3 100644
--- a/ios/chrome/browser/ui/settings/search_engine_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/search_engine_table_view_controller.mm
@@ -89,13 +89,13 @@
   // Note that `TemplateURL` pointers should not be freed. They either come from
   // `TemplateURLService::GetTemplateURLs()`, or they are owned by
   // `_choiceScreenTemplateUrls`.
-  std::vector<TemplateURL*> _firstList;
+  std::vector<raw_ptr<TemplateURL>> _firstList;
   // The second list in the page which contains all remaining custom search
   // engines.
   // Note that `TemplateURL` pointers should not be freed. They either come from
   // `TemplateURLService::GetTemplateURLs()`, or they are owned by
   // `_choiceScreenTemplateUrls`.
-  std::vector<TemplateURL*> _secondList;
+  std::vector<raw_ptr<TemplateURL>> _secondList;
   // FaviconLoader is a keyed service that uses LargeIconService to retrieve
   // favicon images.
   raw_ptr<FaviconLoader> _faviconLoader;
@@ -576,6 +576,7 @@
           [weakSelf faviconReceivedFor:item faviconAttributes:attributes];
         });
   }
+  item.templateURL = templateURL;
   item.text = base::SysUTF16ToNSString(templateURL->short_name());
   item.detailText = base::SysUTF16ToNSString(templateURL->keyword());
   if ([self isItem:item
@@ -608,6 +609,7 @@
           [weakSelf faviconReceivedFor:item faviconAttributes:attributes];
         });
   }
+  item.templateURL = templateURL;
   item.text = base::SysUTF16ToNSString(templateURL->short_name());
   item.detailText = base::SysUTF16ToNSString(templateURL->keyword());
   if ([self isItem:item
@@ -645,7 +647,6 @@
   }
   // Update `_templateURLService`, `_firstList` and `_secondList`.
   _updatingBackend = YES;
-  size_t removedItemsInSecondList = 0;
   NSInteger firstSection = [self.tableViewModel
       sectionForSectionIdentifier:SectionIdentifierFirstList];
   bool resetDefaultEngine = false;
@@ -653,9 +654,10 @@
   // Remove search engines from `_firstList`, `_secondList` and
   // `_templateURLService`.
   for (NSIndexPath* path : indexPaths) {
-    TemplateURL* engine = nullptr;
+    TableViewItem* item = [self.tableViewModel itemAtIndexPath:path];
+    SettingsSearchEngineItem* engineItem =
+        base::apple::ObjCCastStrict<SettingsSearchEngineItem>(item);
     if (path.section == firstSection) {
-      TableViewItem* item = [self.tableViewModel itemAtIndexPath:path];
       // Only custom search engine can be deleted.
       CHECK(item.type == ItemTypeCustomEngine, base::NotFatalUntil::M124);
       // It should not be possible to remove a search engine from the first
@@ -665,41 +667,20 @@
       CHECK(!_shouldShowEEASettings, base::NotFatalUntil::M124);
       // The custom search engine in the first section should be the last one.
       DCHECK(path.row == static_cast<int>(_firstList.size()) - 1);
-      engine = _firstList.back();
-      _firstList.pop_back();
+      std::erase(_firstList, engineItem.templateURL);
     } else {
-      DCHECK(path.row < static_cast<int>(_secondList.size()));
-
-      engine = _secondList[path.row];
-      // Mark as deleted by setting to nullptr.
-      _secondList[path.row] = nullptr;
-      ++removedItemsInSecondList;
+      std::erase(_secondList, engineItem.templateURL);
     }
     // If `engine` is selected as default search engine, reset the default
     // engine to the first prepopulated engine.
-    if (engine == _templateURLService->GetDefaultSearchProvider()) {
+    if (engineItem.templateURL ==
+        _templateURLService->GetDefaultSearchProvider()) {
       CHECK(!_shouldShowEEASettings, base::NotFatalUntil::M124);
       DCHECK(_firstList.size() > 0);
       _templateURLService->SetUserSelectedDefaultSearchProvider(_firstList[0]);
       resetDefaultEngine = true;
     }
-    _templateURLService->Remove(engine);
-  }
-
-  // Clean up the second list.
-  if (removedItemsInSecondList > 0) {
-    if (removedItemsInSecondList == _secondList.size()) {
-      _secondList.clear();
-    } else {
-      std::vector<TemplateURL*> newList(
-          _secondList.size() - removedItemsInSecondList, nullptr);
-      for (size_t i = 0, added = 0; i < _secondList.size(); ++i) {
-        if (_secondList[i]) {
-          newList[added++] = _secondList[i];
-        }
-      }
-      _secondList = std::move(newList);
-    }
+    _templateURLService->Remove(engineItem.templateURL);
   }
 
   // Update UI.
@@ -759,14 +740,18 @@
 - (void)updatePrepopulatedEnginesForEditing:(BOOL)editing {
   if (_settingsAreDismissed)
     return;
-  // All items in the first section should be updated. They are either
-  // a prepopulated search engine or a selected custom search engine.
+  // All prepopulated items in the first section should be updated.
+  // When `_shouldShowEEASettings` is YES, the selected custom item should
+  // be updated since the user is not allowed to remove it.
   NSArray<TableViewItem*>* items = [self.tableViewModel
       itemsInSectionWithIdentifier:SectionIdentifierFirstList];
   for (TableViewItem* item in items) {
     SettingsSearchEngineItem* engineItem =
         base::apple::ObjCCastStrict<SettingsSearchEngineItem>(item);
-    engineItem.enabled = !editing;
+    if (engineItem.type == ItemTypePrepopulatedEngine ||
+        _shouldShowEEASettings) {
+      engineItem.enabled = !editing;
+    }
     if (!editing && [self isItem:engineItem
                         equalForTemplateURL:_templateURLService
                                                 ->GetDefaultSearchProvider()]) {
diff --git a/ios/chrome/browser/ui/settings/search_engine_table_view_controller_eea_unittest.mm b/ios/chrome/browser/ui/settings/search_engine_table_view_controller_eea_unittest.mm
index df99fa241..4fbd12d 100644
--- a/ios/chrome/browser/ui/settings/search_engine_table_view_controller_eea_unittest.mm
+++ b/ios/chrome/browser/ui/settings/search_engine_table_view_controller_eea_unittest.mm
@@ -140,6 +140,20 @@
 
 // Tests that prepopulated engines are correctly displayed when enabling and
 // disabling edit mode.
+// The scenario:
+// + Add custom search engine C#1 as selected.
+// + Add custom search engine C#0.
+// + Test the custom search engine #1 is selected in section 0, at the top.
+// + Test the add button being enabled.
+// + Select the second search engine from the first section (so the first
+//   prepopulated search engine).
+// + Test the custom search engine #1 has been removed from the first section.
+// + Start edit mode.
+// + Test the 12 prepopulated search engine in the first section (disabled).
+// + Test the 2 custom search engine in the second section (enabled).
+// + Stop edit mode.
+// + Test the 12 prepopulated search engine in the first section (enabled).
+// + Test the 2 custom search engine in the second section (enabled).
 TEST_F(SearchEngineTableViewControllerEEATest, EditingMode) {
   AddCustomSearchEngine(custom_search_engine_[1],
                         base::Time::Now() - base::Minutes(10),
@@ -151,10 +165,13 @@
   CreateController();
   CheckController();
 
+  // Test that the first search engine of the first section is the custom search
+  // engine #1.
+  CheckCustomItem(custom_search_engine_[1], /*checked=*/true, /*section=*/0,
+                  /*row=*/0, /*enabled=*/true);
+
   SearchEngineTableViewController* searchEngineController =
       static_cast<SearchEngineTableViewController*>(controller());
-  // TODO(b/324052311): Need to add a test when there is only custom search
-  // engine and it is selected, the edit button should be disabled.
   EXPECT_TRUE([searchEngineController editButtonEnabled]);
 
   // Set the first prepopulated engine as default engine using
@@ -189,8 +206,10 @@
     CheckRealItem(urls_for_choice_screen[i].get(), /*checked=*/false,
                   /*section=*/0, /*row=*/i - 1);
   }
-  CheckCustomItem(custom_search_engine_[0], /*checked=*/false, 1, 0);
-  CheckCustomItem(custom_search_engine_[1], /*checked=*/false, 1, 1);
+  CheckCustomItem(custom_search_engine_[0], /*checked=*/false, /*section=*/1,
+                  /*row=*/0, /*enabled=*/true);
+  CheckCustomItem(custom_search_engine_[1], /*checked=*/false, /*section=*/1,
+                  /*row=*/1, /*enabled=*/true);
 }
 
 // Tests that custom search engines can be deleted, except it if is selected as
@@ -253,8 +272,88 @@
       ^{
         return NumberOfSections() == 1;
       }));
-  // TODO(b/324052311): Need to add a check that the edit button is disabled.
   ASSERT_TRUE(NumberOfItemsInSection(0) == number_of_prepopulated_items);
 }
 
+// Tests all prepopulated items and the selected custom search engine are
+// disabled when the table view is in edit mode.
+// Tests that all custom search engines not selected are enabled when the table
+// view is in edit mode.
+// The scenario:
+// + Add custom search engine C#0 and C#1 with C#0 selected.
+// + Test all items in section 0 (C#0 first, and the 12 prepopulated search
+//   engines).
+// + Test the C#1 in section 1.
+// + Start edit mode.
+// + Test all items disabled in section 0.
+// + Test the C#1 disabled in section 1.
+TEST_F(SearchEngineTableViewControllerEEATest,
+       EditModeWithCustomSearchEngineAsDefault) {
+  // Get all prepopulated search engines.
+  std::vector<std::unique_ptr<TemplateURL>> urls_for_choice_screen =
+      template_url_service_->GetTemplateURLsForChoiceScreen();
+  AddCustomSearchEngine(custom_search_engine_[0],
+                        base::Time::Now() - base::Seconds(10),
+                        /*default=*/true);
+  AddCustomSearchEngine(custom_search_engine_[1],
+                        base::Time::Now() - base::Minutes(10),
+                        /*default=*/false);
+  CreateController();
+  CheckController();
+  ASSERT_EQ(13, NumberOfItemsInSection(0));
+  ASSERT_EQ(1, NumberOfItemsInSection(1));
+  CheckCustomItem(custom_search_engine_[0], /*checked=*/true, /*section=*/0,
+                  /*row=*/0, /*enabled=*/true);
+  CheckCustomItem(custom_search_engine_[1], /*checked=*/false, /*section=*/1,
+                  /*row=*/0, /*enabled=*/true);
+  // Start edit mode.
+  [controller() setEditing:YES animated:NO];
+  CheckCustomItem(custom_search_engine_[0], /*checked=*/false, /*section=*/0,
+                  /*row=*/0, /*enabled=*/false);
+  CheckCustomItem(custom_search_engine_[1], /*checked=*/false, /*section=*/1,
+                  /*row=*/0, /*enabled=*/true);
+  for (size_t i = 0; i < urls_for_choice_screen.size(); i++) {
+    // Add +1 to the row, to skip C#0.
+    CheckRealItem(urls_for_choice_screen[i].get(), /*checked=*/false,
+                  /*section=*/0, /*row=*/i + 1, /*enabled=*/false);
+  }
+}
+
+// Test the edit button is disabled when having no custom search engine.
+TEST_F(SearchEngineTableViewControllerEEATest,
+       EditButtonWithNoCustomSearchEngine) {
+  CreateController();
+  CheckController();
+  SearchEngineTableViewController* searchEngineController =
+      static_cast<SearchEngineTableViewController*>(controller());
+  EXPECT_FALSE([searchEngineController editButtonEnabled]);
+}
+
+// Test the edit button is enabled when having one custom search engine.
+TEST_F(SearchEngineTableViewControllerEEATest,
+       EditButtonWithOneCustomSearchEngine) {
+  AddCustomSearchEngine(custom_search_engine_[0],
+                        base::Time::Now() - base::Seconds(10),
+                        /*default=*/false);
+  CreateController();
+  CheckController();
+  SearchEngineTableViewController* searchEngineController =
+      static_cast<SearchEngineTableViewController*>(controller());
+  EXPECT_TRUE([searchEngineController editButtonEnabled]);
+}
+
+// Test the edit button is disabled when having only one custom search engine,
+// and it is selected.
+TEST_F(SearchEngineTableViewControllerEEATest,
+       EditButtonWithSelectedCustomSearchEngine) {
+  AddCustomSearchEngine(custom_search_engine_[0],
+                        base::Time::Now() - base::Seconds(10),
+                        /*default=*/true);
+  CreateController();
+  CheckController();
+  SearchEngineTableViewController* searchEngineController =
+      static_cast<SearchEngineTableViewController*>(controller());
+  EXPECT_FALSE([searchEngineController editButtonEnabled]);
+}
+
 }  // namespace
diff --git a/ios/chrome/browser/ui/settings/search_engine_table_view_controller_non_eea_unittest.mm b/ios/chrome/browser/ui/settings/search_engine_table_view_controller_non_eea_unittest.mm
index 3875917..01883c0 100644
--- a/ios/chrome/browser/ui/settings/search_engine_table_view_controller_non_eea_unittest.mm
+++ b/ios/chrome/browser/ui/settings/search_engine_table_view_controller_non_eea_unittest.mm
@@ -250,10 +250,29 @@
 
 // Tests that prepopulated engines are disabled with checkmark removed in
 // editing mode, and that toolbar is displayed as expected.
+// The scenario:
+// + Add prepopulated search engine: P#2, P#0, P#1 (selected).
+// + Test the edit button is disabled.
+// + Add custom search engine: C#1, C#0.
+// + Test the edit button is enabled.
+// + Test all search engine in section 0 (all enabled, and P#1 selected).
+// + Enable edit mode.
+// + Test all prepopulated search engine (all disabled and unselected).
+// + Test all custom search engine (all enabled).
+// + Select custom search engine C#1.
+// + Test the edit button is enabled.
+// + Test the tool bar is visible.
+// + Unselect custom search engine C#1.
+// + Stop edit mode.
+// + Test all prepopulated search engine (all enabled and P#1 selected).
+// + Test all custom search engine (all enabled).
 TEST_F(SearchEngineTableViewControllerNonEEATest, EditingMode) {
-  AddPriorSearchEngine(prepopulated_search_engine_[2], 1003, false);
-  AddPriorSearchEngine(prepopulated_search_engine_[0], 1001, false);
-  AddPriorSearchEngine(prepopulated_search_engine_[1], 1002, true);
+  AddPriorSearchEngine(prepopulated_search_engine_[2], 1003,
+                       /*default=*/false);
+  AddPriorSearchEngine(prepopulated_search_engine_[0], 1001,
+                       /*default=*/false);
+  AddPriorSearchEngine(prepopulated_search_engine_[1], 1002,
+                       /*default=*/true);
 
   SearchEngineTableViewController* searchEngineController =
       static_cast<SearchEngineTableViewController*>(controller());
@@ -261,27 +280,37 @@
   // Edit button should be disabled since there is no custom engine.
   EXPECT_FALSE([searchEngineController editButtonEnabled]);
   AddCustomSearchEngine(custom_search_engine_[1],
-                        base::Time::Now() - base::Minutes(10), false);
+                        base::Time::Now() - base::Minutes(10),
+                        /*checked=*/false);
   AddCustomSearchEngine(custom_search_engine_[0],
-                        base::Time::Now() - base::Seconds(10), false);
+                        base::Time::Now() - base::Seconds(10),
+                        /*checked=*/false);
 
   EXPECT_TRUE([searchEngineController editButtonEnabled]);
-  CheckPrepopulatedItem(prepopulated_search_engine_[2], false, 0, 0);
-  CheckPrepopulatedItem(prepopulated_search_engine_[0], false, 0, 1);
-  CheckPrepopulatedItem(prepopulated_search_engine_[1], true, 0, 2);
-  CheckCustomItem(custom_search_engine_[0], false, 1, 0);
-  CheckCustomItem(custom_search_engine_[1], false, 1, 1);
-
+  CheckPrepopulatedItem(prepopulated_search_engine_[2], /*checked=*/false,
+                        /*section=*/0, /*row=*/0, /*enabled=*/true);
+  CheckPrepopulatedItem(prepopulated_search_engine_[0], /*checked=*/false,
+                        /*section=*/0, /*row=*/1, /*enabled=*/true);
+  CheckPrepopulatedItem(prepopulated_search_engine_[1], /*checked=*/true,
+                        /*section=*/0, /*row=*/2, /*enabled=*/true);
+  CheckCustomItem(custom_search_engine_[0], /*checked=*/false, /*section=*/1,
+                  /*row=*/0, /*enabled=*/true);
+  CheckCustomItem(custom_search_engine_[1], /*checked=*/false, /*section=*/1,
+                  /*row=*/1, /*enabled=*/true);
   [searchEngineController setEditing:YES animated:NO];
 
-  // Toolbar should not be displayed unless selection happens.
-  EXPECT_TRUE([searchEngineController editButtonEnabled]);
   // Prepopulated engines should be disabled with checkmark removed.
-  CheckPrepopulatedItem(prepopulated_search_engine_[2], false, 0, 0, false);
-  CheckPrepopulatedItem(prepopulated_search_engine_[0], false, 0, 1, false);
-  CheckPrepopulatedItem(prepopulated_search_engine_[1], false, 0, 2, false);
-  CheckCustomItem(custom_search_engine_[0], false, 1, 0);
-  CheckCustomItem(custom_search_engine_[1], false, 1, 1);
+  CheckPrepopulatedItem(prepopulated_search_engine_[2], /*checked=*/false,
+                        /*section=*/0, /*row=*/0, /*enabled=*/false);
+  CheckPrepopulatedItem(prepopulated_search_engine_[0], /*checked=*/false,
+                        /*section=*/0, /*row=*/1, /*enabled=*/false);
+  CheckPrepopulatedItem(prepopulated_search_engine_[1], /*checked=*/false,
+                        /*section=*/0, /*row=*/2, /*enabled=*/false);
+  // Custom engines should enabled.
+  CheckCustomItem(custom_search_engine_[0], /*checked=*/false, /*section=*/1,
+                  /*row=*/0, /*enabled=*/true);
+  CheckCustomItem(custom_search_engine_[1], /*checked=*/false, /*section=*/1,
+                  /*row=*/1, /*enabled=*/true);
 
   // Select custom engine C1.
   [controller().tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0
@@ -301,11 +330,16 @@
 
   EXPECT_TRUE([searchEngineController editButtonEnabled]);
 
-  CheckPrepopulatedItem(prepopulated_search_engine_[2], false, 0, 0);
-  CheckPrepopulatedItem(prepopulated_search_engine_[0], false, 0, 1);
-  CheckPrepopulatedItem(prepopulated_search_engine_[1], true, 0, 2);
-  CheckCustomItem(custom_search_engine_[0], false, 1, 0);
-  CheckCustomItem(custom_search_engine_[1], false, 1, 1);
+  CheckPrepopulatedItem(prepopulated_search_engine_[2], /*checked=*/false,
+                        /*section=*/0, /*row=*/0, /*enabled=*/true);
+  CheckPrepopulatedItem(prepopulated_search_engine_[0], /*checked=*/false,
+                        /*section=*/0, /*row=*/1, /*enabled=*/true);
+  CheckPrepopulatedItem(prepopulated_search_engine_[1], /*checked=*/true,
+                        /*section=*/0, /*row=*/2, /*enabled=*/true);
+  CheckCustomItem(custom_search_engine_[0], /*checked=*/false, /*section=*/1,
+                  /*row=*/0, /*enabled=*/true);
+  CheckCustomItem(custom_search_engine_[1], /*checked=*/false, /*section=*/1,
+                  /*row=*/1, /*enabled=*/true);
 }
 
 // Tests that custom search engines can be deleted, and if default engine is
@@ -377,4 +411,98 @@
   CheckPrepopulatedItem(prepopulated_search_engine_[1], false, 0, 2);
 }
 
+// Tests all prepopulated items and the selected custom search engine are
+// disabled when the table view is in edit mode.
+// Tests that all custom search engines are enabled when the table view is in
+// edit mode.
+// The scenario:
+// + Add prepopulated search engine P#0 and P#1.
+// + Add custom search engine C#0 and C#1 with C#1 selected.
+// + Test in section 0: P#0 and P#1 not selected, and C#1 selected
+// + Test in section 1: C#0 not selected.
+// + Start edit mode.
+// + Test in section 0: P#0 and P#1 disabled and C#1 enabled.
+// + Test in section 1: C#0 enabled.
+TEST_F(SearchEngineTableViewControllerNonEEATest,
+       EditModeWithCustomSearchEngineAsDefault) {
+  AddPriorSearchEngine(prepopulated_search_engine_[0], 1001,
+                       /*default=*/false);
+  AddPriorSearchEngine(prepopulated_search_engine_[1], 1002,
+                       /*default=*/false);
+  AddCustomSearchEngine(custom_search_engine_[0],
+                        base::Time::Now() - base::Seconds(10),
+                        /*default=*/false);
+  AddCustomSearchEngine(custom_search_engine_[1],
+                        base::Time::Now() - base::Minutes(10),
+                        /*default=*/true);
+  CreateController();
+  CheckController();
+  ASSERT_EQ(3, NumberOfItemsInSection(0));
+  ASSERT_EQ(1, NumberOfItemsInSection(1));
+  CheckPrepopulatedItem(prepopulated_search_engine_[0], /*checked=*/false,
+                        /*section=*/0, /*row=*/0, /*enabled=*/true);
+  CheckPrepopulatedItem(prepopulated_search_engine_[1], /*checked=*/false,
+                        /*section=*/0, /*row=*/1, /*enabled=*/true);
+  CheckCustomItem(custom_search_engine_[1], /*checked=*/true, /*section=*/0,
+                  /*row=*/2, /*enabled=*/true);
+  CheckCustomItem(custom_search_engine_[0], /*checked=*/false, /*section=*/1,
+                  /*row=*/0, /*enabled=*/true);
+  // Start edit mode.
+  [controller() setEditing:YES animated:NO];
+  CheckPrepopulatedItem(prepopulated_search_engine_[0], /*checked=*/false,
+                        /*section=*/0, /*row=*/0, /*enabled=*/false);
+  CheckPrepopulatedItem(prepopulated_search_engine_[1], /*checked=*/false,
+                        /*section=*/0, /*row=*/1, /*enabled=*/false);
+  CheckCustomItem(custom_search_engine_[1], /*checked=*/false, /*section=*/0,
+                  /*row=*/2, /*enabled=*/true);
+  CheckCustomItem(custom_search_engine_[0], /*checked=*/false, /*section=*/1,
+                  /*row=*/0, /*enabled=*/true);
+  // Select C4 as default engine by user interaction.
+  [controller() tableView:controller().tableView
+      didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
+}
+
+// Test the edit button is disabled when having no custom search engine.
+TEST_F(SearchEngineTableViewControllerNonEEATest,
+       EditButtonWithNoCustomSearchEngine) {
+  AddPriorSearchEngine(prepopulated_search_engine_[1], 1002,
+                       /*default=*/true);
+  CreateController();
+  CheckController();
+  SearchEngineTableViewController* searchEngineController =
+      static_cast<SearchEngineTableViewController*>(controller());
+  EXPECT_FALSE([searchEngineController editButtonEnabled]);
+}
+
+// Test the edit button is enabled when having one custom search engine.
+TEST_F(SearchEngineTableViewControllerNonEEATest,
+       EditButtonWithOneCustomSearchEngine) {
+  AddPriorSearchEngine(prepopulated_search_engine_[1], 1002,
+                       /*default=*/true);
+  AddCustomSearchEngine(custom_search_engine_[0],
+                        base::Time::Now() - base::Seconds(10),
+                        /*default=*/false);
+  CreateController();
+  CheckController();
+  SearchEngineTableViewController* searchEngineController =
+      static_cast<SearchEngineTableViewController*>(controller());
+  EXPECT_TRUE([searchEngineController editButtonEnabled]);
+}
+
+// Test the edit button is enabled when having only one custom search engine,
+// and it is selected.
+TEST_F(SearchEngineTableViewControllerNonEEATest,
+       EditButtonWithSelectedCustomSearchEngine) {
+  AddPriorSearchEngine(prepopulated_search_engine_[1], 1002,
+                       /*default=*/false);
+  AddCustomSearchEngine(custom_search_engine_[0],
+                        base::Time::Now() - base::Seconds(10),
+                        /*default=*/true);
+  CreateController();
+  CheckController();
+  SearchEngineTableViewController* searchEngineController =
+      static_cast<SearchEngineTableViewController*>(controller());
+  EXPECT_TRUE([searchEngineController editButtonEnabled]);
+}
+
 }  // namespace
diff --git a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
index 3f8c90b..7809197 100644
--- a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
+++ b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
@@ -751,7 +751,7 @@
     return;
   }
   DCHECK(!self.manageSyncSettingsCoordinator);
-  // TODO(crbug.com/1462552): Remove usage of HasSyncConsent() after kSync
+  // TODO(crbug.com/40066949): Remove usage of HasSyncConsent() after kSync
   // users migrated to kSignin in phase 3. See ConsentLevel::kSync
   // documentation for details.
   SyncSettingsAccountState accountState =
diff --git a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
index c7d1947..b9c65d7 100644
--- a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
@@ -1581,7 +1581,7 @@
 }
 
 - (BOOL)shouldReplaceSyncSettingsWithAccountSettings {
-  // TODO(crbug.com/1462552): Remove usage of HasSyncConsent() after kSync
+  // TODO(crbug.com/40066949): Remove usage of HasSyncConsent() after kSync
   // users migrated to kSignin in phase 3. See ConsentLevel::kSync
   // documentation for details.
   return base::FeatureList::IsEnabled(
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_mediator_unittest.mm b/ios/chrome/browser/ui/side_swipe/side_swipe_mediator_unittest.mm
index 23f3d8a..e4c5c86f 100644
--- a/ios/chrome/browser/ui/side_swipe/side_swipe_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/side_swipe/side_swipe_mediator_unittest.mm
@@ -165,9 +165,9 @@
   item->SetURL(GURL(kChromeUINewTabURL));
   // Insert the WebState and make sure it's active. This should trigger
   // the activation WebState change and update edge navigation state.
-  browser_->GetWebStateList()->InsertWebState(1, std::move(fake_web_state),
-                                              WebStateList::INSERT_ACTIVATE,
-                                              WebStateOpener());
+  browser_->GetWebStateList()->InsertWebState(
+      std::move(fake_web_state),
+      WebStateList::InsertionParams::AtIndex(1).Activate());
   EXPECT_TRUE(side_swipe_mediator_.leadingEdgeNavigationEnabled);
   EXPECT_TRUE(side_swipe_mediator_.trailingEdgeNavigationEnabled);
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm
index 46a71e1..bd6c275d 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm
@@ -1640,30 +1640,29 @@
   } else {
     cell.state = GridCellStateNotEditing;
   }
-  [item fetchFavicon:^(TabSwitcherItem* innerItem, UIImage* icon) {
-    // Only update the icon if the cell is not already reused for another item.
-    if (cell.itemIdentifier == innerItem.identifier) {
-      // TODO(crbug.com/1501837): Remove once the group color is available
-      // throught the group model. Keep for now for testing purposes.
-      cell.icon = icon;
-    }
-  }];
-
-  [item fetchSnapshot:^(TabSwitcherItem* innerItem, UIImage* snapshot) {
-    // Only update the icon if the cell is not already reused for another item.
-    if (cell.itemIdentifier == innerItem.identifier) {
-      GroupTabInfo* snapshotFavicon = [[GroupTabInfo alloc] init];
-      snapshotFavicon.snapshot = snapshot;
-      snapshotFavicon.favicon = snapshot;
-      // The `snapshotFavicon` is for demo purposes only, it will be replaced
-      // when the group tab model is available, the objects in `groupTabInfos`
-      // can be updated manually to view the different group tab configurations.
-      NSArray<GroupTabInfo*>* groupTabInfos = @[
-        snapshotFavicon, snapshotFavicon, snapshotFavicon, snapshotFavicon,
-        snapshotFavicon, snapshotFavicon, snapshotFavicon
-      ];
-      [cell configureWithGroupTabInfos:groupTabInfos totalTabsCount:101];
-    }
+  [item fetchFavicon:^(TabSwitcherItem* itemForFavicon, UIImage* favicon) {
+    [item fetchSnapshot:^(TabSwitcherItem* itemForSnapshot, UIImage* snapshot) {
+      // Only update the icon if the cell is not already reused for another
+      // item.
+      if (cell.itemIdentifier == itemForFavicon.identifier and
+          cell.itemIdentifier == itemForSnapshot.identifier) {
+        // TODO(crbug.com/1501837): Remove once the group color is available
+        // throught the group model. Keep for now for testing purposes.
+        cell.icon = favicon;
+        GroupTabInfo* snapshotFavicon = [[GroupTabInfo alloc] init];
+        snapshotFavicon.snapshot = snapshot;
+        snapshotFavicon.favicon = favicon;
+        // The `snapshotFavicon` is for demo purposes only, it will be replaced
+        // when the group tab model is available, the objects in `groupTabInfos`
+        // can be updated manually to view the different group tab
+        // configurations.
+        NSArray<GroupTabInfo*>* groupTabInfos = @[
+          snapshotFavicon, snapshotFavicon, snapshotFavicon, snapshotFavicon,
+          snapshotFavicon, snapshotFavicon
+        ];
+        [cell configureWithGroupTabInfos:groupTabInfos totalTabsCount:101];
+      }
+    }];
   }];
 
   cell.opacity = 1.0f;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_bottom_trailing_view.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_bottom_trailing_view.mm
index 894bddb..d6d3019 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_bottom_trailing_view.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_bottom_trailing_view.mm
@@ -61,7 +61,7 @@
 - (void)configureWithGroupTabInfo:(GroupTabInfo*)groupTabInfo {
   [self hideAllViews];
   [_mainSubview configureWithSnapshot:groupTabInfo.snapshot
-                              favicon:groupTabInfo.snapshot];
+                              favicon:groupTabInfo.favicon];
   _mainSubview.hidden = NO;
 }
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.mm
index ecb26d1..d5bb52b 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.mm
@@ -256,18 +256,17 @@
   int groupTabInfosLength = [groupTabInfos count];
   if (groupTabInfosLength > 0) {
     [_topLeadingSnapshotView configureWithSnapshot:groupTabInfos[0].snapshot
-                                           favicon:groupTabInfos[0].snapshot];
+                                           favicon:groupTabInfos[0].favicon];
     _topLeadingSnapshotView.hidden = NO;
   }
   if (groupTabInfosLength > 1) {
     [_topTrailingSnapshotView configureWithSnapshot:groupTabInfos[1].snapshot
-                                            favicon:groupTabInfos[1].snapshot];
+                                            favicon:groupTabInfos[1].favicon];
     _topTrailingSnapshotView.hidden = NO;
   }
   if (groupTabInfosLength > 2) {
-    [_bottomLeadingSnapshotView
-        configureWithSnapshot:groupTabInfos[2].snapshot
-                      favicon:groupTabInfos[2].snapshot];
+    [_bottomLeadingSnapshotView configureWithSnapshot:groupTabInfos[2].snapshot
+                                              favicon:groupTabInfos[2].favicon];
     _bottomLeadingSnapshotView.hidden = NO;
   }
   if (groupTabInfosLength == 4) {
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_tab_view.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_tab_view.mm
index c4b7efb21..87c45af 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_tab_view.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_tab_view.mm
@@ -15,6 +15,9 @@
 
 const CGFloat kFaviconViewScaleFactor = 0.6;
 const NSInteger kTabGridButtonFontSize = 14;
+const CGFloat kBottomFaviconViewWidthAndHeightAnchor = 24;
+const CGFloat kBottomFaviconBottomTrailingOffset = 4;
+const CGFloat kBottomFaviconViewScaleFactor = 0.75;
 
 }  // namespace
 
@@ -22,6 +25,13 @@
   // The view for the snapshot configuration.
   TopAlignedImageView* _snapshotFaviconView;
 
+  // The view to display the favicon in the bottom right of the
+  // `_snapshotFaviconView`.
+  UIView* _bottomFaviconView;
+
+  // The view that holds the favicon image.
+  UIImageView* _bottomFaviconImageView;
+
   // The views for favicon configuration.
   UIView* _faviconView;
   UIImageView* _faviconImageView;
@@ -43,6 +53,20 @@
     gradientView.translatesAutoresizingMaskIntoConstraints = NO;
     [_snapshotFaviconView addSubview:gradientView];
 
+    _bottomFaviconView = [[UIView alloc] init];
+    _bottomFaviconView.backgroundColor = [UIColor colorNamed:kBackgroundColor];
+    _bottomFaviconView.layer.cornerRadius =
+        kGroupGridBottomTrailingCellCornerRadius;
+    _bottomFaviconView.layer.masksToBounds = YES;
+    _bottomFaviconView.translatesAutoresizingMaskIntoConstraints = NO;
+
+    _bottomFaviconImageView = [[UIImageView alloc] init];
+    _bottomFaviconImageView.translatesAutoresizingMaskIntoConstraints = NO;
+    _bottomFaviconImageView.backgroundColor = [UIColor clearColor];
+    _bottomFaviconImageView.layer.cornerRadius =
+        kGroupGridFaviconViewCornerRadius;
+    _bottomFaviconImageView.contentMode = UIViewContentModeScaleAspectFit;
+
     _faviconView = [[UIView alloc] init];
     _faviconView.backgroundColor = [UIColor colorNamed:kBackgroundColor];
     _faviconView.layer.cornerRadius = kGroupGridBottomTrailingCellCornerRadius;
@@ -51,7 +75,6 @@
 
     _faviconImageView = [[UIImageView alloc] init];
     _faviconImageView.translatesAutoresizingMaskIntoConstraints = NO;
-    _faviconImageView.layer.masksToBounds = YES;
     _faviconImageView.backgroundColor = [UIColor clearColor];
     _faviconImageView.layer.cornerRadius = kGroupGridFaviconViewCornerRadius;
     _faviconImageView.contentMode = UIViewContentModeScaleAspectFill;
@@ -69,9 +92,12 @@
 
     [self hideAllAttributes];
 
+    [_bottomFaviconView addSubview:_bottomFaviconImageView];
+    [_snapshotFaviconView addSubview:_bottomFaviconView];
     [_faviconView addSubview:_faviconImageView];
     [_remainingTabsView addSubview:_remainingTabsLabel];
     [self addSubview:_snapshotFaviconView];
+
     [self addSubview:_faviconView];
     [self addSubview:_remainingTabsView];
 
@@ -82,6 +108,29 @@
     AddSameCenterConstraints(_faviconView, _remainingTabsLabel);
     AddSameCenterConstraints(_faviconView, _faviconImageView);
     NSArray* constraints = @[
+      [_bottomFaviconView.widthAnchor
+          constraintEqualToConstant:kBottomFaviconViewWidthAndHeightAnchor],
+      [_bottomFaviconView.heightAnchor
+          constraintEqualToConstant:kBottomFaviconViewWidthAndHeightAnchor],
+      [_bottomFaviconView.bottomAnchor
+          constraintEqualToAnchor:_snapshotFaviconView.bottomAnchor
+                         constant:-kBottomFaviconBottomTrailingOffset],
+      [_bottomFaviconView.trailingAnchor
+          constraintEqualToAnchor:_snapshotFaviconView.trailingAnchor
+                         constant:-kBottomFaviconBottomTrailingOffset],
+
+      [_bottomFaviconImageView.widthAnchor
+          constraintEqualToAnchor:_bottomFaviconView.widthAnchor
+                       multiplier:kBottomFaviconViewScaleFactor],
+      [_bottomFaviconImageView.heightAnchor
+          constraintEqualToAnchor:_bottomFaviconView.heightAnchor
+                       multiplier:kBottomFaviconViewScaleFactor],
+
+      [_bottomFaviconImageView.centerYAnchor
+          constraintEqualToAnchor:_bottomFaviconView.centerYAnchor],
+      [_bottomFaviconImageView.centerXAnchor
+          constraintEqualToAnchor:_bottomFaviconView.centerXAnchor],
+
       [_faviconImageView.widthAnchor
           constraintEqualToAnchor:_faviconView.widthAnchor
                        multiplier:kFaviconViewScaleFactor],
@@ -98,9 +147,10 @@
 - (void)configureWithSnapshot:(UIImage*)snapshot favicon:(UIImage*)favicon {
   [self hideAllAttributes];
   _snapshotFaviconView.image = snapshot;
+  _bottomFaviconImageView.image = favicon;
+  _bottomFaviconImageView.hidden = NO;
+  _bottomFaviconView.hidden = NO;
   _snapshotFaviconView.hidden = NO;
-  // TODO(crbug.com/1501837): Handle the favicon in the bottom right of the
-  // `_snapshotFaviconView`.
   return;
 }
 
@@ -126,6 +176,9 @@
 - (void)hideAllAttributes {
   _snapshotFaviconView.hidden = YES;
   _snapshotFaviconView.image = nil;
+  _bottomFaviconView.hidden = YES;
+  _bottomFaviconImageView.hidden = YES;
+  _bottomFaviconImageView.image = nil;
   _faviconView.hidden = YES;
   _faviconImageView.hidden = YES;
   _faviconImageView.image = nil;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/BUILD.gn
index 72a1678..8553f85c 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/BUILD.gn
+++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/BUILD.gn
@@ -34,6 +34,7 @@
   ]
   deps = [
     "//base",
+    "//ios/chrome/app/strings",
     "//ios/chrome/browser/shared/ui/symbols",
     "//ios/chrome/browser/shared/ui/util",
     "//ios/chrome/browser/shared/ui/util/image",
@@ -41,5 +42,6 @@
     "//ios/chrome/common/ui/elements",
     "//ios/chrome/common/ui/util",
     "//ios/third_party/material_components_ios",
+    "//ui/base",
   ]
 }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm
index d8bcd8e..6a6ab859 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_cell.mm
@@ -13,6 +13,8 @@
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/elements/gradient_view.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
+#import "ios/chrome/grit/ios_strings.h"
+#import "ui/base/l10n/l10n_util.h"
 
 namespace {
 
@@ -116,6 +118,10 @@
     contentView.layer.cornerRadius = kCornerSize;
     contentView.translatesAutoresizingMaskIntoConstraints = NO;
 
+    // Needed for the drop animation.
+    self.layer.cornerRadius = kCornerSize;
+    self.backgroundColor = [UIColor colorNamed:kTabStripBackgroundColor];
+
     _faviconView = [self createFaviconView];
     [contentView addSubview:_faviconView];
 
@@ -166,8 +172,9 @@
 }
 
 - (void)setTitle:(NSString*)title {
-  NSTextAlignment titleTextAligment = DetermineBestAlignmentForText(title);
+  self.accessibilityLabel = title;
 
+  NSTextAlignment titleTextAligment = DetermineBestAlignmentForText(title);
   _titleLabel.text = [title copy];
   _titleLabel.textAlignment = titleTextAligment;
   [self updateTitleGradientViewConstraints];
@@ -250,6 +257,9 @@
 - (void)setSelected:(BOOL)selected {
   [super setSelected:selected];
 
+  self.accessibilityTraits =
+      selected ? UIAccessibilityTraitSelected : UIAccessibilityTraitNone;
+
   if (selected) {
     /// The cell attributes is updated just after the cell selection.
     /// Hide separtors to avoid an animation glitch when selecting/inserting.
@@ -323,6 +333,21 @@
   [self updateColors];
 }
 
+#pragma mark - UIAccessibility
+
+- (BOOL)isAccessibilityElement {
+  // This makes the whole cell tappable in VoiceOver rather than the individual
+  // title and close button.
+  return YES;
+}
+
+- (NSArray*)accessibilityCustomActions {
+  return @[ [[UIAccessibilityCustomAction alloc]
+      initWithName:l10n_util::GetNSString(IDS_IOS_TAB_SWITCHER_CLOSE_TAB)
+            target:self
+          selector:@selector(closeButtonTapped:)] ];
+}
+
 #pragma mark - UIPointerInteractionDelegate
 
 - (UIPointerRegion*)pointerInteraction:(UIPointerInteraction*)interaction
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_layout.swift b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_layout.swift
index 438455a..ec872dd 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_layout.swift
+++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_layout.swift
@@ -162,6 +162,12 @@
     let isPreviousCellSelected = (indexPath.item - 1) == selectedIndexPath?.item
     cell.leadingSeparatorHidden = isPreviousCellSelected || !isScrollable
 
+    if UIAccessibility.isVoiceOverRunning {
+      // Prevent frame resizing while VoiceOver is active.
+      // This ensures swiping right/left goes to the next cell.
+      return layoutAttributes
+    }
+
     /// Recalculate the cell width and origin when it intersects with the left
     /// collection view's bounds. The cell should collapse within the collection
     /// view's bounds until its width reaches 0. Its `separatorHeight` is also
diff --git a/ios/chrome/browser/url_loading/model/url_loading_browser_agent_unittest.mm b/ios/chrome/browser/url_loading/model/url_loading_browser_agent_unittest.mm
index 3327b0d4..149c128 100644
--- a/ios/chrome/browser/url_loading/model/url_loading_browser_agent_unittest.mm
+++ b/ios/chrome/browser/url_loading/model/url_loading_browser_agent_unittest.mm
@@ -129,15 +129,13 @@
   std::unique_ptr<web::FakeWebState> web_state = CreateFakeWebState();
   web::WebState* web_state_ptr = web_state.get();
   web_state->SetCurrentURL(GURL("http://test/1"));
-  web_state_list->InsertWebState(std::move(web_state),
-                                 WebStateList::InsertionParams::AtIndex(0));
+  web_state_list->InsertWebState(std::move(web_state));
 
   std::unique_ptr<web::FakeWebState> web_state_2 = CreateFakeWebState();
   web::WebState* web_state_ptr_2 = web_state_2.get();
   GURL url("http://test/2");
   web_state_2->SetCurrentURL(url);
-  web_state_list->InsertWebState(std::move(web_state_2),
-                                 WebStateList::InsertionParams::AtIndex(1));
+  web_state_list->InsertWebState(std::move(web_state_2));
 
   web_state_list->ActivateWebStateAt(0);
 
@@ -158,9 +156,7 @@
   std::unique_ptr<web::FakeWebState> web_state = CreateFakeWebState();
   web::WebState* web_state_ptr = web_state.get();
   web_state->SetCurrentURL(GURL("chrome://newtab"));
-  web_state_list->InsertWebState(0, std::move(web_state),
-                                 WebStateList::INSERT_FORCE_INDEX,
-                                 WebStateOpener());
+  web_state_list->InsertWebState(std::move(web_state));
   id mock_delegate = OCMProtocolMock(@protocol(NewTabPageTabHelperDelegate));
   NewTabPageTabHelper::CreateForWebState(web_state_ptr);
   NewTabPageTabHelper::FromWebState(web_state_ptr)->SetDelegate(mock_delegate);
@@ -169,9 +165,7 @@
   web::WebState* web_state_ptr_2 = web_state_2.get();
   GURL url("http://test/2");
   web_state_2->SetCurrentURL(url);
-  web_state_list->InsertWebState(1, std::move(web_state_2),
-                                 WebStateList::INSERT_FORCE_INDEX,
-                                 WebStateOpener());
+  web_state_list->InsertWebState(std::move(web_state_2));
 
   web_state_list->ActivateWebStateAt(0);
 
@@ -193,9 +187,7 @@
   std::unique_ptr<web::FakeWebState> web_state = CreateFakeWebState();
   web_state->SetCurrentURL(GURL("chrome://newtab"));
   web::WebState* web_state_ptr = web_state.get();
-  web_state_list->InsertWebState(0, std::move(web_state),
-                                 WebStateList::INSERT_FORCE_INDEX,
-                                 WebStateOpener());
+  web_state_list->InsertWebState(std::move(web_state));
   web_state_list->ActivateWebStateAt(0);
   id mock_delegate = OCMProtocolMock(@protocol(NewTabPageTabHelperDelegate));
   NewTabPageTabHelper::CreateForWebState(web_state_ptr);
diff --git a/ios/chrome/test/app/signin_test_util.mm b/ios/chrome/test/app/signin_test_util.mm
index ec07e6f7..b4482bf 100644
--- a/ios/chrome/test/app/signin_test_util.mm
+++ b/ios/chrome/test/app/signin_test_util.mm
@@ -191,7 +191,7 @@
   // And the old global selected types for syncing users. SyncUserSettings::
   // SetSelectedTypes() CHECKs the user is signed-in, so go through SyncPrefs
   // directly.
-  // TODO(crbug.com/1462552): Remove once sync-the-feature is gone on iOS.
+  // TODO(crbug.com/40066949): Remove once sync-the-feature is gone on iOS.
   syncer::SyncPrefs(browser_state->GetPrefs())
       .SetSelectedTypesForSyncingUser(
           /*sync_everything=*/true,
diff --git a/ios_internal b/ios_internal
index 9a183ec..ee8bfec 160000
--- a/ios_internal
+++ b/ios_internal
@@ -1 +1 @@
-Subproject commit 9a183ec88b60cfbeef16ebd32e27a83f9a06126a
+Subproject commit ee8bfecb9125511f41a7f526b5d1cd83157622f1
diff --git a/media/gpu/chromeos/image_processor.cc b/media/gpu/chromeos/image_processor.cc
index da67d0d..c60a91f 100644
--- a/media/gpu/chromeos/image_processor.cc
+++ b/media/gpu/chromeos/image_processor.cc
@@ -60,6 +60,10 @@
 ImageProcessor::ClientCallback::ClientCallback(
     LegacyFrameReadyCB legacy_ready_cb)
     : legacy_ready_cb(std::move(legacy_ready_cb)) {}
+ImageProcessor::ClientCallback::ClientCallback(
+    LegacyFrameResourceReadyCB legacy_frame_resource_ready_cb)
+    : legacy_frame_resource_ready_cb(
+          std::move(legacy_frame_resource_ready_cb)) {}
 ImageProcessor::ClientCallback::ClientCallback(ClientCallback&&) = default;
 ImageProcessor::ClientCallback::~ClientCallback() = default;
 
@@ -296,6 +300,60 @@
   std::move(cb).Run(buffer_id, std::move(frame));
 }
 
+bool ImageProcessor::Process(scoped_refptr<FrameResource> frame,
+                             LegacyFrameResourceReadyCB cb) {
+  DVLOGF(4);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
+  DCHECK_EQ(output_mode(), OutputMode::ALLOCATE);
+
+  int cb_index = StoreCallback(std::move(cb));
+  auto ready_cb =
+      base::BindOnce(&ImageProcessor::OnProcessFrameResourceLegacyDoneThunk,
+                     client_task_runner_, weak_this_, cb_index);
+  backend_task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&ImageProcessorBackend::ProcessLegacyFrame,
+                                base::Unretained(backend_.get()),
+                                std::move(frame), std::move(ready_cb)));
+  return true;
+}
+
+// static
+void ImageProcessor::OnProcessFrameResourceLegacyDoneThunk(
+    scoped_refptr<base::SequencedTaskRunner> task_runner,
+    std::optional<base::WeakPtr<ImageProcessor>> weak_this,
+    int cb_index,
+    size_t buffer_id,
+    scoped_refptr<FrameResource> frame) {
+  DVLOGF(4);
+  DCHECK(weak_this);
+
+  task_runner->PostTask(
+      FROM_HERE,
+      base::BindOnce(&ImageProcessor::OnProcessFrameResourceLegacyDone,
+                     *weak_this, cb_index, buffer_id, std::move(frame)));
+}
+
+void ImageProcessor::OnProcessFrameResourceLegacyDone(
+    int cb_index,
+    size_t buffer_id,
+    scoped_refptr<FrameResource> frame) {
+  DVLOGF(4);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
+
+  auto it = pending_cbs_.find(cb_index);
+  // Skip if the callback is dropped by Reset().
+  if (it == pending_cbs_.end()) {
+    return;
+  }
+
+  DCHECK(it->second.legacy_frame_resource_ready_cb);
+  LegacyFrameResourceReadyCB cb =
+      std::move(it->second.legacy_frame_resource_ready_cb);
+  pending_cbs_.erase(it);
+
+  std::move(cb).Run(buffer_id, std::move(frame));
+}
+
 bool ImageProcessor::Reset() {
   DVLOGF(3);
   DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
diff --git a/media/gpu/chromeos/image_processor.h b/media/gpu/chromeos/image_processor.h
index f717851..85042930 100644
--- a/media/gpu/chromeos/image_processor.h
+++ b/media/gpu/chromeos/image_processor.h
@@ -49,7 +49,10 @@
   using ErrorCB = ImageProcessorBackend::ErrorCB;
   using FrameReadyCB = ImageProcessorBackend::FrameReadyCB;
   using FrameResourceReadyCB = ImageProcessorBackend::FrameResourceReadyCB;
+  // Legacy callbacks are used when allocation mode is ALLOCATE.
   using LegacyFrameReadyCB = ImageProcessorBackend::LegacyFrameReadyCB;
+  using LegacyFrameResourceReadyCB =
+      ImageProcessorBackend::LegacyFrameResourceReadyCB;
 
   // Callback type for creating a ImageProcessorBackend instance. This allows us
   // to create ImageProcessorBackend instance inside ImageProcessor::Create().
@@ -90,6 +93,10 @@
   // IMPORT mode for output.
   bool Process(scoped_refptr<VideoFrame> frame, LegacyFrameReadyCB cb);
 
+  // FrameResource version of legacy Process().
+  bool Process(scoped_refptr<FrameResource> frame,
+               LegacyFrameResourceReadyCB cb);
+
   // Called by client to process |input_frame| and store in |output_frame|. This
   // can only be used when output mode is IMPORT. The processor will drop all
   // its references to |input_frame| and |output_frame| after it finishes
@@ -134,12 +141,14 @@
     ClientCallback(FrameReadyCB ready_cb);
     ClientCallback(FrameResourceReadyCB frame_resource_ready_cb);
     ClientCallback(LegacyFrameReadyCB legacy_ready_cb);
+    ClientCallback(LegacyFrameResourceReadyCB legacy_frame_resource_ready_cb);
     ClientCallback(ClientCallback&&);
     ~ClientCallback();
 
     FrameReadyCB ready_cb;
     FrameResourceReadyCB frame_resource_ready_cb;
     LegacyFrameReadyCB legacy_ready_cb;
+    LegacyFrameResourceReadyCB legacy_frame_resource_ready_cb;
   };
 
   ImageProcessor(std::unique_ptr<ImageProcessorBackend> backend,
@@ -163,12 +172,21 @@
       int cb_index,
       size_t buffer_id,
       scoped_refptr<VideoFrame> frame);
+  static void OnProcessFrameResourceLegacyDoneThunk(
+      scoped_refptr<base::SequencedTaskRunner> task_runner,
+      std::optional<base::WeakPtr<ImageProcessor>> weak_this,
+      int cb_index,
+      size_t buffer_id,
+      scoped_refptr<FrameResource> frame);
   void OnProcessDone(int cb_index, scoped_refptr<VideoFrame> frame);
   void OnProcessFrameResourceDone(int cb_index,
                                   scoped_refptr<FrameResource> frame);
   void OnProcessLegacyDone(int cb_index,
                            size_t buffer_id,
                            scoped_refptr<VideoFrame> frame);
+  void OnProcessFrameResourceLegacyDone(int cb_index,
+                                        size_t buffer_id,
+                                        scoped_refptr<FrameResource> frame);
 
   // Store |cb| at |pending_cbs_| and return a index for the callback.
   int StoreCallback(ClientCallback cb);
diff --git a/media/gpu/chromeos/image_processor_backend.cc b/media/gpu/chromeos/image_processor_backend.cc
index 07e47164..0e3637b4 100644
--- a/media/gpu/chromeos/image_processor_backend.cc
+++ b/media/gpu/chromeos/image_processor_backend.cc
@@ -112,6 +112,14 @@
   NOTIMPLEMENTED();
 }
 
+void ImageProcessorBackend::ProcessLegacyFrame(
+    scoped_refptr<FrameResource> frame,
+    LegacyFrameResourceReadyCB cb) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
+
+  NOTIMPLEMENTED();
+}
+
 void ImageProcessorBackend::Reset() {
   DVLOGF(3);
   DCHECK_CALLED_ON_VALID_SEQUENCE(backend_sequence_checker_);
diff --git a/media/gpu/chromeos/image_processor_backend.h b/media/gpu/chromeos/image_processor_backend.h
index d90956d..f05ecc93 100644
--- a/media/gpu/chromeos/image_processor_backend.h
+++ b/media/gpu/chromeos/image_processor_backend.h
@@ -35,6 +35,9 @@
   // buffer.
   using LegacyFrameReadyCB =
       base::OnceCallback<void(size_t, scoped_refptr<VideoFrame>)>;
+  // FrameResource version of LegacyFrameReadyCB
+  using LegacyFrameResourceReadyCB =
+      base::OnceCallback<void(size_t, scoped_refptr<FrameResource>)>;
 
   // Callback for notifying client when error occurs.
   using ErrorCB = base::RepeatingClosure;
@@ -118,6 +121,15 @@
   virtual void ProcessLegacy(scoped_refptr<VideoFrame> frame,
                              LegacyFrameReadyCB cb);
 
+  // Process |frame| and store in in a ImageProcessor-owned output buffer. Only
+  // used when output mode is ALLOCATE. After processing, call |cb| with the
+  // buffer.
+  // If ALLOCATE mode is not supported, the implementation is optional. In this
+  // case, this method should not be called and the default implementation will
+  // panic.
+  virtual void ProcessLegacyFrame(scoped_refptr<FrameResource> frame,
+                                  LegacyFrameResourceReadyCB cb);
+
   // Drop all pending process requests. The default implementation is no-op.
   virtual void Reset();
 
diff --git a/media/gpu/command_buffer_helper.cc b/media/gpu/command_buffer_helper.cc
index b71d6d9..b72534b 100644
--- a/media/gpu/command_buffer_helper.cc
+++ b/media/gpu/command_buffer_helper.cc
@@ -190,14 +190,6 @@
     textures_.erase(service_id);
   }
 
-  void SetCleared(GLuint service_id) override {
-    DVLOG(2) << __func__ << "(" << service_id << ")";
-    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
-    DCHECK(textures_.count(service_id));
-    textures_[service_id]->SetCleared();
-  }
-
  private:
   gpu::Mailbox CreateLegacyMailbox(GLuint service_id) override {
     DVLOG(2) << __func__ << "(" << service_id << ")";
diff --git a/media/gpu/command_buffer_helper.h b/media/gpu/command_buffer_helper.h
index a2f7fa5..bb8f84ee 100644
--- a/media/gpu/command_buffer_helper.h
+++ b/media/gpu/command_buffer_helper.h
@@ -124,9 +124,6 @@
   // The context must be current.
   virtual void DestroyTexture(GLuint service_id) = 0;
 
-  // Sets the cleared flag on level 0 of the texture.
-  virtual void SetCleared(GLuint service_id) = 0;
-
   // Add a callback to be called when our stub is destroyed. This callback
   // may not change the current context.
   virtual void AddWillDestroyStubCB(WillDestroyStubCB callback) = 0;
diff --git a/media/gpu/ipc/service/picture_buffer_manager.cc b/media/gpu/ipc/service/picture_buffer_manager.cc
index 3c5ed07..c09d45e0 100644
--- a/media/gpu/ipc/service/picture_buffer_manager.cc
+++ b/media/gpu/ipc/service/picture_buffer_manager.cc
@@ -144,10 +144,8 @@
           DCHECK(service_id);
           picture_data.service_ids.push_back(service_id);
 
-          // The texture is not cleared yet, but it will be before the VDA
-          // outputs it. Rather than requiring output to happen on the GPU
-          // thread, mark the texture as cleared immediately.
-          command_buffer_helper_->SetCleared(service_id);
+          // NOTE: The texture is not cleared yet, but it will be before the VDA
+          // outputs it.
 
           // Generate a mailbox while we are still on the GPU thread.
           picture_data.mailbox_holders[j] = gpu::MailboxHolder(
diff --git a/media/gpu/test/fake_command_buffer_helper.cc b/media/gpu/test/fake_command_buffer_helper.cc
index 94d900a..2221cae 100644
--- a/media/gpu/test/fake_command_buffer_helper.cc
+++ b/media/gpu/test/fake_command_buffer_helper.cc
@@ -147,12 +147,6 @@
   service_ids_.erase(service_id);
 }
 
-void FakeCommandBufferHelper::SetCleared(GLuint service_id) {
-  DVLOG(2) << __func__;
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  DCHECK(service_ids_.count(service_id));
-}
-
 gpu::Mailbox FakeCommandBufferHelper::CreateLegacyMailbox(GLuint service_id) {
   DVLOG(2) << __func__ << "(" << service_id << ")";
   DCHECK(task_runner_->BelongsToCurrentThread());
diff --git a/media/gpu/test/fake_command_buffer_helper.h b/media/gpu/test/fake_command_buffer_helper.h
index 30a89f1..7383097 100644
--- a/media/gpu/test/fake_command_buffer_helper.h
+++ b/media/gpu/test/fake_command_buffer_helper.h
@@ -64,7 +64,6 @@
                        GLenum format,
                        GLenum type) override;
   void DestroyTexture(GLuint service_id) override;
-  void SetCleared(GLuint service_id) override;
   gpu::Mailbox CreateLegacyMailbox(GLuint service_id) override;
   void AddWillDestroyStubCB(WillDestroyStubCB callback) override;
   bool IsPassthrough() const override;
diff --git a/media/gpu/v4l2/v4l2_image_processor_backend.cc b/media/gpu/v4l2/v4l2_image_processor_backend.cc
index 51235809..940e78b 100644
--- a/media/gpu/v4l2/v4l2_image_processor_backend.cc
+++ b/media/gpu/v4l2/v4l2_image_processor_backend.cc
@@ -517,6 +517,25 @@
   ProcessJobs();
 }
 
+void V4L2ImageProcessorBackend::ProcessLegacyFrame(
+    scoped_refptr<FrameResource> frame,
+    LegacyFrameResourceReadyCB cb) {
+  DVLOGF(4) << "ts=" << frame->timestamp().InMilliseconds();
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  CHECK_EQ(output_memory_type_, V4L2_MEMORY_MMAP);
+
+  auto job_record = std::make_unique<JobRecord>();
+  job_record->input_frame = std::move(frame);
+  job_record->legacy_frame_ready_cb = std::move(cb);
+  if (MediaTraceIsEnabled()) {
+    job_record->start_time = base::TimeTicks::Now();
+  }
+
+  input_job_queue_.emplace(std::move(job_record));
+  ProcessJobs();
+}
+
 void V4L2ImageProcessorBackend::ProcessFrame(
     scoped_refptr<FrameResource> input_frame,
     scoped_refptr<FrameResource> output_frame,
@@ -875,6 +894,10 @@
           base::TimeTicks::Now(), "timestamp", timestamp.InMilliseconds());
     }
 
+    // At most of of |job_record->legacy_ready_cb| or
+    // |job_record->legacy_frame_ready_cb| should be set.
+    CHECK(job_record->legacy_ready_cb.is_null() ||
+          job_record->legacy_frame_ready_cb.is_null());
     if (!job_record->legacy_ready_cb.is_null()) {
       // Since the legacy API only supports a |output_memory_type_| of
       // V4L2_MEMORY_MMAP, |output_frame| is manufactured by a call to
@@ -887,6 +910,9 @@
       std::move(job_record->legacy_ready_cb)
           .Run(buffer->BufferId(),
                output_frame->AsVideoFrameResource()->GetMutableVideoFrame());
+    } else if (!job_record->legacy_frame_ready_cb.is_null()) {
+      std::move(job_record->legacy_frame_ready_cb)
+          .Run(buffer->BufferId(), std::move(output_frame));
     } else {
       std::move(job_record->ready_cb).Run(std::move(output_frame));
     }
diff --git a/media/gpu/v4l2/v4l2_image_processor_backend.h b/media/gpu/v4l2/v4l2_image_processor_backend.h
index 0e0d3c50..605cd0e 100644
--- a/media/gpu/v4l2/v4l2_image_processor_backend.h
+++ b/media/gpu/v4l2/v4l2_image_processor_backend.h
@@ -63,6 +63,8 @@
                     FrameResourceReadyCB cb) override;
   void ProcessLegacy(scoped_refptr<VideoFrame> frame,
                      LegacyFrameReadyCB cb) override;
+  void ProcessLegacyFrame(scoped_refptr<FrameResource> frame,
+                          LegacyFrameResourceReadyCB cb) override;
   void Reset() override;
 
   // Returns true if image processing is supported on this platform.
@@ -97,14 +99,16 @@
 
   // Job record. Jobs are processed in a FIFO order. |input_frame| will be
   // processed and the result written into |output_frame|. Once processing is
-  // complete, |ready_cb| or |legacy_ready_cb| will be called depending on which
-  // Process() method has been used to create that JobRecord.
+  // complete, |ready_cb|, |legacy_ready_cb|, or |legacy_frame_ready_cb| will be
+  // called depending on which Process() method has been used to create that
+  // JobRecord.
   struct JobRecord {
     JobRecord();
     ~JobRecord();
     scoped_refptr<FrameResource> input_frame;
     FrameResourceReadyCB ready_cb;
     LegacyFrameReadyCB legacy_ready_cb;
+    LegacyFrameResourceReadyCB legacy_frame_ready_cb;
     scoped_refptr<FrameResource> output_frame;
     size_t output_buffer_id;
 
diff --git a/net/android/network_library.cc b/net/android/network_library.cc
index fd81ded..d4ae0db 100644
--- a/net/android/network_library.cc
+++ b/net/android/network_library.cc
@@ -140,12 +140,12 @@
       base::android::AttachCurrentThread(), enabled);
 }
 
-absl::optional<int32_t> GetWifiSignalLevel() {
+std::optional<int32_t> GetWifiSignalLevel() {
   const int count_buckets = 5;
   int signal_strength = Java_AndroidNetworkLibrary_getWifiSignalLevel(
       base::android::AttachCurrentThread(), count_buckets);
   if (signal_strength < 0)
-    return absl::nullopt;
+    return std::nullopt;
   DCHECK_LE(0, signal_strength);
   DCHECK_GE(count_buckets - 1, signal_strength);
 
diff --git a/net/android/network_library.h b/net/android/network_library.h
index 7437793..51191c5 100644
--- a/net/android/network_library.h
+++ b/net/android/network_library.h
@@ -11,6 +11,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -22,7 +23,6 @@
 #include "net/base/net_export.h"
 #include "net/base/network_handle.h"
 #include "net/socket/socket_descriptor.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net::android {
 
@@ -90,7 +90,7 @@
 // Returns the signal strength level (between 0 and 4, both inclusive) of the
 // currently registered Wifi connection. If the value is unavailable, an
 // empty value is returned.
-NET_EXPORT_PRIVATE absl::optional<int32_t> GetWifiSignalLevel();
+NET_EXPORT_PRIVATE std::optional<int32_t> GetWifiSignalLevel();
 
 // Gets the DNS servers for the current default network and puts them in
 // `dns_servers`. Sets `dns_over_tls_active` and `dns_over_tls_hostname` based
diff --git a/net/android/network_library_unittest.cc b/net/android/network_library_unittest.cc
index 3abc5f8..b42ec05 100644
--- a/net/android/network_library_unittest.cc
+++ b/net/android/network_library_unittest.cc
@@ -24,7 +24,7 @@
 }
 
 TEST(NetworkLibraryTest, GetWifiSignalLevel) {
-  absl::optional<int32_t> signal_strength = android::GetWifiSignalLevel();
+  std::optional<int32_t> signal_strength = android::GetWifiSignalLevel();
   if (!signal_strength.has_value())
     return;
   EXPECT_LE(0, signal_strength.value());
diff --git a/net/cert/asn1_util.cc b/net/cert/asn1_util.cc
index 26de465..8d58f9a 100644
--- a/net/cert/asn1_util.cc
+++ b/net/cert/asn1_util.cc
@@ -4,9 +4,9 @@
 
 #include "net/cert/asn1_util.h"
 
+#include <optional>
 #include <string_view>
 
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/pki/input.h"
 #include "third_party/boringssl/src/pki/parse_certificate.h"
 #include "third_party/boringssl/src/pki/parser.h"
@@ -123,7 +123,7 @@
     return false;
   }
 
-  absl::optional<bssl::der::Input> extensions;
+  std::optional<bssl::der::Input> extensions;
   if (!tbs_cert_parser.ReadOptionalTag(
           bssl::der::kTagConstructed | bssl::der::kTagContextSpecific | 3,
           &extensions)) {
diff --git a/net/cert/cert_verify_proc.cc b/net/cert/cert_verify_proc.cc
index 2973634..41d24d7 100644
--- a/net/cert/cert_verify_proc.cc
+++ b/net/cert/cert_verify_proc.cc
@@ -285,9 +285,9 @@
     return false;
   }
 
-  absl::optional<bssl::SignatureAlgorithm> cert_algorithm =
+  std::optional<bssl::SignatureAlgorithm> cert_algorithm =
       bssl::ParseSignatureAlgorithm(bssl::der::Input(cert_algorithm_sequence));
-  absl::optional<bssl::SignatureAlgorithm> tbs_algorithm =
+  std::optional<bssl::SignatureAlgorithm> tbs_algorithm =
       bssl::ParseSignatureAlgorithm(bssl::der::Input(tbs_algorithm_sequence));
   if (!cert_algorithm || !tbs_algorithm || *cert_algorithm != *tbs_algorithm) {
     return false;
diff --git a/net/cert/cert_verify_proc.h b/net/cert/cert_verify_proc.h
index 7beed62..11cb71f 100644
--- a/net/cert/cert_verify_proc.h
+++ b/net/cert/cert_verify_proc.h
@@ -92,7 +92,7 @@
     std::vector<scoped_refptr<const net::CTLogVerifier>> ct_logs;
     scoped_refptr<net::CTPolicyEnforcer> ct_policy_enforcer;
 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
-    absl::optional<net::ChromeRootStoreData> root_store_data;
+    std::optional<net::ChromeRootStoreData> root_store_data;
 #endif
 #if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL)
     bool use_chrome_root_store;
diff --git a/net/cert/cert_verify_proc_builtin.cc b/net/cert/cert_verify_proc_builtin.cc
index 678c07e4..3251e7c3 100644
--- a/net/cert/cert_verify_proc_builtin.cc
+++ b/net/cert/cert_verify_proc_builtin.cc
@@ -5,6 +5,7 @@
 #include "net/cert/cert_verify_proc_builtin.h"
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <string_view>
 #include <vector>
@@ -35,7 +36,6 @@
 #include "net/cert/x509_util.h"
 #include "net/log/net_log_values.h"
 #include "net/log/net_log_with_source.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/pki/cert_errors.h"
 #include "third_party/boringssl/src/pki/cert_issuer_source_static.h"
 #include "third_party/boringssl/src/pki/common_cert_errors.h"
@@ -768,7 +768,7 @@
       digest_policy, flags, trust_store, ocsp_response, sct_list, ev_metadata,
       checked_revocation, deadline, net_log);
 
-  absl::optional<CertIssuerSourceAia> aia_cert_issuer_source;
+  std::optional<CertIssuerSourceAia> aia_cert_issuer_source;
 
   // Initialize the path builder.
   bssl::CertPathBuilder path_builder(
diff --git a/net/cert/cert_verify_proc_builtin_unittest.cc b/net/cert/cert_verify_proc_builtin_unittest.cc
index 2e6e00c..5770212 100644
--- a/net/cert/cert_verify_proc_builtin_unittest.cc
+++ b/net/cert/cert_verify_proc_builtin_unittest.cc
@@ -281,8 +281,8 @@
   GURL CreateAndServeCrl(EmbeddedTestServer* test_server,
                          CertBuilder* crl_issuer,
                          const std::vector<uint64_t>& revoked_serials,
-                         absl::optional<bssl::SignatureAlgorithm>
-                             signature_algorithm = absl::nullopt) {
+                         std::optional<bssl::SignatureAlgorithm>
+                             signature_algorithm = std::nullopt) {
     std::string crl = BuildCrl(crl_issuer->GetSubject(), crl_issuer->GetKey(),
                                revoked_serials, signature_algorithm);
     std::string crl_path = MakeRandomPath(".crl");
diff --git a/net/cert/cert_verify_proc_unittest.cc b/net/cert/cert_verify_proc_unittest.cc
index a998eda..071ef87 100644
--- a/net/cert/cert_verify_proc_unittest.cc
+++ b/net/cert/cert_verify_proc_unittest.cc
@@ -2853,8 +2853,8 @@
   // Returns the full URL to retrieve the CRL from the test server.
   GURL CreateAndServeCrl(CertBuilder* crl_issuer,
                          const std::vector<uint64_t>& revoked_serials,
-                         absl::optional<bssl::SignatureAlgorithm>
-                             signature_algorithm = absl::nullopt) {
+                         std::optional<bssl::SignatureAlgorithm>
+                             signature_algorithm = std::nullopt) {
     std::string crl = BuildCrl(crl_issuer->GetSubject(), crl_issuer->GetKey(),
                                revoked_serials, signature_algorithm);
     std::string crl_path = MakeRandomPath(".crl");
@@ -4302,7 +4302,7 @@
     static const char kPolicy3[] = "1.2.3.5";
     chain_[3]->SetPolicyConstraints(
         /*require_explicit_policy=*/0,
-        /*inhibit_policy_mapping=*/absl::nullopt);
+        /*inhibit_policy_mapping=*/std::nullopt);
     chain_[3]->SetCertificatePolicies({kPolicy1, kPolicy2});
     chain_[2]->SetCertificatePolicies({kPolicy3, kPolicy1});
     chain_[1]->SetCertificatePolicies({kPolicy1});
@@ -4334,7 +4334,7 @@
   // long, an explicit policy is never required.
   chain_[3]->SetPolicyConstraints(
       /*require_explicit_policy=*/4,
-      /*inhibit_policy_mapping=*/absl::nullopt);
+      /*inhibit_policy_mapping=*/std::nullopt);
 
   EXPECT_THAT(Verify(), IsOk());
   if (VerifyProcTypeIsBuiltin()) {
@@ -4348,7 +4348,7 @@
   // constraints are enforced.
   chain_[3]->SetPolicyConstraints(
       /*require_explicit_policy=*/3,
-      /*inhibit_policy_mapping=*/absl::nullopt);
+      /*inhibit_policy_mapping=*/std::nullopt);
 
   if (VerifyProcTypeIsBuiltin()) {
     EXPECT_THAT(Verify(), IsOk());
@@ -4368,7 +4368,7 @@
   // constraints are enforced.
   chain_[3]->SetPolicyConstraints(
       /*require_explicit_policy=*/2,
-      /*inhibit_policy_mapping=*/absl::nullopt);
+      /*inhibit_policy_mapping=*/std::nullopt);
 
   if (VerifyProcTypeIsBuiltin()) {
     EXPECT_THAT(Verify(), IsOk());
@@ -4395,7 +4395,7 @@
     static const char kPolicy3[] = "1.2.3.5";
     chain_[2]->SetPolicyConstraints(
         /*require_explicit_policy=*/0,
-        /*inhibit_policy_mapping=*/absl::nullopt);
+        /*inhibit_policy_mapping=*/std::nullopt);
     chain_[2]->SetCertificatePolicies({kPolicy1, kPolicy2});
     chain_[1]->SetCertificatePolicies({kPolicy3, kPolicy1});
 
@@ -4421,7 +4421,7 @@
   // |chain_[2]| is 3 certs long, an explicit policy is never required.
   chain_[2]->SetPolicyConstraints(
       /*require_explicit_policy=*/3,
-      /*inhibit_policy_mapping=*/absl::nullopt);
+      /*inhibit_policy_mapping=*/std::nullopt);
 
   EXPECT_THAT(Verify(), IsOk());
   if (VerifyProcTypeIsBuiltin()) {
@@ -4435,11 +4435,11 @@
   // should fail to verify.
   chain_[2]->SetPolicyConstraints(
       /*require_explicit_policy=*/2,
-      /*inhibit_policy_mapping=*/absl::nullopt);
+      /*inhibit_policy_mapping=*/std::nullopt);
 
-    EXPECT_THAT(Verify(), IsError(ExpectedIntermediateConstraintError()));
-    if (VerifyProcTypeIsBuiltin()) {
-      EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsError(ERR_CERT_INVALID));
+  EXPECT_THAT(Verify(), IsError(ExpectedIntermediateConstraintError()));
+  if (VerifyProcTypeIsBuiltin()) {
+    EXPECT_THAT(VerifyWithExpiryAndConstraints(), IsError(ERR_CERT_INVALID));
     }
 }
 
@@ -4449,7 +4449,7 @@
   // should fail to verify.
   chain_[2]->SetPolicyConstraints(
       /*require_explicit_policy=*/1,
-      /*inhibit_policy_mapping=*/absl::nullopt);
+      /*inhibit_policy_mapping=*/std::nullopt);
 
   EXPECT_THAT(Verify(), IsError(ExpectedIntermediateConstraintError()));
   if (VerifyProcTypeIsBuiltin()) {
@@ -4463,7 +4463,7 @@
   // and the final paragraph of 6.1.5)
   chain_[0]->SetPolicyConstraints(
       /*require_explicit_policy=*/0,
-      /*inhibit_policy_mapping=*/absl::nullopt);
+      /*inhibit_policy_mapping=*/std::nullopt);
 
   EXPECT_THAT(Verify(), IsError(ExpectedIntermediateConstraintError()));
 }
@@ -4474,14 +4474,14 @@
 
   // Root inhibits policy mapping immediately.
   chain_[3]->SetPolicyConstraints(
-      /*require_explicit_policy=*/absl::nullopt,
+      /*require_explicit_policy=*/std::nullopt,
       /*inhibit_policy_mapping=*/0);
 
   // Policy constraints are specified on an intermediate so that an explicit
   // policy will be required regardless if root constraints are applied.
   chain_[2]->SetPolicyConstraints(
       /*require_explicit_policy=*/0,
-      /*inhibit_policy_mapping=*/absl::nullopt);
+      /*inhibit_policy_mapping=*/std::nullopt);
 
   // Intermediate uses policy mappings. This should not be allowed if the root
   // constraints were enforced.
@@ -4510,14 +4510,14 @@
 
   // Root inhibits policy mapping after 1 cert.
   chain_[3]->SetPolicyConstraints(
-      /*require_explicit_policy=*/absl::nullopt,
+      /*require_explicit_policy=*/std::nullopt,
       /*inhibit_policy_mapping=*/1);
 
   // Policy constraints are specified on an intermediate so that an explicit
   // policy will be required regardless if root constraints are applied.
   chain_[2]->SetPolicyConstraints(
       /*require_explicit_policy=*/0,
-      /*inhibit_policy_mapping=*/absl::nullopt);
+      /*inhibit_policy_mapping=*/std::nullopt);
 
   // Intermediate uses policy mappings. This should be allowed even if the root
   // constraints were enforced, since policy mapping was allowed for 1 cert
@@ -4548,7 +4548,7 @@
   // policy will be required regardless if root constraints are applied.
   chain_[2]->SetPolicyConstraints(
       /*require_explicit_policy=*/0,
-      /*inhibit_policy_mapping=*/absl::nullopt);
+      /*inhibit_policy_mapping=*/std::nullopt);
 
   // This intermediate only asserts anyPolicy, so this chain should
   // be invalid if policyConstraints from the root cert are enforced.
@@ -4584,7 +4584,7 @@
     // policy will be required regardless if root constraints are applied.
     chain_[2]->SetPolicyConstraints(
         /*require_explicit_policy=*/0,
-        /*inhibit_policy_mapping=*/absl::nullopt);
+        /*inhibit_policy_mapping=*/std::nullopt);
 
     // AnyPolicy should be allowed in this cert.
     chain_[2]->SetCertificatePolicies({kAnyPolicy});
@@ -4624,7 +4624,7 @@
   chain_[2]->SetInhibitAnyPolicy(0);
   chain_[2]->SetPolicyConstraints(
       /*require_explicit_policy=*/0,
-      /*inhibit_policy_mapping=*/absl::nullopt);
+      /*inhibit_policy_mapping=*/std::nullopt);
 
   chain_[2]->SetCertificatePolicies({kAnyPolicy});
   // This shouldn't be allowed as the parent cert set inhibitAnyPolicy=0.
@@ -4641,7 +4641,7 @@
   chain_[2]->SetInhibitAnyPolicy(1);
   chain_[2]->SetPolicyConstraints(
       /*require_explicit_policy=*/0,
-      /*inhibit_policy_mapping=*/absl::nullopt);
+      /*inhibit_policy_mapping=*/std::nullopt);
 
   chain_[2]->SetCertificatePolicies({kAnyPolicy});
   // This is okay as the parent cert set inhibitAnyPolicy=1.
@@ -4672,7 +4672,7 @@
     // policy will be required regardless if root constraints are applied.
     chain_[2]->SetPolicyConstraints(
         /*require_explicit_policy=*/0,
-        /*inhibit_policy_mapping=*/absl::nullopt);
+        /*inhibit_policy_mapping=*/std::nullopt);
 
     chain_[2]->SetCertificatePolicies({kPolicy1});
     chain_[1]->SetCertificatePolicies({kPolicy1});
@@ -4724,7 +4724,7 @@
     // policy will be required regardless if root constraints are applied.
     chain_[2]->SetPolicyConstraints(
         /*require_explicit_policy=*/0,
-        /*inhibit_policy_mapping=*/absl::nullopt);
+        /*inhibit_policy_mapping=*/std::nullopt);
 
     chain_[2]->SetCertificatePolicies({kPolicy2});
     chain_[1]->SetCertificatePolicies({kPolicy2});
@@ -5129,7 +5129,7 @@
 
     chain_[0]->SetPolicyConstraints(
         /*require_explicit_policy=*/0,
-        /*inhibit_policy_mapping=*/absl::nullopt);
+        /*inhibit_policy_mapping=*/std::nullopt);
     if (leaf_has_policy) {
       chain_[0]->SetCertificatePolicies({kPolicy1});
     } else {
@@ -5151,7 +5151,7 @@
   static const char kAnyPolicy[] = "2.5.29.32.0";
   chain_[0]->SetPolicyConstraints(
       /*require_explicit_policy=*/0,
-      /*inhibit_policy_mapping=*/absl::nullopt);
+      /*inhibit_policy_mapping=*/std::nullopt);
   chain_[0]->SetInhibitAnyPolicy(0);
   chain_[0]->SetCertificatePolicies({kAnyPolicy});
 
@@ -5402,7 +5402,7 @@
 
     cert_->SetPolicyConstraints(
         /*require_explicit_policy=*/0,
-        /*inhibit_policy_mapping=*/absl::nullopt);
+        /*inhibit_policy_mapping=*/std::nullopt);
     if (leaf_has_policy) {
       cert_->SetCertificatePolicies({kPolicy1});
 
@@ -5424,7 +5424,7 @@
   static const char kAnyPolicy[] = "2.5.29.32.0";
   cert_->SetPolicyConstraints(
       /*require_explicit_policy=*/0,
-      /*inhibit_policy_mapping=*/absl::nullopt);
+      /*inhibit_policy_mapping=*/std::nullopt);
   cert_->SetInhibitAnyPolicy(0);
   cert_->SetCertificatePolicies({kAnyPolicy});
 
diff --git a/net/cert/crl_set.cc b/net/cert/crl_set.cc
index e0c1e470..879477f 100644
--- a/net/cert/crl_set.cc
+++ b/net/cert/crl_set.cc
@@ -54,26 +54,26 @@
 // ReadHeader reads the header (including length prefix) from |data| and
 // updates |data| to remove the header on return. Caller takes ownership of the
 // returned pointer.
-absl::optional<base::Value> ReadHeader(std::string_view* data) {
+std::optional<base::Value> ReadHeader(std::string_view* data) {
   uint16_t header_len;
   if (data->size() < sizeof(header_len)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   // Assumes little-endian.
   memcpy(&header_len, data->data(), sizeof(header_len));
   data->remove_prefix(sizeof(header_len));
 
   if (data->size() < header_len) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   const std::string_view header_bytes = data->substr(0, header_len);
   data->remove_prefix(header_len);
 
-  absl::optional<base::Value> header =
+  std::optional<base::Value> header =
       base::JSONReader::Read(header_bytes, base::JSON_ALLOW_TRAILING_COMMAS);
   if (!header || !header->is_dict()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return header;
@@ -215,7 +215,7 @@
 #error assumes little endian
 #endif
 
-  absl::optional<base::Value> header_value = ReadHeader(&data);
+  std::optional<base::Value> header_value = ReadHeader(&data);
   if (!header_value) {
     return false;
   }
@@ -229,7 +229,7 @@
   if (header_dict.FindInt("Version") != kCurrentFileVersion)
     return false;
 
-  absl::optional<int> sequence = header_dict.FindInt("Sequence");
+  std::optional<int> sequence = header_dict.FindInt("Sequence");
   if (!sequence)
     return false;
 
diff --git a/net/cert/ct_log_response_parser_unittest.cc b/net/cert/ct_log_response_parser_unittest.cc
index 79ae4df..383eb84 100644
--- a/net/cert/ct_log_response_parser_unittest.cc
+++ b/net/cert/ct_log_response_parser_unittest.cc
@@ -20,7 +20,7 @@
 namespace net::ct {
 
 TEST(CTLogResponseParserTest, ParsesValidJsonSTH) {
-  absl::optional<base::Value> sample_sth_json =
+  std::optional<base::Value> sample_sth_json =
       base::JSONReader::Read(GetSampleSTHAsJson());
   SignedTreeHead tree_head;
   EXPECT_TRUE(FillSignedTreeHead(*sample_sth_json, &tree_head));
@@ -51,14 +51,14 @@
 }
 
 TEST(CTLogResponseParserTest, FailsToParseMissingFields) {
-  absl::optional<base::Value> missing_signature_sth = base::JSONReader::Read(
+  std::optional<base::Value> missing_signature_sth = base::JSONReader::Read(
       CreateSignedTreeHeadJsonString(1 /* tree_size */, 123456u /* timestamp */,
                                      GetSampleSTHSHA256RootHash(), ""));
 
   SignedTreeHead tree_head;
   ASSERT_FALSE(FillSignedTreeHead(*missing_signature_sth, &tree_head));
 
-  absl::optional<base::Value> missing_root_hash_sth = base::JSONReader::Read(
+  std::optional<base::Value> missing_root_hash_sth = base::JSONReader::Read(
       CreateSignedTreeHeadJsonString(1 /* tree_size */, 123456u /* timestamp */,
                                      "", GetSampleSTHTreeHeadSignature()));
   ASSERT_FALSE(FillSignedTreeHead(*missing_root_hash_sth, &tree_head));
@@ -71,7 +71,7 @@
   base::Base64Decode(
       std::string_view("/WHFMgXtI/umKKuACJIN0Bb73TcILm9WkeU6qszvoArK\n"),
       &too_long_hash);
-  absl::optional<base::Value> too_long_hash_json =
+  std::optional<base::Value> too_long_hash_json =
       base::JSONReader::Read(CreateSignedTreeHeadJsonString(
           1 /* tree_size */, 123456u /* timestamp */,
           GetSampleSTHSHA256RootHash(), too_long_hash));
@@ -81,7 +81,7 @@
   base::Base64Decode(
       std::string_view("/WHFMgXtI/umKKuACJIN0Bb73TcILm9WkeU6qszvoA==\n"),
       &too_short_hash);
-  absl::optional<base::Value> too_short_hash_json =
+  std::optional<base::Value> too_short_hash_json =
       base::JSONReader::Read(CreateSignedTreeHeadJsonString(
           1 /* tree_size */, 123456u /* timestamp */,
           GetSampleSTHSHA256RootHash(), too_short_hash));
@@ -91,7 +91,7 @@
 TEST(CTLogResponseParserTest, ParsesJsonSTHWithLargeTimestamp) {
   SignedTreeHead tree_head;
 
-  absl::optional<base::Value> large_timestamp_json =
+  std::optional<base::Value> large_timestamp_json =
       base::JSONReader::Read(CreateSignedTreeHeadJsonString(
           100, INT64_C(1) << 34, GetSampleSTHSHA256RootHash(),
           GetSampleSTHTreeHeadSignature()));
@@ -113,7 +113,7 @@
   raw_nodes.push_back(first);
   raw_nodes.push_back(second);
   raw_nodes.push_back(third);
-  absl::optional<base::Value> sample_consistency_proof =
+  std::optional<base::Value> sample_consistency_proof =
       base::JSONReader::Read(CreateConsistencyProofJsonString(raw_nodes));
 
   std::vector<std::string> output;
@@ -128,19 +128,19 @@
 TEST(CTLogResponseParserTest, FailsOnInvalidProofJson) {
   std::vector<std::string> output;
 
-  absl::optional<base::Value> badly_encoded =
+  std::optional<base::Value> badly_encoded =
       base::JSONReader::Read(std::string("{\"consistency\": [\"notbase64\"]}"));
   EXPECT_FALSE(FillConsistencyProof(*badly_encoded, &output));
 
-  absl::optional<base::Value> not_a_string =
+  std::optional<base::Value> not_a_string =
       base::JSONReader::Read(std::string("{\"consistency\": [42, 16]}"));
   EXPECT_FALSE(FillConsistencyProof(*badly_encoded, &output));
 
-  absl::optional<base::Value> missing_consistency =
+  std::optional<base::Value> missing_consistency =
       base::JSONReader::Read(std::string("{}"));
   EXPECT_FALSE(FillConsistencyProof(*missing_consistency, &output));
 
-  absl::optional<base::Value> not_a_dict =
+  std::optional<base::Value> not_a_dict =
       base::JSONReader::Read(std::string("[]"));
   EXPECT_FALSE(FillConsistencyProof(*not_a_dict, &output));
 }
@@ -148,7 +148,7 @@
 TEST(CTLogResponseParserTest, ParsesProofJsonWithExtraFields) {
   std::vector<std::string> output;
 
-  absl::optional<base::Value> badly_encoded = base::JSONReader::Read(
+  std::optional<base::Value> badly_encoded = base::JSONReader::Read(
       std::string("{\"consistency\": [], \"somethingelse\": 3}"));
   EXPECT_TRUE(FillConsistencyProof(*badly_encoded, &output));
 }
diff --git a/net/cert/internal/revocation_checker.cc b/net/cert/internal/revocation_checker.cc
index 352a4c51..f6efa5ab 100644
--- a/net/cert/internal/revocation_checker.cc
+++ b/net/cert/internal/revocation_checker.cc
@@ -4,13 +4,13 @@
 
 #include "net/cert/internal/revocation_checker.h"
 
+#include <optional>
 #include <string>
 #include <string_view>
 
 #include "base/logging.h"
 #include "crypto/sha2.h"
 #include "net/cert/cert_net_fetcher.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/pki/common_cert_errors.h"
 #include "third_party/boringssl/src/pki/crl.h"
 #include "third_party/boringssl/src/pki/ocsp.h"
@@ -39,7 +39,7 @@
                          const RevocationPolicy& policy,
                          base::TimeTicks deadline,
                          std::string_view stapled_ocsp_response,
-                         absl::optional<int64_t> max_age_seconds,
+                         std::optional<int64_t> max_age_seconds,
                          CertNetFetcher* net_fetcher,
                          bssl::CertErrors* cert_errors,
                          bssl::OCSPVerifyResult* stapled_ocsp_verify_result) {
@@ -110,7 +110,7 @@
 
       // TODO(eroman): Duplication of work if there are multiple URLs to try.
       // TODO(eroman): Are there cases where we would need to POST instead?
-      absl::optional<std::string> get_url_str =
+      std::optional<std::string> get_url_str =
           CreateOCSPGetURL(cert, issuer_cert, ocsp_uri);
       if (!get_url_str.has_value()) {
         // An unexpected failure from BoringSSL, or the input was too large to
@@ -308,7 +308,7 @@
     std::string_view stapled_ocsp =
         (i == 0) ? stapled_leaf_ocsp_response : std::string_view();
 
-    absl::optional<int64_t> max_age_seconds;
+    std::optional<int64_t> max_age_seconds;
     if (policy.enforce_baseline_requirements) {
       max_age_seconds = ((i == 0) ? kMaxRevocationLeafUpdateAge
                                   : kMaxRevocationIntermediateUpdateAge)
diff --git a/net/cert/internal/trust_store_chrome.cc b/net/cert/internal/trust_store_chrome.cc
index 9137ca1..5b2cd42 100644
--- a/net/cert/internal/trust_store_chrome.cc
+++ b/net/cert/internal/trust_store_chrome.cc
@@ -3,13 +3,15 @@
 // found in the LICENSE file.
 
 #include "net/cert/internal/trust_store_chrome.h"
+
+#include <optional>
+
 #include "base/containers/span.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "net/cert/root_store_proto_lite/root_store.pb.h"
 #include "net/cert/x509_certificate.h"
 #include "net/cert/x509_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/include/openssl/pool.h"
 #include "third_party/boringssl/src/pki/cert_errors.h"
 #include "third_party/boringssl/src/pki/parsed_certificate.h"
@@ -32,7 +34,7 @@
 ChromeRootStoreData& ChromeRootStoreData::operator=(
     ChromeRootStoreData&& other) = default;
 
-absl::optional<ChromeRootStoreData>
+std::optional<ChromeRootStoreData>
 ChromeRootStoreData::CreateChromeRootStoreData(
     const chrome_root_store::RootStore& proto) {
   ChromeRootStoreData root_store_data;
@@ -40,7 +42,7 @@
   for (auto& anchor : proto.trust_anchors()) {
     if (anchor.der().empty()) {
       LOG(ERROR) << "Error anchor with empty DER in update";
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     auto parsed = bssl::ParsedCertificate::Create(
@@ -48,7 +50,7 @@
         net::x509_util::DefaultParseCertificateOptions(), nullptr);
     if (!parsed) {
       LOG(ERROR) << "Error parsing cert for update";
-      return absl::nullopt;
+      return std::nullopt;
     }
     root_store_data.anchors_.push_back(std::move(parsed));
   }
diff --git a/net/cert/internal/trust_store_chrome.h b/net/cert/internal/trust_store_chrome.h
index 3a7d455..03d2a37 100644
--- a/net/cert/internal/trust_store_chrome.h
+++ b/net/cert/internal/trust_store_chrome.h
@@ -5,10 +5,11 @@
 #ifndef NET_CERT_INTERNAL_TRUST_STORE_CHROME_H_
 #define NET_CERT_INTERNAL_TRUST_STORE_CHROME_H_
 
+#include <optional>
+
 #include "base/containers/span.h"
 #include "net/base/net_export.h"
 #include "net/cert/root_store_proto_lite/root_store.pb.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/pki/trust_store.h"
 #include "third_party/boringssl/src/pki/trust_store_in_memory.h"
 
@@ -23,9 +24,9 @@
 class NET_EXPORT ChromeRootStoreData {
  public:
   // CreateChromeRootStoreData converts |proto| into a usable
-  // ChromeRootStoreData object. Returns absl::nullopt if the passed in
+  // ChromeRootStoreData object. Returns std::nullopt if the passed in
   // proto has errors in it (e.g. an unparsable DER-encoded certificate).
-  static absl::optional<ChromeRootStoreData> CreateChromeRootStoreData(
+  static std::optional<ChromeRootStoreData> CreateChromeRootStoreData(
       const chrome_root_store::RootStore& proto);
   ~ChromeRootStoreData();
 
diff --git a/net/cert/internal/trust_store_nss_unittest.cc b/net/cert/internal/trust_store_nss_unittest.cc
index fceb7868..994dbb3 100644
--- a/net/cert/internal/trust_store_nss_unittest.cc
+++ b/net/cert/internal/trust_store_nss_unittest.cc
@@ -64,7 +64,7 @@
       x509_util::DefaultParseCertificateOptions(), &parsing_errors);
 }
 
-absl::optional<unsigned> GetNSSTrustForCert(
+std::optional<unsigned> GetNSSTrustForCert(
     const bssl::ParsedCertificate* cert) {
   SECItem der_cert;
   der_cert.data = const_cast<uint8_t*>(cert->der_cert().data());
@@ -73,12 +73,12 @@
   ScopedCERTCertificate nss_cert(
       CERT_FindCertByDERCert(CERT_GetDefaultCertDB(), &der_cert));
   if (!nss_cert) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   CERTCertTrust nss_cert_trust;
   if (CERT_GetCertTrust(nss_cert.get(), &nss_cert_trust) != SECSuccess) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return SEC_GET_TRUST_FLAGS(&nss_cert_trust, trustSSL);
diff --git a/net/cookies/canonical_cookie.cc b/net/cookies/canonical_cookie.cc
index ec55013..fb0fe287 100644
--- a/net/cookies/canonical_cookie.cc
+++ b/net/cookies/canonical_cookie.cc
@@ -45,6 +45,7 @@
 #include "net/cookies/canonical_cookie.h"
 
 #include <limits>
+#include <optional>
 #include <utility>
 
 #include "base/containers/contains.h"
@@ -67,7 +68,6 @@
 #include "net/cookies/cookie_util.h"
 #include "net/cookies/parsed_cookie.h"
 #include "net/http/http_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/url_canon.h"
 #include "url/url_util.h"
@@ -393,7 +393,7 @@
     bool httponly,
     CookieSameSite same_site,
     CookiePriority priority,
-    absl::optional<CookiePartitionKey> partition_key,
+    std::optional<CookiePartitionKey> partition_key,
     CookieSourceScheme source_scheme,
     int source_port)
     : name_(std::move(name)),
@@ -556,8 +556,8 @@
     const GURL& url,
     const std::string& cookie_line,
     const base::Time& creation_time,
-    absl::optional<base::Time> server_time,
-    absl::optional<CookiePartitionKey> cookie_partition_key,
+    std::optional<base::Time> server_time,
+    std::optional<CookiePartitionKey> cookie_partition_key,
     bool block_truncated,
     CookieInclusionStatus* status) {
   // Put a pointer on the stack so the rest of the function can assign to it if
@@ -655,7 +655,7 @@
     if (!partition_has_nonce)
       UMA_HISTOGRAM_BOOLEAN("Cookie.IsPartitionedValid", is_partitioned_valid);
   } else if (!partition_has_nonce) {
-    cookie_partition_key = absl::nullopt;
+    cookie_partition_key = std::nullopt;
   }
 
   if (!status->IsInclude())
@@ -762,7 +762,7 @@
     bool http_only,
     CookieSameSite same_site,
     CookiePriority priority,
-    absl::optional<CookiePartitionKey> partition_key,
+    std::optional<CookiePartitionKey> partition_key,
     CookieInclusionStatus* status) {
   // Put a pointer on the stack so the rest of the function can assign to it if
   // the default nullptr is passed in.
@@ -951,7 +951,7 @@
     bool httponly,
     CookieSameSite same_site,
     CookiePriority priority,
-    absl::optional<CookiePartitionKey> partition_key,
+    std::optional<CookiePartitionKey> partition_key,
     CookieSourceScheme source_scheme,
     int source_port) {
   // We check source_port here because it could have concievably been
@@ -996,7 +996,7 @@
     bool httponly,
     CookieSameSite same_site,
     CookiePriority priority,
-    absl::optional<CookiePartitionKey> partition_key,
+    std::optional<CookiePartitionKey> partition_key,
     CookieSourceScheme source_scheme,
     int source_port) {
   return std::make_unique<CanonicalCookie>(
@@ -1025,13 +1025,13 @@
 }
 
 CanonicalCookie::UniqueCookieKey CanonicalCookie::UniqueKey() const {
-  absl::optional<CookieSourceScheme> source_scheme =
+  std::optional<CookieSourceScheme> source_scheme =
       cookie_util::IsSchemeBoundCookiesEnabled()
-          ? absl::make_optional(source_scheme_)
-          : absl::nullopt;
-  absl::optional<int> source_port = cookie_util::IsPortBoundCookiesEnabled()
-                                        ? absl::make_optional(source_port_)
-                                        : absl::nullopt;
+          ? std::make_optional(source_scheme_)
+          : std::nullopt;
+  std::optional<int> source_port = cookie_util::IsPortBoundCookiesEnabled()
+                                       ? std::make_optional(source_port_)
+                                       : std::nullopt;
 
   return std::make_tuple(partition_key_, name_, domain_, path_, source_scheme,
                          source_port);
@@ -1039,10 +1039,10 @@
 
 CanonicalCookie::UniqueDomainCookieKey CanonicalCookie::UniqueDomainKey()
     const {
-  absl::optional<CookieSourceScheme> source_scheme =
+  std::optional<CookieSourceScheme> source_scheme =
       cookie_util::IsSchemeBoundCookiesEnabled()
-          ? absl::make_optional(source_scheme_)
-          : absl::nullopt;
+          ? std::make_optional(source_scheme_)
+          : std::nullopt;
 
   return std::make_tuple(partition_key_, name_, domain_, path_, source_scheme);
 }
@@ -1313,7 +1313,7 @@
     const CookieOptions& options,
     const CookieAccessParams& params,
     const std::vector<std::string>& cookieable_schemes,
-    const absl::optional<CookieAccessResult>& cookie_access_result) const {
+    const std::optional<CookieAccessResult>& cookie_access_result) const {
   CookieAccessResult access_result;
   if (cookie_access_result) {
     access_result = *cookie_access_result;
@@ -1815,7 +1815,7 @@
 CookieAndLineWithAccessResult::CookieAndLineWithAccessResult() = default;
 
 CookieAndLineWithAccessResult::CookieAndLineWithAccessResult(
-    absl::optional<CanonicalCookie> cookie,
+    std::optional<CanonicalCookie> cookie,
     std::string cookie_string,
     CookieAccessResult access_result)
     : cookie(std::move(cookie)),
diff --git a/net/cookies/canonical_cookie.h b/net/cookies/canonical_cookie.h
index 9524266..64e945b 100644
--- a/net/cookies/canonical_cookie.h
+++ b/net/cookies/canonical_cookie.h
@@ -6,6 +6,7 @@
 #define NET_COOKIES_CANONICAL_COOKIE_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <vector>
@@ -22,7 +23,6 @@
 #include "net/cookies/cookie_inclusion_status.h"
 #include "net/cookies/cookie_options.h"
 #include "net/cookies/cookie_partition_key.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/third_party/mozilla/url_parse.h"
 
 class GURL;
@@ -57,7 +57,7 @@
  public:
   // StrictlyUniqueCookieKey always populates the cookie's source scheme and
   // source port.
-  using StrictlyUniqueCookieKey = std::tuple<absl::optional<CookiePartitionKey>,
+  using StrictlyUniqueCookieKey = std::tuple<std::optional<CookiePartitionKey>,
                                              /*name=*/std::string,
                                              /*domain=*/std::string,
                                              /*path=*/std::string,
@@ -66,20 +66,20 @@
 
   // Conditionally populates the source scheme and source port depending on the
   // state of their associated feature.
-  using UniqueCookieKey = std::tuple<absl::optional<CookiePartitionKey>,
+  using UniqueCookieKey = std::tuple<std::optional<CookiePartitionKey>,
                                      /*name=*/std::string,
                                      /*domain=*/std::string,
                                      /*path=*/std::string,
-                                     absl::optional<CookieSourceScheme>,
-                                     /*source_port=*/absl::optional<int>>;
+                                     std::optional<CookieSourceScheme>,
+                                     /*source_port=*/std::optional<int>>;
 
   // Same as UniqueCookieKey but for use with Domain cookies, which do not
   // consider the source_port.
-  using UniqueDomainCookieKey = std::tuple<absl::optional<CookiePartitionKey>,
+  using UniqueDomainCookieKey = std::tuple<std::optional<CookiePartitionKey>,
                                            /*name=*/std::string,
                                            /*domain=*/std::string,
                                            /*path=*/std::string,
-                                           absl::optional<CookieSourceScheme>>;
+                                           std::optional<CookieSourceScheme>>;
 
   CanonicalCookie();
   CanonicalCookie(const CanonicalCookie& other);
@@ -107,7 +107,7 @@
                   bool httponly,
                   CookieSameSite same_site,
                   CookiePriority priority,
-                  absl::optional<CookiePartitionKey> partition_key,
+                  std::optional<CookiePartitionKey> partition_key,
                   CookieSourceScheme scheme_secure = CookieSourceScheme::kUnset,
                   int source_port = url::PORT_UNSPECIFIED);
 
@@ -128,7 +128,7 @@
   //
   // The partition_key argument only needs to be present if the cookie line
   // contains the Partitioned attribute. If the cookie line will never contain
-  // that attribute, you should use absl::nullopt to indicate you intend to
+  // that attribute, you should use std::nullopt to indicate you intend to
   // always create an unpartitioned cookie. If partition_key has a value but the
   // cookie line does not contain the Partitioned attribute, the resulting
   // cookie will be unpartitioned. If the partition_key is null, then the cookie
@@ -144,8 +144,8 @@
       const GURL& url,
       const std::string& cookie_line,
       const base::Time& creation_time,
-      absl::optional<base::Time> server_time,
-      absl::optional<CookiePartitionKey> cookie_partition_key,
+      std::optional<base::Time> server_time,
+      std::optional<CookiePartitionKey> cookie_partition_key,
       bool block_truncated = true,
       CookieInclusionStatus* status = nullptr);
 
@@ -167,7 +167,7 @@
       bool http_only,
       CookieSameSite same_site,
       CookiePriority priority,
-      absl::optional<CookiePartitionKey> partition_key,
+      std::optional<CookiePartitionKey> partition_key,
       CookieInclusionStatus* status = nullptr);
 
   // FromStorage is a factory method which is meant for creating a new
@@ -190,7 +190,7 @@
       bool httponly,
       CookieSameSite same_site,
       CookiePriority priority,
-      absl::optional<CookiePartitionKey> partition_key,
+      std::optional<CookiePartitionKey> partition_key,
       CookieSourceScheme source_scheme,
       int source_port);
 
@@ -209,7 +209,7 @@
       bool httponly,
       CookieSameSite same_site,
       CookiePriority priority,
-      absl::optional<CookiePartitionKey> partition_key = absl::nullopt,
+      std::optional<CookiePartitionKey> partition_key = std::nullopt,
       CookieSourceScheme scheme_secure = CookieSourceScheme::kUnset,
       int source_port = url::PORT_UNSPECIFIED);
 
@@ -241,7 +241,7 @@
   CookieSameSite SameSite() const { return same_site_; }
   CookiePriority Priority() const { return priority_; }
   bool IsPartitioned() const { return partition_key_.has_value(); }
-  const absl::optional<CookiePartitionKey>& PartitionKey() const {
+  const std::optional<CookiePartitionKey>& PartitionKey() const {
     return partition_key_;
   }
 
@@ -452,8 +452,8 @@
       const CookieOptions& options,
       const CookieAccessParams& params,
       const std::vector<std::string>& cookieable_schemes,
-      const absl::optional<CookieAccessResult>& cookie_access_result =
-          absl::nullopt) const;
+      const std::optional<CookieAccessResult>& cookie_access_result =
+          std::nullopt) const;
 
   std::string DebugString() const;
 
@@ -635,13 +635,13 @@
   bool httponly_{false};
   CookieSameSite same_site_{CookieSameSite::NO_RESTRICTION};
   CookiePriority priority_{COOKIE_PRIORITY_MEDIUM};
-  // This will be absl::nullopt for all cookies not set with the Partitioned
+  // This will be std::nullopt for all cookies not set with the Partitioned
   // attribute or without a nonce. If the value is non-null, then the cookie
   // will only be delivered when the top-frame site matches the partition key
   // and the nonce (if present). If the partition key is non-null and opaque,
   // this means the Partitioned cookie was created on an opaque origin or with
   // a nonce.
-  absl::optional<CookiePartitionKey> partition_key_;
+  std::optional<CookiePartitionKey> partition_key_;
   CookieSourceScheme source_scheme_{CookieSourceScheme::kUnset};
   // This can be [0,65535], PORT_UNSPECIFIED, or PORT_INVALID.
   // PORT_UNSPECIFIED is used for cookies which already existed in the cookie
@@ -654,7 +654,7 @@
 // canonical cookie object may not be available.
 struct NET_EXPORT CookieAndLineWithAccessResult {
   CookieAndLineWithAccessResult();
-  CookieAndLineWithAccessResult(absl::optional<CanonicalCookie> cookie,
+  CookieAndLineWithAccessResult(std::optional<CanonicalCookie> cookie,
                                 std::string cookie_string,
                                 CookieAccessResult access_result);
   CookieAndLineWithAccessResult(
@@ -668,7 +668,7 @@
 
   ~CookieAndLineWithAccessResult();
 
-  absl::optional<CanonicalCookie> cookie;
+  std::optional<CanonicalCookie> cookie;
   std::string cookie_string;
   CookieAccessResult access_result;
 };
diff --git a/net/cookies/canonical_cookie_fuzzer.cc b/net/cookies/canonical_cookie_fuzzer.cc
index c2113af..56990193 100644
--- a/net/cookies/canonical_cookie_fuzzer.cc
+++ b/net/cookies/canonical_cookie_fuzzer.cc
@@ -57,7 +57,7 @@
           CookiePriority::COOKIE_PRIORITY_HIGH,
       });
 
-  const auto partition_key = absl::make_optional<CookiePartitionKey>(
+  const auto partition_key = std::make_optional<CookiePartitionKey>(
       CookiePartitionKey::FromURLForTesting(
           GURL(data_provider.ConsumeRandomLengthString(800))));
 
diff --git a/net/cookies/canonical_cookie_unittest.cc b/net/cookies/canonical_cookie_unittest.cc
index 6ba2b65..e971cf4 100644
--- a/net/cookies/canonical_cookie_unittest.cc
+++ b/net/cookies/canonical_cookie_unittest.cc
@@ -5,6 +5,7 @@
 #include "net/cookies/canonical_cookie.h"
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -23,7 +24,6 @@
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/third_party/mozilla/url_parse.h"
 
@@ -58,7 +58,7 @@
   auto cookie1 = CanonicalCookie::CreateUnsafeCookieForTesting(
       "A", "2", "www.example.com", "/test", current_time, base::Time(),
       base::Time(), base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt, CookieSourceScheme::kSecure, 443);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt, CookieSourceScheme::kSecure, 443);
   EXPECT_EQ("A", cookie1->Name());
   EXPECT_EQ("2", cookie1->Value());
   EXPECT_EQ("www.example.com", cookie1->Domain());
@@ -120,7 +120,7 @@
   auto cookie5 = CanonicalCookie::CreateUnsafeCookieForTesting(
       "A", "2", ".www.example.com", "/", current_time, base::Time(),
       base::Time(), base::Time(), true /* secure */, false,
-      CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, absl::nullopt,
+      CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, std::nullopt,
       CookieSourceScheme::kUnset, url::PORT_UNSPECIFIED);
   EXPECT_EQ(cookie5->SourcePort(), url::PORT_UNSPECIFIED);
 
@@ -128,7 +128,7 @@
   auto cookie6 = CanonicalCookie::CreateUnsafeCookieForTesting(
       "A", "2", ".www.example.com", "/", current_time, base::Time(),
       base::Time(), base::Time(), true /* secure */, false,
-      CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, absl::nullopt,
+      CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, std::nullopt,
       CookieSourceScheme::kUnset, url::PORT_INVALID);
   EXPECT_EQ(cookie6->SourcePort(), url::PORT_INVALID);
 }
@@ -136,33 +136,33 @@
 TEST(CanonicalCookieTest, CreationCornerCases) {
   base::Time creation_time = base::Time::Now();
   std::unique_ptr<CanonicalCookie> cookie;
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
 
   // Space in name.
   cookie = CanonicalCookie::Create(GURL("http://www.example.com/test/foo.html"),
                                    "A C=2", creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
   EXPECT_EQ("A C", cookie->Name());
 
   // Semicolon in path.
   cookie = CanonicalCookie::Create(GURL("http://fool/;/"), "*", creation_time,
                                    server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
 
   // Control characters in name or value.
   CookieInclusionStatus status;
   cookie = CanonicalCookie::Create(GURL("http://www.example.com/test/foo.html"),
                                    "\b=foo", creation_time, server_time,
-                                   /*cookie_partition_key=*/absl::nullopt,
+                                   /*cookie_partition_key=*/std::nullopt,
                                    /*block_truncated=*/true, &status);
   EXPECT_FALSE(cookie.get());
   EXPECT_TRUE(status.HasExclusionReason(
       CookieInclusionStatus::ExclusionReason::EXCLUDE_DISALLOWED_CHARACTER));
   cookie = CanonicalCookie::Create(GURL("http://www.example.com/test/foo.html"),
                                    "bar=\b", creation_time, server_time,
-                                   /*cookie_partition_key=*/absl::nullopt,
+                                   /*cookie_partition_key=*/std::nullopt,
                                    /*block_truncated=*/true, &status);
   EXPECT_FALSE(cookie.get());
   EXPECT_TRUE(status.HasExclusionReason(
@@ -178,7 +178,7 @@
 
   cookie = CanonicalCookie::Create(GURL("http://www.example.com/test/foo.html"),
                                    too_long_value, creation_time, server_time,
-                                   /*cookie_partition_key=*/absl::nullopt,
+                                   /*cookie_partition_key=*/std::nullopt,
                                    /*block_truncated=*/true, &status);
   EXPECT_FALSE(cookie.get());
   EXPECT_TRUE(
@@ -191,11 +191,11 @@
   GURL url("http://www.example.com/test/foo.html");
   GURL https_url("https://www.example.com/test/foo.html");
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
 
   std::unique_ptr<CanonicalCookie> cookie(
       CanonicalCookie::Create(url, "A=2", creation_time, server_time,
-                              absl::nullopt /* cookie_partition_key */));
+                              std::nullopt /* cookie_partition_key */));
   EXPECT_EQ("A", cookie->Name());
   EXPECT_EQ("2", cookie->Value());
   EXPECT_EQ("www.example.com", cookie->Domain());
@@ -206,7 +206,7 @@
 
   GURL url2("http://www.foo.com");
   cookie = CanonicalCookie::Create(url2, "B=1", creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_EQ("B", cookie->Name());
   EXPECT_EQ("1", cookie->Value());
   EXPECT_EQ("www.foo.com", cookie->Domain());
@@ -219,118 +219,118 @@
   // so a URL of any scheme can create a Secure cookie.
   cookie =
       CanonicalCookie::Create(url, "A=2; Secure", creation_time, server_time,
-                              absl::nullopt /* cookie_partition_key */);
+                              std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie->SecureAttribute());
 
   cookie = CanonicalCookie::Create(https_url, "A=2; Secure", creation_time,
                                    server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie->SecureAttribute());
 
   GURL url3("https://www.foo.com");
   cookie =
       CanonicalCookie::Create(url3, "A=2; Secure", creation_time, server_time,
-                              absl::nullopt /* cookie_partition_key */);
+                              std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie->SecureAttribute());
   EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kSecure);
 
   cookie = CanonicalCookie::Create(url3, "A=2", creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_FALSE(cookie->SecureAttribute());
   EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kSecure);
 
   // Test creating cookie from localhost URL.
   cookie = CanonicalCookie::Create(GURL("http://localhost/path"), "A=2",
                                    creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kNonSecure);
 
   cookie = CanonicalCookie::Create(GURL("http://127.0.0.1/path"), "A=2",
                                    creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kNonSecure);
 
   cookie = CanonicalCookie::Create(GURL("http://[::1]/path"), "A=2",
                                    creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kNonSecure);
 
   cookie = CanonicalCookie::Create(GURL("https://localhost/path"), "A=2",
                                    creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kSecure);
 
   cookie = CanonicalCookie::Create(GURL("https://127.0.0.1/path"), "A=2",
                                    creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kSecure);
 
   cookie = CanonicalCookie::Create(GURL("https://[::1]/path"), "A=2",
                                    creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kSecure);
 
   // Test creating http only cookies. HttpOnly is not checked upon creation.
   cookie =
       CanonicalCookie::Create(url, "A=2; HttpOnly", creation_time, server_time,
-                              absl::nullopt /* cookie_partition_key */);
+                              std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie->IsHttpOnly());
 
   cookie =
       CanonicalCookie::Create(url, "A=2; HttpOnly", creation_time, server_time,
-                              absl::nullopt /* cookie_partition_key */);
+                              std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie->IsHttpOnly());
 
   // Test creating SameSite cookies. SameSite is not checked upon creation.
   cookie = CanonicalCookie::Create(url, "A=2; SameSite=Strict", creation_time,
                                    server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   ASSERT_TRUE(cookie.get());
   EXPECT_EQ(CookieSameSite::STRICT_MODE, cookie->SameSite());
   cookie = CanonicalCookie::Create(url, "A=2; SameSite=Lax", creation_time,
                                    server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   ASSERT_TRUE(cookie.get());
   EXPECT_EQ(CookieSameSite::LAX_MODE, cookie->SameSite());
   cookie = CanonicalCookie::Create(url, "A=2; SameSite=Extended", creation_time,
                                    server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   ASSERT_TRUE(cookie.get());
   EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
   cookie = CanonicalCookie::Create(url, "A=2; SameSite=None", creation_time,
                                    server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   ASSERT_TRUE(cookie.get());
   EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie->SameSite());
   cookie = CanonicalCookie::Create(url, "A=2", creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   ASSERT_TRUE(cookie.get());
   EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
 
   // Test creating cookies with different ports.
   cookie = CanonicalCookie::Create(GURL("http://www.foo.com"), "B=1",
                                    creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_EQ(cookie->SourcePort(), 80);
 
   cookie = CanonicalCookie::Create(GURL("http://www.foo.com:81"), "B=1",
                                    creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_EQ(cookie->SourcePort(), 81);
 
   cookie = CanonicalCookie::Create(GURL("https://www.foo.com"), "B=1",
                                    creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_EQ(cookie->SourcePort(), 443);
 
   cookie = CanonicalCookie::Create(GURL("https://www.foo.com:1234"), "B=1",
                                    creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_EQ(cookie->SourcePort(), 1234);
 
   cookie = CanonicalCookie::Create(GURL("http://www.foo.com:443"), "B=1",
                                    creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_EQ(cookie->SourcePort(), 443);
 
   // An invalid port leads to an invalid GURL, which causes cookie creation
@@ -338,7 +338,7 @@
   CookieInclusionStatus status;
   cookie = CanonicalCookie::Create(GURL("http://www.foo.com:70000"), "B=1",
                                    creation_time, server_time,
-                                   /*cookie_partition_key=*/absl::nullopt,
+                                   /*cookie_partition_key=*/std::nullopt,
                                    /*block_truncated=*/true, &status);
   EXPECT_FALSE(cookie.get());
   EXPECT_TRUE(status.HasExclusionReason(
@@ -347,12 +347,11 @@
 
 TEST(CanonicalCookieTest, CreateInvalidUrl) {
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   CookieInclusionStatus status;
   std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
       GURL("http://.127.0.0.1/path"), "A=2", creation_time, server_time,
-      /*cookie_partition_key=*/absl::nullopt, /*block_truncated=*/true,
-      &status);
+      /*cookie_partition_key=*/std::nullopt, /*block_truncated=*/true, &status);
   EXPECT_FALSE(cookie.get());
   EXPECT_TRUE(status.HasExclusionReason(
       CookieInclusionStatus::ExclusionReason::EXCLUDE_FAILURE_TO_STORE));
@@ -365,10 +364,10 @@
   // cookie_line.
   GURL url("http://www.example.com/test/foo.html");
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   std::unique_ptr<CanonicalCookie> cookie(CanonicalCookie::Create(
       url, "A=2; domain=; Secure", creation_time, server_time,
-      absl::nullopt /*cookie_partition_key*/));
+      std::nullopt /*cookie_partition_key*/));
   EXPECT_EQ("www.example.com", cookie->Domain());
   EXPECT_TRUE(cookie->IsHostCookie());
 }
@@ -377,18 +376,18 @@
   GURL url("http://www.example.com/test/foo.html");
   base::Time now = base::Time::Now();
   std::unique_ptr<CanonicalCookie> cookie;
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
 
   // Non-standard value for the SameSite attribute.
   cookie = CanonicalCookie::Create(url, "A=2; SameSite=NonStandard", now,
                                    server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
   EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
 
   // Omit value for the SameSite attribute.
   cookie = CanonicalCookie::Create(url, "A=2; SameSite", now, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
   EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
 }
@@ -397,36 +396,36 @@
   GURL url("http://www.example.com/test/foo.html");
   base::Time now = base::Time::Now();
   std::unique_ptr<CanonicalCookie> cookie;
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
 
   // A cookie can be created from any SameSiteContext regardless of SameSite
   // value (it is upon setting the cookie that the SameSiteContext comes into
   // effect).
   cookie =
       CanonicalCookie::Create(url, "A=2; SameSite=Strict", now, server_time,
-                              absl::nullopt /* cookie_partition_key */);
+                              std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
   cookie = CanonicalCookie::Create(url, "A=2; SameSite=Lax", now, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
   cookie = CanonicalCookie::Create(url, "A=2; SameSite=None", now, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
   cookie = CanonicalCookie::Create(url, "A=2;", now, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
 }
 
 TEST(CanonicalCookieTest, CreateHttpOnly) {
   GURL url("http://www.example.com/test/foo.html");
   base::Time now = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   CookieInclusionStatus status;
 
   // An HttpOnly cookie can be created.
   std::unique_ptr<CanonicalCookie> cookie =
       CanonicalCookie::Create(url, "A=2; HttpOnly", now, server_time,
-                              /*cookie_partition_key=*/absl::nullopt,
+                              /*cookie_partition_key=*/std::nullopt,
                               /*block_truncated=*/true, &status);
   EXPECT_TRUE(cookie->IsHttpOnly());
   EXPECT_TRUE(status.IsInclude());
@@ -435,13 +434,12 @@
 TEST(CanonicalCookieTest, CreateWithInvalidDomain) {
   GURL url("http://www.example.com/test/foo.html");
   base::Time now = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   CookieInclusionStatus status;
 
   std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
       url, "A=2; Domain=wrongdomain.com", now, server_time,
-      /*cookie_partition_key=*/absl::nullopt, /*block_truncated=*/true,
-      &status);
+      /*cookie_partition_key=*/std::nullopt, /*block_truncated=*/true, &status);
   EXPECT_EQ(nullptr, cookie.get());
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
@@ -452,12 +450,12 @@
 TEST(CanonicalCookieTest, CreateFromPublicSuffix) {
   GURL url("http://com/path");
   base::Time now = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   CookieInclusionStatus status;
 
   // Host cookie can be created for an eTLD.
   std::unique_ptr<CanonicalCookie> cookie =
-      CanonicalCookie::Create(url, "A=2", now, server_time, absl::nullopt,
+      CanonicalCookie::Create(url, "A=2", now, server_time, std::nullopt,
                               /*block_truncated=*/true, &status);
   EXPECT_TRUE(status.IsInclude());
   EXPECT_TRUE(cookie->IsHostCookie());
@@ -468,7 +466,7 @@
   // host cookie only.
   cookie =
       CanonicalCookie::Create(url, "A=2; domain=com", now, server_time,
-                              absl::nullopt, /*block_truncated=*/true, &status);
+                              std::nullopt, /*block_truncated=*/true, &status);
   EXPECT_TRUE(status.IsInclude());
   EXPECT_TRUE(cookie->IsHostCookie());
   EXPECT_EQ("com", cookie->Domain());
@@ -476,7 +474,7 @@
   // Same thing if the domain attribute is specified with a dot.
   cookie =
       CanonicalCookie::Create(url, "A=2; domain=.com", now, server_time,
-                              absl::nullopt, /*block_truncated=*/true, &status);
+                              std::nullopt, /*block_truncated=*/true, &status);
   EXPECT_TRUE(status.IsInclude());
   EXPECT_TRUE(cookie->IsHostCookie());
   EXPECT_EQ("com", cookie->Domain());
@@ -484,7 +482,7 @@
   // Capitalization is ok because everything is canonicalized.
   cookie =
       CanonicalCookie::Create(url, "A=2; domain=CoM", now, server_time,
-                              absl::nullopt, /*block_truncated=*/true, &status);
+                              std::nullopt, /*block_truncated=*/true, &status);
   EXPECT_TRUE(status.IsInclude());
   EXPECT_TRUE(cookie->IsHostCookie());
   EXPECT_EQ("com", cookie->Domain());
@@ -495,20 +493,20 @@
   GURL multilabel_url = GURL("http://co.uk/path");
   cookie =
       CanonicalCookie::Create(multilabel_url, "A=2", now, server_time,
-                              absl::nullopt, /*block_truncated=*/true, &status);
+                              std::nullopt, /*block_truncated=*/true, &status);
   EXPECT_TRUE(status.IsInclude());
   EXPECT_TRUE(cookie->IsHostCookie());
   EXPECT_EQ("co.uk", cookie->Domain());
 
   cookie = CanonicalCookie::Create(multilabel_url, "A=2; domain=co.uk", now,
-                                   server_time, absl::nullopt,
+                                   server_time, std::nullopt,
                                    /*block_truncated=*/true, &status);
   EXPECT_TRUE(status.IsInclude());
   EXPECT_TRUE(cookie->IsHostCookie());
   EXPECT_EQ("co.uk", cookie->Domain());
 
   cookie = CanonicalCookie::Create(multilabel_url, "A=2; domain=.co.uk", now,
-                                   server_time, absl::nullopt,
+                                   server_time, std::nullopt,
                                    /*block_truncated=*/true, &status);
   EXPECT_TRUE(status.IsInclude());
   EXPECT_TRUE(cookie->IsHostCookie());
@@ -516,14 +514,14 @@
 
   // Don't allow setting a domain cookie from a public suffix for a superdomain.
   cookie = CanonicalCookie::Create(multilabel_url, "A=2; domain=uk", now,
-                                   server_time, absl::nullopt,
+                                   server_time, std::nullopt,
                                    /*block_truncated=*/true, &status);
   EXPECT_EQ(nullptr, cookie.get());
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
 
   cookie = CanonicalCookie::Create(multilabel_url, "A=2; domain=.uk", now,
-                                   server_time, absl::nullopt,
+                                   server_time, std::nullopt,
                                    /*block_truncated=*/true, &status);
   EXPECT_EQ(nullptr, cookie.get());
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
@@ -531,7 +529,7 @@
 
   // Don't allow setting a domain cookie for an unrelated domain.
   cookie = CanonicalCookie::Create(multilabel_url, "A=2; domain=foo.com", now,
-                                   server_time, absl::nullopt,
+                                   server_time, std::nullopt,
                                    /*block_truncated=*/true, &status);
   EXPECT_EQ(nullptr, cookie.get());
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
@@ -540,7 +538,7 @@
   // Don't allow setting a domain cookie for some other domain with no
   // registrable domain.
   cookie = CanonicalCookie::Create(multilabel_url, "A=2; domain=com", now,
-                                   server_time, absl::nullopt,
+                                   server_time, std::nullopt,
                                    /*block_truncated=*/true, &status);
   EXPECT_EQ(nullptr, cookie.get());
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
@@ -550,7 +548,7 @@
 TEST(CanonicalCookieTest, CreateWithNonASCIIDomain) {
   GURL url("http://www.xn--xample-9ua.com/test/foo.html");
   base::Time now = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
 
   // Test with feature flag enabled.
   {
@@ -561,7 +559,7 @@
     // Test that non-ascii characters are rejected.
     std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
         url, "A=1; Domain=\xC3\xA9xample.com", now, server_time,
-        /*cookie_partition_key=*/absl::nullopt, /*block_truncated=*/true,
+        /*cookie_partition_key=*/std::nullopt, /*block_truncated=*/true,
         &status);
     EXPECT_EQ(nullptr, cookie.get());
     EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
@@ -579,7 +577,7 @@
 
     std::unique_ptr<CanonicalCookie> cookie2 = CanonicalCookie::Create(
         url, "A=2; Domain=\xC3\xA9xample.com", now, server_time,
-        /*cookie_partition_key=*/absl::nullopt, /*block_truncated=*/true,
+        /*cookie_partition_key=*/std::nullopt, /*block_truncated=*/true,
         &status2);
 
     EXPECT_TRUE(cookie2.get());
@@ -592,7 +590,7 @@
   CookieInclusionStatus status3;
   std::unique_ptr<CanonicalCookie> cookie3 = CanonicalCookie::Create(
       url, "A=3; Domain=xn--xample-9ua.com", now, server_time,
-      /*cookie_partition_key=*/absl::nullopt, /*block_truncated=*/true,
+      /*cookie_partition_key=*/std::nullopt, /*block_truncated=*/true,
       &status3);
   EXPECT_TRUE(cookie3.get());
   EXPECT_TRUE(status3.IsInclude());
@@ -605,7 +603,7 @@
   GURL url6("http://[2606:2800:220:1:248:1893:25c8:1946]");
 
   base::Time now = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   CookieInclusionStatus status;
 
   const struct {
@@ -635,7 +633,7 @@
   for (const auto& test : kTests) {
     std::unique_ptr<CanonicalCookie> cookie =
         CanonicalCookie::Create(test.url, test.cookie_line, now, server_time,
-                                /*cookie_partition_key=*/absl::nullopt,
+                                /*cookie_partition_key=*/std::nullopt,
                                 /*block_truncated=*/true, &status);
     if (test.expectedResult) {
       ASSERT_TRUE(cookie.get());
@@ -651,7 +649,7 @@
 TEST(CanonicalCookieTest, CreateWithPartitioned) {
   GURL url("https://www.example.com/test/foo.html");
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   auto partition_key =
       CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite.com"));
   CookieInclusionStatus status;
@@ -733,7 +731,7 @@
   // No Partitioned attribute but with a nonce.
   status = CookieInclusionStatus();
   auto partition_key_with_nonce =
-      absl::make_optional(CookiePartitionKey::FromURLForTesting(
+      std::make_optional(CookiePartitionKey::FromURLForTesting(
           GURL("https://toplevelsite.com"), base::UnguessableToken::Create()));
   cookie = CanonicalCookie::Create(
       url, "__Host-A=2; Path=/; Secure", creation_time, server_time,
@@ -747,7 +745,7 @@
 TEST(CanonicalCookieTest, CreateWithPartitioned_Localhost) {
   GURL url("http://localhost:8000/foo/bar.html");
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   auto partition_key =
       CookiePartitionKey::FromURLForTesting(GURL("http://localhost:8000"));
   CookieInclusionStatus status;
@@ -766,12 +764,12 @@
 TEST(CanonicalCookieTest, CreateWithMaxAge) {
   GURL url("http://www.example.com/test/foo.html");
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
 
   // Max-age with positive integer.
   std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
       url, "A=1; max-age=60", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
   EXPECT_TRUE(cookie->IsPersistent());
   EXPECT_FALSE(cookie->IsExpired(creation_time));
@@ -781,7 +779,7 @@
   // Max-age with expires (max-age should take precedence).
   cookie = CanonicalCookie::Create(
       url, "A=1; expires=01-Jan-1970, 00:00:00 GMT; max-age=60", creation_time,
-      server_time, absl::nullopt /* cookie_partition_key */);
+      server_time, std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
   EXPECT_TRUE(cookie->IsPersistent());
   EXPECT_FALSE(cookie->IsExpired(creation_time));
@@ -792,7 +790,7 @@
   // representable time.
   cookie =
       CanonicalCookie::Create(url, "A=1; max-age=0", creation_time, server_time,
-                              absl::nullopt /* cookie_partition_key */);
+                              std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
   EXPECT_TRUE(cookie->IsPersistent());
   EXPECT_TRUE(cookie->IsExpired(creation_time));
@@ -803,7 +801,7 @@
   // earliest representable time.
   cookie = CanonicalCookie::Create(url, "A=1; max-age=-1", creation_time,
                                    server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
   EXPECT_TRUE(cookie->IsPersistent());
   EXPECT_TRUE(cookie->IsExpired(creation_time));
@@ -813,7 +811,7 @@
   // Max-age with whitespace (should be trimmed out).
   cookie = CanonicalCookie::Create(url, "A=1; max-age = 60  ; Secure",
                                    creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
   EXPECT_TRUE(cookie->IsPersistent());
   EXPECT_FALSE(cookie->IsExpired(creation_time));
@@ -823,7 +821,7 @@
   // Max-age with non-integer should be ignored.
   cookie = CanonicalCookie::Create(url, "A=1; max-age=abcd", creation_time,
                                    server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
   EXPECT_FALSE(cookie->IsPersistent());
   EXPECT_FALSE(cookie->IsExpired(creation_time));
@@ -836,7 +834,7 @@
                                    "9999999999999999999999999999999999999999999"
                                    "999999999999999999999999999999999999999999",
                                    creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
   EXPECT_TRUE(cookie->IsPersistent());
   EXPECT_FALSE(cookie->IsExpired(creation_time));
@@ -850,7 +848,7 @@
                                    "9999999999999999999999999999999999999999999"
                                    "999999999999999999999999999999999999999999",
                                    creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
   EXPECT_TRUE(cookie->IsPersistent());
   EXPECT_TRUE(cookie->IsExpired(creation_time));
@@ -861,13 +859,13 @@
 TEST(CanonicalCookieTest, CreateWithExpires) {
   GURL url("http://www.example.com/test/foo.html");
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
 
   // Expires in the past
   base::Time past_date = base::Time::Now() - base::Days(10);
   std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
       url, "A=1; expires=" + HttpUtil::TimeFormatHTTP(past_date), creation_time,
-      server_time, absl::nullopt /* cookie_partition_key */);
+      server_time, std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
   EXPECT_TRUE(cookie->IsPersistent());
   EXPECT_TRUE(cookie->IsExpired(creation_time));
@@ -879,7 +877,7 @@
   base::Time future_date = base::Time::Now() + base::Days(10);
   cookie = CanonicalCookie::Create(
       url, "A=1; expires=" + HttpUtil::TimeFormatHTTP(future_date),
-      creation_time, server_time, absl::nullopt /* cookie_partition_key */);
+      creation_time, server_time, std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
   EXPECT_TRUE(cookie->IsPersistent());
   EXPECT_FALSE(cookie->IsExpired(creation_time));
@@ -891,7 +889,7 @@
   future_date = base::Time::Now() + base::Days(800);
   cookie = CanonicalCookie::Create(
       url, "A=1; expires=" + HttpUtil::TimeFormatHTTP(future_date),
-      creation_time, server_time, absl::nullopt /* cookie_partition_key */);
+      creation_time, server_time, std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
   EXPECT_TRUE(cookie->IsPersistent());
   EXPECT_FALSE(cookie->IsExpired(creation_time));
@@ -904,7 +902,7 @@
   cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
       "A", "1", url.host(), url.path(), creation_time, base::Time::Max(),
       base::Time(), base::Time(), true, false, CookieSameSite::UNSPECIFIED,
-      COOKIE_PRIORITY_HIGH, absl::nullopt /* cookie_partition_key */,
+      COOKIE_PRIORITY_HIGH, std::nullopt /* cookie_partition_key */,
       CookieSourceScheme::kSecure, 443);
   EXPECT_TRUE(cookie.get());
   EXPECT_TRUE(cookie->IsPersistent());
@@ -918,7 +916,7 @@
       "A", "B", "www.foo.com", "/bar", creation_time, base::Time::Max(),
       base::Time(), base::Time(), false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, CookieSourceScheme::kSecure, 443);
+      std::nullopt /*partition_key*/, CookieSourceScheme::kSecure, 443);
   EXPECT_TRUE(cookie.get());
   EXPECT_TRUE(cookie->IsPersistent());
   EXPECT_FALSE(cookie->IsExpired(creation_time));
@@ -930,13 +928,13 @@
 TEST(CanonicalCookieTest, EmptyExpiry) {
   GURL url("http://www7.ipdl.inpit.go.jp/Tokujitu/tjkta.ipdl?N0000=108");
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
 
   std::string cookie_line =
       "ACSTM=20130308043820420042; path=/; domain=ipdl.inpit.go.jp; Expires=";
   std::unique_ptr<CanonicalCookie> cookie(
       CanonicalCookie::Create(url, cookie_line, creation_time, server_time,
-                              absl::nullopt /* cookie_partition_key */));
+                              std::nullopt /* cookie_partition_key */));
   EXPECT_TRUE(cookie.get());
   EXPECT_FALSE(cookie->IsPersistent());
   EXPECT_FALSE(cookie->IsExpired(creation_time));
@@ -945,7 +943,7 @@
   // With a stale server time
   server_time = creation_time - base::Hours(1);
   cookie = CanonicalCookie::Create(url, cookie_line, creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
   EXPECT_FALSE(cookie->IsPersistent());
   EXPECT_FALSE(cookie->IsExpired(creation_time));
@@ -954,7 +952,7 @@
   // With a future server time
   server_time = creation_time + base::Hours(1);
   cookie = CanonicalCookie::Create(url, cookie_line, creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie.get());
   EXPECT_FALSE(cookie->IsPersistent());
   EXPECT_FALSE(cookie->IsExpired(creation_time));
@@ -965,12 +963,12 @@
   GURL url("http://www.example.com/test/foo.html");
   base::Time creation_time = base::Time::Now() - base::Days(1);
   base::Time last_update_time = base::Time::Now() - base::Hours(1);
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
 
   // Creating a cookie sets the last update date as now.
   std::unique_ptr<CanonicalCookie> cookie =
       CanonicalCookie::Create(url, "A=1", creation_time, server_time,
-                              /*cookie_partition_key=*/absl::nullopt);
+                              /*cookie_partition_key=*/std::nullopt);
   ASSERT_TRUE(cookie.get());
   EXPECT_TRUE((base::Time::Now() - cookie->LastUpdateDate()).magnitude() <
               base::Seconds(1));
@@ -981,7 +979,7 @@
       creation_time, /*secure=*/true,
       /*http_only=*/false, CookieSameSite::NO_RESTRICTION,
       COOKIE_PRIORITY_DEFAULT,
-      /*partition_key=*/absl::nullopt);
+      /*partition_key=*/std::nullopt);
   ASSERT_TRUE(cookie.get());
   EXPECT_TRUE((base::Time::Now() - cookie->LastUpdateDate()).magnitude() <
               base::Seconds(1));
@@ -992,7 +990,7 @@
       base::Time(), last_update_time, /*secure=*/true,
       /*httponly=*/false, CookieSameSite::NO_RESTRICTION,
       COOKIE_PRIORITY_DEFAULT,
-      /*partition_key=*/absl::nullopt, CookieSourceScheme::kSecure,
+      /*partition_key=*/std::nullopt, CookieSourceScheme::kSecure,
       /*source_port=*/443);
   ASSERT_TRUE(cookie.get());
   EXPECT_EQ(last_update_time, cookie->LastUpdateDate());
@@ -1003,7 +1001,7 @@
       base::Time(), last_update_time, /*secure=*/true,
       /*httponly=*/false, CookieSameSite::NO_RESTRICTION,
       COOKIE_PRIORITY_DEFAULT,
-      /*partition_key=*/absl::nullopt, CookieSourceScheme::kSecure,
+      /*partition_key=*/std::nullopt, CookieSourceScheme::kSecure,
       /*source_port=*/443);
   ASSERT_TRUE(cookie.get());
   EXPECT_EQ(last_update_time, cookie->LastUpdateDate());
@@ -1189,7 +1187,7 @@
       const char* name;
       const char* domain;
       const char* path;
-      absl::optional<CookiePartitionKey> cookie_partition_key = absl::nullopt;
+      std::optional<CookiePartitionKey> cookie_partition_key = std::nullopt;
     } cookie, secure_cookie;
     bool equivalent;
     bool is_symmetric;  // Whether the reverse comparison has the same result.
@@ -1269,7 +1267,7 @@
     const bool secure = false;
     const bool httponly = false;
     const CookieSameSite same_site = CookieSameSite::NO_RESTRICTION;
-    const absl::optional<CookiePartitionKey> partition_key = absl::nullopt;
+    const std::optional<CookiePartitionKey> partition_key = std::nullopt;
 
     return CanonicalCookie::CreateUnsafeCookieForTesting(
         cookie_name, cookie_value, domain_field, cookie_path, creation_time,
@@ -1478,11 +1476,11 @@
 TEST(CanonicalCookieTest, IsDomainMatch) {
   GURL url("http://www.example.com/test/foo.html");
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
 
   std::unique_ptr<CanonicalCookie> cookie(
       CanonicalCookie::Create(url, "A=2", creation_time, server_time,
-                              absl::nullopt /* cookie_partition_key */));
+                              std::nullopt /* cookie_partition_key */));
   EXPECT_TRUE(cookie->IsHostCookie());
   EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
   EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
@@ -1492,7 +1490,7 @@
 
   cookie = CanonicalCookie::Create(url, "A=2; Domain=www.example.com",
                                    creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie->IsDomainCookie());
   EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
   EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
@@ -1502,7 +1500,7 @@
 
   cookie = CanonicalCookie::Create(url, "A=2; Domain=.www.example.com",
                                    creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
   EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
   EXPECT_TRUE(cookie->IsDomainMatch("foo.www.example.com"));
@@ -1512,11 +1510,11 @@
 
 TEST(CanonicalCookieTest, IsOnPath) {
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
 
   std::unique_ptr<CanonicalCookie> cookie(CanonicalCookie::Create(
       GURL("http://www.example.com"), "A=2", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+      std::nullopt /* cookie_partition_key */));
   EXPECT_TRUE(cookie->IsOnPath("/"));
   EXPECT_TRUE(cookie->IsOnPath("/test"));
   EXPECT_TRUE(cookie->IsOnPath("/test/bar.html"));
@@ -1526,7 +1524,7 @@
 
   cookie = CanonicalCookie::Create(GURL("http://www.example.com/test/foo.html"),
                                    "A=2", creation_time, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_FALSE(cookie->IsOnPath("/"));
   EXPECT_TRUE(cookie->IsOnPath("/test"));
   EXPECT_TRUE(cookie->IsOnPath("/test/bar.html"));
@@ -1539,8 +1537,8 @@
     CookieEffectiveSameSite expected_effective_same_site;
     // nullopt for following members indicates same effective SameSite result
     // for all possible values.
-    absl::optional<CookieAccessSemantics> access_semantics = absl::nullopt;
-    absl::optional<bool> is_cookie_recent = absl::nullopt;
+    std::optional<CookieAccessSemantics> access_semantics = std::nullopt;
+    std::optional<bool> is_cookie_recent = std::nullopt;
   } kTestCases[] = {
       // Explicitly specified SameSite always has the same effective SameSite
       // regardless of the access semantics.
@@ -1619,11 +1617,11 @@
   GURL url("http://www.example.com");
   base::Time creation_time = base::Time::Now();
   CookieOptions options = CookieOptions::MakeAllInclusive();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
 
   std::unique_ptr<CanonicalCookie> cookie(
       CanonicalCookie::Create(url, "A=2", creation_time, server_time,
-                              absl::nullopt /* cookie_partition_key */));
+                              std::nullopt /* cookie_partition_key */));
   EXPECT_TRUE(
       cookie
           ->IncludeForRequestURL(
@@ -1665,7 +1663,7 @@
   // not included.
   cookie = CanonicalCookie::Create(url, "A=2; Path=/foo/bar", creation_time,
                                    server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(
       cookie
           ->IncludeForRequestURL(
@@ -1685,7 +1683,7 @@
   GURL secure_url("https://www.example.com");
   cookie = CanonicalCookie::Create(secure_url, "A=2; Secure", creation_time,
                                    server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie->SecureAttribute());
   EXPECT_TRUE(
       cookie
@@ -1707,7 +1705,7 @@
   // non-secure URL to be treated as trustworthy... with a warning.
   cookie =
       CanonicalCookie::Create(url, "A=2; Secure", creation_time, server_time,
-                              absl::nullopt /* cookie_partition_key */);
+                              std::nullopt /* cookie_partition_key */);
   ASSERT_TRUE(cookie);
   EXPECT_TRUE(cookie->SecureAttribute());
   CookieAccessResult result = cookie->IncludeForRequestURL(
@@ -1722,7 +1720,7 @@
   GURL localhost_url("http://localhost/");
   cookie = CanonicalCookie::Create(localhost_url, "A=2; Secure", creation_time,
                                    server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   ASSERT_TRUE(cookie);
   EXPECT_TRUE(cookie->SecureAttribute());
   result = cookie->IncludeForRequestURL(
@@ -1736,7 +1734,7 @@
   // An unneeded exception doesn't add a warning, however.
   cookie = CanonicalCookie::Create(secure_url, "A=2; Secure", creation_time,
                                    server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   ASSERT_TRUE(cookie);
   EXPECT_TRUE(cookie->SecureAttribute());
   result = cookie->IncludeForRequestURL(
@@ -1751,7 +1749,7 @@
   options.set_include_httponly();
   cookie =
       CanonicalCookie::Create(url, "A=2; HttpOnly", creation_time, server_time,
-                              absl::nullopt /* cookie_partition_key */);
+                              std::nullopt /* cookie_partition_key */);
   EXPECT_TRUE(cookie->IsHttpOnly());
   EXPECT_TRUE(
       cookie
@@ -1787,8 +1785,8 @@
   for (const auto& test : test_cases) {
     base::Time creation_time = base::Time::Now() - test.creation_time_delta;
     std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
-        url, test.cookie_line, creation_time, absl::nullopt /* server_time */,
-        absl::nullopt /* cookie_partition_key */);
+        url, test.cookie_line, creation_time, std::nullopt /* server_time */,
+        std::nullopt /* cookie_partition_key */);
     EXPECT_EQ(test.expected_samesite, cookie->SameSite());
 
     CookieOptions request_options;
@@ -2170,7 +2168,7 @@
         CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, partition_key);
   };
 
-  auto no_partition_key_cookie = make_cookie(absl::nullopt);
+  auto no_partition_key_cookie = make_cookie(std::nullopt);
   auto partitioned_cookie =
       make_cookie(CookiePartitionKey::FromURLForTesting(GURL(url)));
   auto nonced_partition_key_cookie =
@@ -2222,13 +2220,13 @@
 TEST(CanonicalCookieTest, IncludeCookiesWithoutSameSiteMustBeSecure) {
   GURL url("https://www.example.com");
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   CookieOptions options;
 
   // Make a SameSite=None, *not* Secure cookie.
   std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
       url, "A=2; SameSite=None", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* cookie_partition_key */);
   ASSERT_TRUE(cookie.get());
   EXPECT_FALSE(cookie->SecureAttribute());
   EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie->SameSite());
@@ -2476,7 +2474,7 @@
 // scheme does(n't) match the url's.
 TEST(CanonicalCookieTest, IncludeForRequestURL_SchemeBoundStatus) {
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   CookieOptions options;
   options.set_same_site_cookie_context(
       CookieOptions::SameSiteCookieContext::MakeInclusive());
@@ -2494,18 +2492,18 @@
   // rather to prevent warnings that SameSite isn't specified.
   auto secure_cookie = CanonicalCookie::Create(
       secure_url, "secure=foobar; SameSite=Lax", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* cookie_partition_key */);
   auto secure_attr_cookie = CanonicalCookie::Create(
       secure_url, "secure=foobar; SameSite=Lax; Secure", creation_time,
-      server_time, absl::nullopt /* cookie_partition_key */);
+      server_time, std::nullopt /* cookie_partition_key */);
   auto insecure_cookie = CanonicalCookie::Create(
       insecure_url, "insecure=foobar; SameSite=Lax", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* cookie_partition_key */);
   // Create a cookie with an unset scheme. This can happen if a cookie was
   // stored in the DB before we began recording source schemes.
   auto unset_cookie = CanonicalCookie::Create(
       secure_url, "unset=foobar; SameSite=Lax", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* cookie_partition_key */);
   unset_cookie->SetSourceScheme(CookieSourceScheme::kUnset);
 
   // When the feature is disabled we should have warnings.
@@ -2611,7 +2609,7 @@
 // port does(n't) match the url's.
 TEST(CanonicalCookieTest, IncludeForRequestURL_PortBoundStatus) {
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   CookieOptions options;
   options.set_same_site_cookie_context(
       CookieOptions::SameSiteCookieContext::MakeInclusive());
@@ -2626,16 +2624,16 @@
   // rather to prevent warnings that SameSite isn't specified.
   auto cookie1 = CanonicalCookie::Create(
       url1, "cookie=1; SameSite=Lax", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* cookie_partition_key */);
   auto cookie2 = CanonicalCookie::Create(
       url2, "cookie=2; SameSite=Lax", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* cookie_partition_key */);
 
   // Create a cookie with an unspecified port. This can happen if a cookie was
   // stored in the DB before we began recording source ports.
   auto unspecified_cookie = CanonicalCookie::Create(
       url2, "cookie=unspecified; SameSite=Lax", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* cookie_partition_key */);
   unspecified_cookie->SetSourcePort(url::PORT_UNSPECIFIED);
 
   // When the feature is disabled we should have warnings.
@@ -2679,7 +2677,7 @@
 // Test that domain cookies match any request url port.
 TEST(CanonicalCookieTest, IncludeForRequestURL_DomainCookiesPortMatch) {
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   CookieOptions options;
   options.set_same_site_cookie_context(
       CookieOptions::SameSiteCookieContext::MakeInclusive());
@@ -2694,11 +2692,11 @@
   // rather to prevent warnings that SameSite isn't specified.
   auto host_cookie = CanonicalCookie::Create(
       url1, "cookie=hostonly; SameSite=Lax", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* cookie_partition_key */);
 
   auto domain_cookie = CanonicalCookie::Create(
       url1, "cookie=domain; SameSite=Lax; Domain=example.test", creation_time,
-      server_time, absl::nullopt /* cookie_partition_key */);
+      server_time, std::nullopt /* cookie_partition_key */);
 
   // When the feature is disabled we shouldn't get any port mismatch warnings
   // for domain cookies.
@@ -2751,8 +2749,8 @@
         {});
     std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
         url, "A=1; expires=" + HttpUtil::TimeFormatHTTP(future_date),
-        creation_time, /*server_time=*/absl::nullopt,
-        /*cookie_partition_key=*/absl::nullopt);
+        creation_time, /*server_time=*/std::nullopt,
+        /*cookie_partition_key=*/std::nullopt);
     ASSERT_TRUE(cookie);
     // With the feature enabled, expiration time should be limited to 3 hours
     // after creation. Equality check needs to have a second margin due to
@@ -2768,8 +2766,8 @@
         {features::kTimeLimitedInsecureCookies});
     std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
         url, "A=1; expires=" + HttpUtil::TimeFormatHTTP(future_date),
-        creation_time, /*server_time=*/absl::nullopt,
-        /*cookie_partition_key=*/absl::nullopt);
+        creation_time, /*server_time=*/std::nullopt,
+        /*cookie_partition_key=*/std::nullopt);
     ASSERT_TRUE(cookie);
     // With the feature disabled, expiration time should not be limited.
     // Equality check needs to have a second margin due to microsecond rounding
@@ -2783,7 +2781,7 @@
 TEST(CanonicalCookieTest, MultipleExclusionReasons) {
   GURL url("http://www.not-secure.com/foo");
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   CookieOptions options;
   options.set_exclude_httponly();
   options.set_same_site_cookie_context(CookieOptions::SameSiteCookieContext(
@@ -2815,7 +2813,7 @@
   CookieInclusionStatus create_status;
   auto cookie2 = CanonicalCookie::Create(
       url, "__Secure-notactuallysecure=value;Domain=some-other-domain.com",
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt, true,
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt, true,
       &create_status);
   ASSERT_FALSE(cookie2);
   EXPECT_TRUE(create_status.HasExactlyExclusionReasonsForTesting(
@@ -2825,7 +2823,7 @@
   // Test IsSetPermittedInContext()
   auto cookie3 = CanonicalCookie::Create(
       url, "name=value;HttpOnly;SameSite=Lax", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* cookie_partition_key */);
   ASSERT_TRUE(cookie3);
   EXPECT_THAT(
       cookie3->IsSetPermittedInContext(
@@ -2844,16 +2842,16 @@
 TEST(CanonicalCookieTest, PartialCompare) {
   GURL url("http://www.example.com");
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   std::unique_ptr<CanonicalCookie> cookie(
       CanonicalCookie::Create(url, "a=b", creation_time, server_time,
-                              absl::nullopt /* cookie_partition_key */));
+                              std::nullopt /* cookie_partition_key */));
   std::unique_ptr<CanonicalCookie> cookie_different_path(
       CanonicalCookie::Create(url, "a=b; path=/foo", creation_time, server_time,
-                              absl::nullopt /* cookie_partition_key */));
+                              std::nullopt /* cookie_partition_key */));
   std::unique_ptr<CanonicalCookie> cookie_different_value(
       CanonicalCookie::Create(url, "a=c", creation_time, server_time,
-                              absl::nullopt /* cookie_partition_key */));
+                              std::nullopt /* cookie_partition_key */));
 
   // Cookie is equivalent to itself.
   EXPECT_FALSE(cookie->PartialCompare(*cookie));
@@ -2875,19 +2873,19 @@
   GURL https_url("https://www.example.test");
   GURL http_url("http://www.example.test");
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   CookieInclusionStatus status;
 
   // A __Secure- cookie must be Secure.
   EXPECT_FALSE(CanonicalCookie::Create(https_url, "__Secure-A=B", creation_time,
                                        server_time,
-                                       /*cookie_partition_key=*/absl::nullopt,
+                                       /*cookie_partition_key=*/std::nullopt,
                                        /*block_truncated=*/true, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
   EXPECT_FALSE(CanonicalCookie::Create(https_url, "__Secure-A=B; httponly",
                                        creation_time, server_time,
-                                       /*cookie_partition_key=*/absl::nullopt,
+                                       /*cookie_partition_key=*/std::nullopt,
                                        /*block_truncated=*/true, &status));
   // (EXCLUDE_HTTP_ONLY would be fine, too)
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
@@ -2896,17 +2894,17 @@
   // Prefixes are case insensitive.
   EXPECT_FALSE(CanonicalCookie::Create(
       https_url, "__secure-A=C;", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+      std::nullopt /* cookie_partition_key */));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
   EXPECT_FALSE(CanonicalCookie::Create(
       https_url, "__SECURE-A=C;", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+      std::nullopt /* cookie_partition_key */));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
   EXPECT_FALSE(CanonicalCookie::Create(
       https_url, "__SeCuRe-A=C;", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+      std::nullopt /* cookie_partition_key */));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
 
@@ -2917,33 +2915,33 @@
 
     EXPECT_TRUE(CanonicalCookie::Create(
         https_url, "__secure-A=C;", creation_time, server_time,
-        absl::nullopt /* cookie_partition_key */));
+        std::nullopt /* cookie_partition_key */));
     EXPECT_TRUE(CanonicalCookie::Create(
         https_url, "__SECURE-A=C;", creation_time, server_time,
-        absl::nullopt /* cookie_partition_key */));
+        std::nullopt /* cookie_partition_key */));
     EXPECT_TRUE(CanonicalCookie::Create(
         https_url, "__SeCuRe-A=C;", creation_time, server_time,
-        absl::nullopt /* cookie_partition_key */));
+        std::nullopt /* cookie_partition_key */));
   }
 
   // A typoed prefix does not have to be Secure.
-  EXPECT_TRUE(CanonicalCookie::Create(
-      https_url, "__SecureA=B; Secure", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
-  EXPECT_TRUE(CanonicalCookie::Create(
-      https_url, "__SecureA=C;", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
-  EXPECT_TRUE(CanonicalCookie::Create(
-      https_url, "_Secure-A=C;", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
-  EXPECT_TRUE(CanonicalCookie::Create(
-      https_url, "Secure-A=C;", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+  EXPECT_TRUE(CanonicalCookie::Create(https_url, "__SecureA=B; Secure",
+                                      creation_time, server_time,
+                                      std::nullopt /* cookie_partition_key */));
+  EXPECT_TRUE(CanonicalCookie::Create(https_url, "__SecureA=C;", creation_time,
+                                      server_time,
+                                      std::nullopt /* cookie_partition_key */));
+  EXPECT_TRUE(CanonicalCookie::Create(https_url, "_Secure-A=C;", creation_time,
+                                      server_time,
+                                      std::nullopt /* cookie_partition_key */));
+  EXPECT_TRUE(CanonicalCookie::Create(https_url, "Secure-A=C;", creation_time,
+                                      server_time,
+                                      std::nullopt /* cookie_partition_key */));
 
   // A __Secure- cookie can't be set on a non-secure origin.
   EXPECT_FALSE(CanonicalCookie::Create(http_url, "__Secure-A=B; Secure",
                                        creation_time, server_time,
-                                       /*cookie_partition_key=*/absl::nullopt,
+                                       /*cookie_partition_key=*/std::nullopt,
                                        /*block_truncated=*/true, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
@@ -2951,69 +2949,69 @@
   // Hidden __Secure- prefixes should be rejected.
   EXPECT_FALSE(CanonicalCookie::Create(https_url, "=__Secure-A=B; Secure",
                                        creation_time, server_time,
-                                       /*cookie_partition_key=*/absl::nullopt,
+                                       /*cookie_partition_key=*/std::nullopt,
                                        /*block_truncated=*/true, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
   EXPECT_FALSE(CanonicalCookie::Create(https_url, "=__Secure-A; Secure",
                                        creation_time, server_time,
-                                       /*cookie_partition_key=*/absl::nullopt,
+                                       /*cookie_partition_key=*/std::nullopt,
                                        /*block_truncated=*/true, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
 
   // While tricky, this isn't considered hidden and is fine.
-  EXPECT_TRUE(CanonicalCookie::Create(
-      https_url, "A=__Secure-A=B; Secure", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+  EXPECT_TRUE(CanonicalCookie::Create(https_url, "A=__Secure-A=B; Secure",
+                                      creation_time, server_time,
+                                      std::nullopt /* cookie_partition_key */));
 }
 
 TEST(CanonicalCookieTest, HostCookiePrefix) {
   GURL https_url("https://www.example.test");
   GURL http_url("http://www.example.test");
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   std::string domain = https_url.host();
   CookieInclusionStatus status;
 
   // A __Host- cookie must be Secure.
   EXPECT_FALSE(CanonicalCookie::Create(https_url, "__Host-A=B;", creation_time,
                                        server_time,
-                                       /*cookie_partition_key=*/absl::nullopt,
+                                       /*cookie_partition_key=*/std::nullopt,
                                        /*block_truncated=*/true, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
   EXPECT_FALSE(CanonicalCookie::Create(
       https_url, "__Host-A=B; Domain=" + domain + "; Path=/;", creation_time,
-      server_time, /*cookie_partition_key=*/absl::nullopt,
+      server_time, /*cookie_partition_key=*/std::nullopt,
       /*block_truncated=*/true, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
-  EXPECT_TRUE(CanonicalCookie::Create(
-      https_url, "__Host-A=B; Path=/; Secure;", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+  EXPECT_TRUE(CanonicalCookie::Create(https_url, "__Host-A=B; Path=/; Secure;",
+                                      creation_time, server_time,
+                                      std::nullopt /* cookie_partition_key */));
 
   // A __Host- cookie must be set from a secure scheme.
   EXPECT_FALSE(CanonicalCookie::Create(
       http_url, "__Host-A=B; Domain=" + domain + "; Path=/; Secure;",
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt,
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt,
       /*block_truncated=*/true, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
-  EXPECT_TRUE(CanonicalCookie::Create(
-      https_url, "__Host-A=B; Path=/; Secure;", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+  EXPECT_TRUE(CanonicalCookie::Create(https_url, "__Host-A=B; Path=/; Secure;",
+                                      creation_time, server_time,
+                                      std::nullopt /* cookie_partition_key */));
 
   // A __Host- cookie can't have a Domain.
   EXPECT_FALSE(CanonicalCookie::Create(
       https_url, "__Host-A=B; Domain=" + domain + "; Path=/; Secure;",
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt,
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt,
       /*block_truncated=*/true, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
   EXPECT_FALSE(CanonicalCookie::Create(
       https_url, "__Host-A=B; Domain=" + domain + "; Secure;", creation_time,
-      server_time, /*cookie_partition_key=*/absl::nullopt,
+      server_time, /*cookie_partition_key=*/std::nullopt,
       /*block_truncated=*/true, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
@@ -3023,49 +3021,49 @@
   EXPECT_TRUE(CanonicalCookie::Create(
       GURL("https://127.0.0.1"),
       "__Host-A=B; Domain=127.0.0.1; Path=/; Secure;", creation_time,
-      server_time, /*cookie_partition_key=*/absl::nullopt,
+      server_time, /*cookie_partition_key=*/std::nullopt,
       /*block_truncated=*/true, &status));
   // A __Host- cookie with an IP address domain does not need the domain
   // attribute specified explicitly (just like a normal domain).
   EXPECT_TRUE(CanonicalCookie::Create(
       GURL("https://127.0.0.1"), "__Host-A=B; Domain=; Path=/; Secure;",
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt,
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt,
       /*block_truncated=*/true, &status));
 
   // A __Host- cookie must have a Path of "/".
   EXPECT_FALSE(CanonicalCookie::Create(
       https_url, "__Host-A=B; Path=/foo; Secure;", creation_time, server_time,
-      /*cookie_partition_key=*/absl::nullopt, /*block_truncated=*/true,
+      /*cookie_partition_key=*/std::nullopt, /*block_truncated=*/true,
       &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
   EXPECT_FALSE(CanonicalCookie::Create(
       https_url, "__Host-A=B; Secure;", creation_time, server_time,
-      /*cookie_partition_key=*/absl::nullopt, true, &status));
+      /*cookie_partition_key=*/std::nullopt, true, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
-  EXPECT_TRUE(CanonicalCookie::Create(
-      https_url, "__Host-A=B; Secure; Path=/;", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+  EXPECT_TRUE(CanonicalCookie::Create(https_url, "__Host-A=B; Secure; Path=/;",
+                                      creation_time, server_time,
+                                      std::nullopt /* cookie_partition_key */));
 
   // Prefixes are case insensitive.
   EXPECT_FALSE(CanonicalCookie::Create(
       http_url, "__host-A=B; Domain=" + domain + "; Path=/;", creation_time,
-      server_time, /*cookie_partition_key=*/absl::nullopt,
+      server_time, /*cookie_partition_key=*/std::nullopt,
       /*block_truncated=*/true, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
 
   EXPECT_FALSE(CanonicalCookie::Create(
       http_url, "__HOST-A=B; Domain=" + domain + "; Path=/;", creation_time,
-      server_time, /*cookie_partition_key=*/absl::nullopt,
+      server_time, /*cookie_partition_key=*/std::nullopt,
       /*block_truncated=*/true, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
 
   EXPECT_FALSE(CanonicalCookie::Create(
       http_url, "__HoSt-A=B; Domain=" + domain + "; Path=/;", creation_time,
-      server_time, /*cookie_partition_key=*/absl::nullopt,
+      server_time, /*cookie_partition_key=*/std::nullopt,
       /*block_truncated=*/true, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
@@ -3077,43 +3075,43 @@
 
     EXPECT_TRUE(CanonicalCookie::Create(
         http_url, "__host-A=B; Domain=" + domain + "; Path=/;", creation_time,
-        server_time, /*cookie_partition_key=*/absl::nullopt,
+        server_time, /*cookie_partition_key=*/std::nullopt,
         /*block_truncated=*/true, &status));
 
     EXPECT_TRUE(CanonicalCookie::Create(
         http_url, "__HOST-A=B; Domain=" + domain + "; Path=/;", creation_time,
-        server_time, /*cookie_partition_key=*/absl::nullopt,
+        server_time, /*cookie_partition_key=*/std::nullopt,
         /*block_truncated=*/true, &status));
 
     EXPECT_TRUE(CanonicalCookie::Create(
         http_url, "__HoSt-A=B; Domain=" + domain + "; Path=/;", creation_time,
-        server_time, /*cookie_partition_key=*/absl::nullopt,
+        server_time, /*cookie_partition_key=*/std::nullopt,
         /*block_truncated=*/true, &status));
   }
 
   // Rules don't apply for a typoed prefix.
   EXPECT_TRUE(CanonicalCookie::Create(
       https_url, "__HostA=B; Domain=" + domain + "; Secure;", creation_time,
-      server_time, absl::nullopt /* cookie_partition_key */));
+      server_time, std::nullopt /* cookie_partition_key */));
 
   EXPECT_TRUE(CanonicalCookie::Create(
       https_url, "_Host-A=B; Domain=" + domain + "; Secure;", creation_time,
-      server_time, absl::nullopt /* cookie_partition_key */));
+      server_time, std::nullopt /* cookie_partition_key */));
 
   EXPECT_TRUE(CanonicalCookie::Create(
       https_url, "Host-A=B; Domain=" + domain + "; Secure;", creation_time,
-      server_time, absl::nullopt /* cookie_partition_key */));
+      server_time, std::nullopt /* cookie_partition_key */));
 
   // Hidden __Host- prefixes should be rejected.
   EXPECT_FALSE(CanonicalCookie::Create(
       https_url, "=__Host-A=B; Path=/; Secure;", creation_time, server_time,
-      /*cookie_partition_key=*/absl::nullopt, /*block_truncated=*/true,
+      /*cookie_partition_key=*/std::nullopt, /*block_truncated=*/true,
       &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
   EXPECT_FALSE(CanonicalCookie::Create(https_url, "=__Host-A; Path=/; Secure;",
                                        creation_time, server_time,
-                                       /*cookie_partition_key=*/absl::nullopt,
+                                       /*cookie_partition_key=*/std::nullopt,
                                        /*block_truncated=*/true, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
@@ -3121,27 +3119,27 @@
   // While tricky, this isn't considered hidden and is fine.
   EXPECT_TRUE(CanonicalCookie::Create(
       https_url, "A=__Host-A=B; Path=/; Secure;", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+      std::nullopt /* cookie_partition_key */));
 }
 
 TEST(CanonicalCookieTest, CanCreateSecureCookiesFromAnyScheme) {
   GURL http_url("http://www.example.com");
   GURL https_url("https://www.example.com");
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
 
   std::unique_ptr<CanonicalCookie> http_cookie_no_secure(
       CanonicalCookie::Create(http_url, "a=b", creation_time, server_time,
-                              absl::nullopt /* cookie_partition_key */));
+                              std::nullopt /* cookie_partition_key */));
   std::unique_ptr<CanonicalCookie> http_cookie_secure(CanonicalCookie::Create(
       http_url, "a=b; Secure", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+      std::nullopt /* cookie_partition_key */));
   std::unique_ptr<CanonicalCookie> https_cookie_no_secure(
       CanonicalCookie::Create(https_url, "a=b", creation_time, server_time,
-                              absl::nullopt /* cookie_partition_key */));
+                              std::nullopt /* cookie_partition_key */));
   std::unique_ptr<CanonicalCookie> https_cookie_secure(CanonicalCookie::Create(
       https_url, "a=b; Secure", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+      std::nullopt /* cookie_partition_key */));
 
   EXPECT_TRUE(http_cookie_no_secure.get());
   EXPECT_TRUE(http_cookie_secure.get());
@@ -3593,40 +3591,40 @@
   const char kVariantCountHistogram[] = "Cookie.CookiePrefix.CaseVariantCount";
   GURL https_url("https://www.example.test");
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
 
   EXPECT_FALSE(CanonicalCookie::Create(
       https_url, "__Host-A=B;", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+      std::nullopt /* cookie_partition_key */));
 
   histograms.ExpectBucketCount(kCookiePrefixHistogram,
                                CanonicalCookie::COOKIE_PREFIX_HOST, 1);
 
-  EXPECT_TRUE(CanonicalCookie::Create(
-      https_url, "__Host-A=B; Path=/; Secure", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+  EXPECT_TRUE(CanonicalCookie::Create(https_url, "__Host-A=B; Path=/; Secure",
+                                      creation_time, server_time,
+                                      std::nullopt /* cookie_partition_key */));
   histograms.ExpectBucketCount(kCookiePrefixHistogram,
                                CanonicalCookie::COOKIE_PREFIX_HOST, 2);
-  EXPECT_TRUE(CanonicalCookie::Create(
-      https_url, "__HostA=B; Path=/; Secure", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+  EXPECT_TRUE(CanonicalCookie::Create(https_url, "__HostA=B; Path=/; Secure",
+                                      creation_time, server_time,
+                                      std::nullopt /* cookie_partition_key */));
   histograms.ExpectBucketCount(kCookiePrefixHistogram,
                                CanonicalCookie::COOKIE_PREFIX_HOST, 2);
 
   EXPECT_FALSE(CanonicalCookie::Create(
       https_url, "__Secure-A=B;", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+      std::nullopt /* cookie_partition_key */));
 
   histograms.ExpectBucketCount(kCookiePrefixHistogram,
                                CanonicalCookie::COOKIE_PREFIX_SECURE, 1);
-  EXPECT_TRUE(CanonicalCookie::Create(
-      https_url, "__Secure-A=B; Path=/; Secure", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+  EXPECT_TRUE(CanonicalCookie::Create(https_url, "__Secure-A=B; Path=/; Secure",
+                                      creation_time, server_time,
+                                      std::nullopt /* cookie_partition_key */));
   histograms.ExpectBucketCount(kCookiePrefixHistogram,
                                CanonicalCookie::COOKIE_PREFIX_SECURE, 2);
-  EXPECT_TRUE(CanonicalCookie::Create(
-      https_url, "__SecureA=B; Path=/; Secure", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+  EXPECT_TRUE(CanonicalCookie::Create(https_url, "__SecureA=B; Path=/; Secure",
+                                      creation_time, server_time,
+                                      std::nullopt /* cookie_partition_key */));
   histograms.ExpectBucketCount(kCookiePrefixHistogram,
                                CanonicalCookie::COOKIE_PREFIX_SECURE, 2);
 
@@ -3636,18 +3634,18 @@
   const int sensitive_value_secure = histograms.GetBucketCount(
       kCookiePrefixHistogram, CanonicalCookie::COOKIE_PREFIX_SECURE);
 
-  EXPECT_TRUE(CanonicalCookie::Create(
-      https_url, "__SECURE-A=B; Path=/; Secure", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+  EXPECT_TRUE(CanonicalCookie::Create(https_url, "__SECURE-A=B; Path=/; Secure",
+                                      creation_time, server_time,
+                                      std::nullopt /* cookie_partition_key */));
   histograms.ExpectBucketCount(kCookiePrefixVariantHistogram,
                                CanonicalCookie::COOKIE_PREFIX_SECURE, 1);
   histograms.ExpectBucketCount(kCookiePrefixHistogram,
                                CanonicalCookie::COOKIE_PREFIX_SECURE,
                                sensitive_value_secure);
 
-  EXPECT_TRUE(CanonicalCookie::Create(
-      https_url, "__HOST-A=B; Path=/; Secure", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+  EXPECT_TRUE(CanonicalCookie::Create(https_url, "__HOST-A=B; Path=/; Secure",
+                                      creation_time, server_time,
+                                      std::nullopt /* cookie_partition_key */));
   histograms.ExpectBucketCount(kCookiePrefixVariantHistogram,
                                CanonicalCookie::COOKIE_PREFIX_HOST, 1);
   histograms.ExpectBucketCount(kCookiePrefixHistogram,
@@ -3661,11 +3659,11 @@
   // Invalid variants
   EXPECT_FALSE(CanonicalCookie::Create(
       https_url, "__SECURE-A=B", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+      std::nullopt /* cookie_partition_key */));
 
   EXPECT_FALSE(CanonicalCookie::Create(
       https_url, "__HOST-A=B;", creation_time, server_time,
-      absl::nullopt /* cookie_partition_key */));
+      std::nullopt /* cookie_partition_key */));
 
   histograms.ExpectBucketCount(kVariantValidHistogram, true, 2);
   histograms.ExpectBucketCount(kVariantValidHistogram, false, 2);
@@ -3685,7 +3683,7 @@
                              const std::string& value) {
     return CanonicalCookie::Create(
         test_url, name + "=" + value, /*creation_time=*/base::Time::Now(),
-        /*server_time=*/absl::nullopt, /*cookie_partition_key=*/absl::nullopt);
+        /*server_time=*/std::nullopt, /*cookie_partition_key=*/std::nullopt);
   };
 
   auto check_histograms = [&]() {
@@ -3724,35 +3722,35 @@
   std::vector<std::unique_ptr<CanonicalCookie>> cookies;
   GURL url("https://example.com/");
   base::Time now = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   MatchCookieLineToVector("", cookies);
 
   cookies.push_back(CanonicalCookie::Create(
-      url, "A=B", now, server_time, absl::nullopt /* cookie_partition_key */));
+      url, "A=B", now, server_time, std::nullopt /* cookie_partition_key */));
   MatchCookieLineToVector("A=B", cookies);
   // Nameless cookies are sent back without a prefixed '='.
   cookies.push_back(CanonicalCookie::Create(
-      url, "C", now, server_time, absl::nullopt /* cookie_partition_key */));
+      url, "C", now, server_time, std::nullopt /* cookie_partition_key */));
   MatchCookieLineToVector("A=B; C", cookies);
   // Cookies separated by ';'.
   cookies.push_back(CanonicalCookie::Create(
-      url, "D=E", now, server_time, absl::nullopt /* cookie_partition_key */));
+      url, "D=E", now, server_time, std::nullopt /* cookie_partition_key */));
   MatchCookieLineToVector("A=B; C; D=E", cookies);
   // BuildCookieLine doesn't reorder the list, it relies on the caller to do so.
   cookies.push_back(
       CanonicalCookie::Create(url, "F=G", now - base::Seconds(1), server_time,
-                              absl::nullopt /* cookie_partition_key */));
+                              std::nullopt /* cookie_partition_key */));
   MatchCookieLineToVector("A=B; C; D=E; F=G", cookies);
   // BuildCookieLine doesn't deduplicate.
   cookies.push_back(
       CanonicalCookie::Create(url, "D=E", now - base::Seconds(2), server_time,
-                              absl::nullopt /* cookie_partition_key */));
+                              std::nullopt /* cookie_partition_key */));
   MatchCookieLineToVector("A=B; C; D=E; F=G; D=E", cookies);
   // BuildCookieLine should match the spec in the case of an empty name with a
   // value containing an equal sign (even if it currently produces "invalid"
   // cookie lines).
   cookies.push_back(CanonicalCookie::Create(
-      url, "=H=I", now, server_time, absl::nullopt /* cookie_partition_key */));
+      url, "=H=I", now, server_time, std::nullopt /* cookie_partition_key */));
   MatchCookieLineToVector("A=B; C; D=E; F=G; D=E; H=I", cookies);
 }
 
@@ -3760,22 +3758,22 @@
   std::unique_ptr<CanonicalCookie> cookie;
   GURL url("https://example.com/");
   base::Time now = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
 
   cookie = CanonicalCookie::Create(url, "A=B", now, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_EQ("A=B; domain=example.com; path=/",
             CanonicalCookie::BuildCookieAttributesLine(*cookie));
   // Nameless cookies are sent back without a prefixed '='.
   cookie = CanonicalCookie::Create(url, "C", now, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_EQ("C; domain=example.com; path=/",
             CanonicalCookie::BuildCookieAttributesLine(*cookie));
   // BuildCookieAttributesLine should match the spec in the case of an empty
   // name with a value containing an equal sign (even if it currently produces
   // "invalid" cookie lines).
   cookie = CanonicalCookie::Create(url, "=H=I", now, server_time,
-                                   absl::nullopt /* cookie_partition_key */);
+                                   std::nullopt /* cookie_partition_key */);
   EXPECT_EQ("H=I; domain=example.com; path=/",
             CanonicalCookie::BuildCookieAttributesLine(*cookie));
   // BuildCookieAttributesLine should include all attributes.
@@ -3802,7 +3800,7 @@
       GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
       base::Time(), base::Time(), base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   EXPECT_TRUE(cc);
   EXPECT_EQ("A", cc->Name());
   EXPECT_EQ("B", cc->Value());
@@ -3824,7 +3822,7 @@
       GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
       two_hours_ago, base::Time(), base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   EXPECT_TRUE(cc);
   EXPECT_EQ(two_hours_ago, cc->CreationDate());
   EXPECT_TRUE(status.IsInclude());
@@ -3834,7 +3832,7 @@
       GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
       two_hours_ago, base::Time(), one_hour_ago, false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   EXPECT_TRUE(cc);
   EXPECT_EQ(one_hour_ago, cc->LastAccessDate());
   EXPECT_TRUE(status.IsInclude());
@@ -3844,7 +3842,7 @@
       GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
       base::Time(), one_hour_from_now, base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   EXPECT_TRUE(cc);
   EXPECT_EQ(one_hour_from_now, cc->ExpiryDate());
   EXPECT_TRUE(status.IsInclude());
@@ -3854,7 +3852,7 @@
       GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
       base::Time(), base::Time(), base::Time(), true /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   EXPECT_TRUE(cc);
   EXPECT_TRUE(cc->SecureAttribute());
   EXPECT_TRUE(status.IsInclude());
@@ -3864,7 +3862,7 @@
       GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
       base::Time(), base::Time(), base::Time(), false /*secure*/,
       true /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   EXPECT_TRUE(cc);
   EXPECT_TRUE(cc->IsHttpOnly());
   EXPECT_TRUE(status.IsInclude());
@@ -3874,7 +3872,7 @@
       GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
       base::Time(), base::Time(), base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status);
+      std::nullopt /*partition_key*/, &status);
   EXPECT_TRUE(cc);
   EXPECT_EQ(CookieSameSite::LAX_MODE, cc->SameSite());
   EXPECT_TRUE(status.IsInclude());
@@ -3884,7 +3882,7 @@
       GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
       base::Time(), base::Time(), base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW,
-      absl::nullopt /*partition_key*/, &status);
+      std::nullopt /*partition_key*/, &status);
   EXPECT_TRUE(cc);
   EXPECT_EQ(COOKIE_PRIORITY_LOW, cc->Priority());
   EXPECT_TRUE(status.IsInclude());
@@ -3894,7 +3892,7 @@
       GURL("https://www.foo.com"), "A", "B", "www.foo.com", "/foo",
       base::Time(), base::Time(), base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   EXPECT_TRUE(cc);
   EXPECT_TRUE(cc->IsDomainCookie());
   EXPECT_TRUE(status.IsInclude());
@@ -3923,19 +3921,19 @@
       GURL("http://www.foo.com/foo"), "A", "B", std::string(), "/foo",
       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status));
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
       GURL("http://www.foo.com/bar"), "C", "D", "www.foo.com", "/",
       two_hours_ago, base::Time(), one_hour_ago, false /*secure*/,
       true /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status));
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
       GURL("https://www.foo.com"), "E", "F", std::string(), std::string(),
       base::Time(), base::Time(), base::Time(), true /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status));
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
 
   // Test the file:// protocol.
@@ -3943,19 +3941,19 @@
       GURL("file:///"), "A", "B", std::string(), "/foo", one_hour_ago,
       one_hour_from_now, base::Time(), false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
       GURL("file:///home/user/foo.txt"), "A", "B", std::string(), "/foo",
       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status));
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
       GURL("file:///home/user/foo.txt"), "A", "B", "home", "/foo", one_hour_ago,
       one_hour_from_now, base::Time(), false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
 
@@ -3965,7 +3963,7 @@
       base::Time(), base::Time(), base::Time(), /*secure=*/false,
       /*http_only=*/false, CookieSameSite::NO_RESTRICTION,
       COOKIE_PRIORITY_DEFAULT,
-      /*partition_key=*/absl::nullopt, &status));
+      /*partition_key=*/std::nullopt, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_DISALLOWED_CHARACTER}));
   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
@@ -3973,7 +3971,7 @@
       base::Time(), base::Time(), base::Time(), /*secure=*/false,
       /*http_only=*/false, CookieSameSite::NO_RESTRICTION,
       COOKIE_PRIORITY_DEFAULT,
-      /*partition_key=*/absl::nullopt, &status));
+      /*partition_key=*/std::nullopt, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_DISALLOWED_CHARACTER}));
   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
@@ -3981,7 +3979,7 @@
       base::Time(), base::Time(), base::Time(), /*secure=*/false,
       /*http_only=*/false, CookieSameSite::NO_RESTRICTION,
       COOKIE_PRIORITY_DEFAULT,
-      /*partition_key=*/absl::nullopt, &status));
+      /*partition_key=*/std::nullopt, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_DISALLOWED_CHARACTER}));
   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
@@ -3989,7 +3987,7 @@
       one_hour_ago, one_hour_from_now, base::Time(), /*secure=*/false,
       /*http_only=*/false, CookieSameSite::NO_RESTRICTION,
       COOKIE_PRIORITY_DEFAULT,
-      /*partition_key=*/absl::nullopt, &status));
+      /*partition_key=*/std::nullopt, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_DISALLOWED_CHARACTER}));
   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
@@ -3997,7 +3995,7 @@
       base::Time(), base::Time(), base::Time(), /*secure=*/false,
       /*http_only=*/false, CookieSameSite::NO_RESTRICTION,
       COOKIE_PRIORITY_DEFAULT,
-      /*partition_key=*/absl::nullopt, &status));
+      /*partition_key=*/std::nullopt, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_DISALLOWED_CHARACTER}));
   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
@@ -4005,28 +4003,28 @@
       base::Time(), base::Time(), base::Time(), /*secure=*/false,
       /*http_only=*/false, CookieSameSite::NO_RESTRICTION,
       COOKIE_PRIORITY_DEFAULT,
-      /*partition_key=*/absl::nullopt, &status));
+      /*partition_key=*/std::nullopt, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_DISALLOWED_CHARACTER}));
   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
       GURL("http://www.foo.com"), "A", "B", "www.foo.com ", "/foo",
       base::Time(), base::Time(), base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status));
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
       GURL("http://www.foo.com/foo"), "A", "B", "foo.ozzzzzzle", "/foo",
       base::Time(), base::Time(), base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status));
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
       GURL("http://www.foo.com/foo"), "A", "B", std::string(), "foo",
       base::Time(), base::Time(), base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status));
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
@@ -4034,14 +4032,14 @@
       base::Time(), base::Time(), base::Time(), /*secure=*/false,
       /*http_only=*/false, CookieSameSite::NO_RESTRICTION,
       COOKIE_PRIORITY_DEFAULT,
-      /*partition_key=*/absl::nullopt, &status));
+      /*partition_key=*/std::nullopt, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_DISALLOWED_CHARACTER}));
   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
       GURL("http://www.foo.com/foo"), "A", "B", "%2Efoo.com", "/foo",
       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status));
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
@@ -4049,7 +4047,7 @@
       "domaintest.%E3%81%BF%E3%82%93%E3%81%AA", "/foo", base::Time(),
       base::Time(), base::Time(), false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
 
@@ -4061,7 +4059,7 @@
       GURL("http://www.foo.com/foo"), "A", "B", "www.foo.com", "/foo",
       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   ASSERT_TRUE(cc);
   EXPECT_TRUE(cc->IsDomainCookie());
   EXPECT_EQ(".www.foo.com", cc->Domain());
@@ -4071,7 +4069,7 @@
       GURL("http://www.foo.com/foo"), "A", "B", ".www.foo.com", "/foo",
       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   ASSERT_TRUE(cc);
   EXPECT_TRUE(cc->IsDomainCookie());
   EXPECT_EQ(".www.foo.com", cc->Domain());
@@ -4081,7 +4079,7 @@
       GURL("http://www.foo.com/foo"), "A", "B", ".foo.com", "/foo",
       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   ASSERT_TRUE(cc);
   EXPECT_TRUE(cc->IsDomainCookie());
   EXPECT_EQ(".foo.com", cc->Domain());
@@ -4091,7 +4089,7 @@
       GURL("http://www.foo.com/foo"), "A", "B", ".www2.www.foo.com", "/foo",
       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   EXPECT_FALSE(cc);
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
@@ -4102,7 +4100,7 @@
       base::Time(), base::Time(), /*secure=*/true,
       /*http_only=*/false, CookieSameSite::NO_RESTRICTION,
       COOKIE_PRIORITY_DEFAULT,
-      /*partition_key=*/absl::nullopt, &status));
+      /*partition_key=*/std::nullopt, &status));
   EXPECT_TRUE(status.IsInclude());
   EXPECT_TRUE(status.HasExactlyWarningReasonsForTesting(
       {CookieInclusionStatus::WARN_TENTATIVELY_ALLOWING_SECURE_SOURCE_SCHEME}));
@@ -4112,7 +4110,7 @@
       GURL("http://www.foo.com"), "A", "B", std::string(), "/foo", base::Time(),
       base::Time(), base::Time::Now(), false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
 
@@ -4121,7 +4119,7 @@
       GURL("http://www.foo.com"), "A", "B", "www.bar.com", "/", base::Time(),
       base::Time(), base::Time(), false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
 
@@ -4130,7 +4128,7 @@
       GURL("http://www.foo.com"), "A", "B", std::string(), "/foo\x7F",
       base::Time(), base::Time(), base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   ASSERT_TRUE(cc);
   EXPECT_EQ("/foo%7F", cc->Path());
   EXPECT_TRUE(status.IsInclude());
@@ -4164,7 +4162,7 @@
       GURL("http://www.foo.com"), "A", "B", std::string(), initial,
       base::Time(), base::Time(), base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   ASSERT_TRUE(cc);
   EXPECT_EQ(expected, cc->Path());
   EXPECT_TRUE(status.IsInclude());
@@ -4174,7 +4172,7 @@
       GURL("http://www.foo.com"), "", "", std::string(), "/", base::Time(),
       base::Time(), base::Time(), false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_NO_COOKIE_CONTENT}));
 
@@ -4191,7 +4189,7 @@
       GURL("http://www.foo.com"), "", "ambiguous=value", std::string(),
       std::string(), base::Time(), base::Time(), base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   EXPECT_TRUE(cc);
   std::vector<std::unique_ptr<CanonicalCookie>> cookies;
   cookies.push_back(std::move(cc));
@@ -4205,7 +4203,7 @@
       std::string(), base::Time(), base::Time(), base::Time(), /*secure=*/false,
       /*http_only=*/false, CookieSameSite::NO_RESTRICTION,
       COOKIE_PRIORITY_DEFAULT,
-      /*partition_key=*/absl::nullopt, &status));
+      /*partition_key=*/std::nullopt, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_DISALLOWED_CHARACTER}));
 
@@ -4214,13 +4212,13 @@
       GURL("https://www.foo.com"), "__Secure-A", "B", ".www.foo.com", "/",
       two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
       GURL("https://www.foo.com"), "__Secure-A", "B", ".www.foo.com", "/",
       two_hours_ago, one_hour_from_now, one_hour_ago, false, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
 
@@ -4229,13 +4227,13 @@
       GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
       two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
       GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
       two_hours_ago, one_hour_from_now, one_hour_ago, false, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
 
@@ -4244,13 +4242,13 @@
       GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
       two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
       GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/foo",
       two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
 
@@ -4259,13 +4257,13 @@
       GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
       two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
       GURL("https://www.foo.com"), "__Host-A", "B", ".www.foo.com", "/",
       two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
 
@@ -4275,7 +4273,7 @@
       GURL("https://www.foo.com"), "A", "B", std::string(), "/", two_hours_ago,
       one_hour_from_now, one_hour_ago, true, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
 
   // Without __Host- prefix, this is a valid domain (not host) cookie.
@@ -4283,7 +4281,7 @@
       GURL("https://www.foo.com"), "A", "B", ".www.foo.com", "/", two_hours_ago,
       one_hour_from_now, one_hour_ago, true, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
 
   // The __Host- prefix should not prevent otherwise-valid host cookies from
@@ -4292,13 +4290,13 @@
       GURL("https://127.0.0.1"), "A", "B", std::string(), "/", two_hours_ago,
       one_hour_from_now, one_hour_ago, true, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
       GURL("https://127.0.0.1"), "__Host-A", "B", std::string(), "/",
       two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
 
   // Host cookies should not specify domain unless it is an IP address that
@@ -4307,13 +4305,13 @@
       GURL("https://127.0.0.1"), "A", "B", "127.0.0.1", "/", two_hours_ago,
       one_hour_from_now, one_hour_ago, true, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
       GURL("https://127.0.0.1"), "__Host-A", "B", "127.0.0.1", "/",
       two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
 
   // Cookies with hidden prefixes should be rejected.
@@ -4322,7 +4320,7 @@
       GURL("https://www.foo.com"), "", "__Host-A=B", "", "/", two_hours_ago,
       one_hour_from_now, one_hour_ago, true, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
 
@@ -4330,7 +4328,7 @@
       GURL("https://www.foo.com"), "", "__Host-A", "", "/", two_hours_ago,
       one_hour_from_now, one_hour_ago, true, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
 
@@ -4338,7 +4336,7 @@
       GURL("https://www.foo.com"), "", "__Secure-A=B", "", "/", two_hours_ago,
       one_hour_from_now, one_hour_ago, true, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
 
@@ -4346,7 +4344,7 @@
       GURL("https://www.foo.com"), "", "__Secure-A", "", "/", two_hours_ago,
       one_hour_from_now, one_hour_ago, true, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
 
@@ -4355,14 +4353,14 @@
       GURL("https://www.foo.com"), "A", "__Host-A=B", "", "/", two_hours_ago,
       one_hour_from_now, one_hour_ago, true, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
 
   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
       GURL("https://www.foo.com"), "A", "__Secure-A=B", "", "/", two_hours_ago,
       one_hour_from_now, one_hour_ago, true, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
 
   // Partitioned attribute requires __Host-.
@@ -4371,7 +4369,7 @@
       GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
       two_hours_ago, one_hour_from_now, one_hour_ago, true /*secure*/, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
+      std::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
           GURL("https://toplevelsite.com"))),
       &status));
   EXPECT_TRUE(status.IsInclude());
@@ -4381,7 +4379,7 @@
       GURL("https://www.foo.com"), "A", "B", std::string(), "/", two_hours_ago,
       one_hour_from_now, one_hour_ago, true /*secure*/, false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
+      std::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
           GURL("https://toplevelsite.com"))),
       &status));
   EXPECT_TRUE(status.IsInclude());
@@ -4392,7 +4390,7 @@
       GURL("https://www.foo.com"), "A", "B", std::string(), "/", two_hours_ago,
       one_hour_from_now, one_hour_ago, /*secure=*/false, /*http_only=*/false,
       CookieSameSite::LAX_MODE, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
+      std::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
           GURL("https://toplevelsite.com"))),
       &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
@@ -4404,7 +4402,7 @@
       two_hours_ago, one_hour_from_now, one_hour_ago, /*secure=*/true,
       /*http_only=*/false, CookieSameSite::NO_RESTRICTION,
       CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
+      std::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
           GURL("https://toplevelsite.com"))),
       &status));
   EXPECT_TRUE(status.IsInclude());
@@ -4414,7 +4412,7 @@
       GURL("https://www.foo.com"), "A", "B", ".foo.com", "/", two_hours_ago,
       one_hour_from_now, one_hour_ago, /*secure=*/true, /*http_only=*/false,
       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
-      absl::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
+      std::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
           GURL("https://toplevelsite.com"))),
       &status));
   EXPECT_TRUE(status.IsInclude());
@@ -4430,21 +4428,21 @@
       GURL("http://..."), "A", "B", "...", "/", base::Time(), base::Time(),
       base::Time(), false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
       GURL("http://."), "A", "B", std::string(), "/", base::Time(),
       base::Time(), base::Time(), false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
       GURL("http://.chromium.org"), "A", "B", ".chromium.org", "/",
       base::Time(), base::Time(), base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status));
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
 
@@ -4454,7 +4452,7 @@
       GURL("file://[A::]"), "A", "B", "[A::]", "", base::Time(), base::Time(),
       base::Time(), false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status));
+      std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
 
   // On Windows, URLs beginning with two backslashes are considered file
@@ -4463,7 +4461,7 @@
       GURL("\\\\[A::]"), "A", "B", "[A::]", "", base::Time(), base::Time(),
       base::Time(), false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status);
+      std::nullopt /*partition_key*/, &status);
 #if BUILDFLAG(IS_WIN)
   EXPECT_TRUE(double_backslash_ipv6_cookie);
   EXPECT_TRUE(double_backslash_ipv6_cookie->IsCanonical());
@@ -4478,7 +4476,7 @@
   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
       GURL(""), "", "", "", "", base::Time(), base::Time(), base::Time::Now(),
       true /*secure*/, true /*httponly*/, CookieSameSite::STRICT_MODE,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status));
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_NO_COOKIE_CONTENT,
        CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE,
@@ -4494,32 +4492,32 @@
       GURL("http://www.foo.com/foo"), max_name, "", std::string(), "/foo",
       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status));
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
       GURL("http://www.foo.com/foo"), "", max_value, std::string(), "/foo",
       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status));
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
       GURL("http://www.foo.com/foo"), almost_max_name, "b", std::string(),
       "/foo", one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status));
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
       GURL("http://www.foo.com/foo"), "a", almost_max_value, std::string(),
       "/foo", one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status));
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status));
   EXPECT_TRUE(status.IsInclude());
 
   cc = CanonicalCookie::CreateSanitizedCookie(
       GURL("http://www.foo.com/foo"), max_name, "X", std::string(), "/foo",
       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   EXPECT_FALSE(cc);
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_NAME_VALUE_PAIR_EXCEEDS_MAX_SIZE}));
@@ -4528,7 +4526,7 @@
       GURL("http://www.foo.com/foo"), "X", max_value, std::string(), "/foo",
       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   EXPECT_FALSE(cc);
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_NAME_VALUE_PAIR_EXCEEDS_MAX_SIZE}));
@@ -4544,7 +4542,7 @@
       GURL("http://www.foo.com" + max_path), "name", "value", std::string(),
       max_path, one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   EXPECT_TRUE(cc);
   EXPECT_EQ(max_path, cc->Path());
   EXPECT_TRUE(status.IsInclude());
@@ -4554,7 +4552,7 @@
       std::string(), too_long_path, one_hour_ago, one_hour_from_now,
       base::Time(), false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status);
+      std::nullopt /*partition_key*/, &status);
   EXPECT_FALSE(cc);
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE}));
@@ -4567,7 +4565,7 @@
       std::string(), std::string(), one_hour_ago, one_hour_from_now,
       base::Time(), false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status);
+      std::nullopt /*partition_key*/, &status);
   EXPECT_TRUE(cc);
   EXPECT_EQ(too_long_path, cc->Path());
   EXPECT_TRUE(status.IsInclude());
@@ -4585,7 +4583,7 @@
       std::string(), expanding_path, one_hour_ago, one_hour_from_now,
       base::Time(), false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, &status);
+      std::nullopt /*partition_key*/, &status);
   EXPECT_FALSE(cc);
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE}));
@@ -4600,7 +4598,7 @@
       GURL("http://" + max_domain + "/"), "name", "value", max_domain, "/",
       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   EXPECT_TRUE(cc);
   EXPECT_EQ(max_domain, cc->DomainWithoutDot());
   EXPECT_TRUE(status.IsInclude());
@@ -4608,7 +4606,7 @@
       GURL("http://www.domain-from-url.com/"), "name", "value", too_long_domain,
       "/", one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   EXPECT_FALSE(cc);
   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
       {CookieInclusionStatus::EXCLUDE_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE}));
@@ -4619,7 +4617,7 @@
       GURL("http://" + too_long_domain + "/"), "name", "value", std::string(),
       "/", one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
-      COOKIE_PRIORITY_DEFAULT, absl::nullopt /*partition_key*/, &status);
+      COOKIE_PRIORITY_DEFAULT, std::nullopt /*partition_key*/, &status);
   EXPECT_TRUE(cc);
   EXPECT_EQ(too_long_domain, cc->DomainWithoutDot());
   EXPECT_TRUE(status.IsInclude());
@@ -4638,7 +4636,7 @@
 
   // A secure url doesn't need "Secure" to have a source scheme of secure
   cc = CanonicalCookie::Create(secure_url, "a=b; SameSite=Lax",
-                               base::Time::Now(), absl::nullopt, absl::nullopt,
+                               base::Time::Now(), std::nullopt, std::nullopt,
                                /*block_truncated=*/true, &status);
   EXPECT_TRUE(cc);
   EXPECT_TRUE(status.IsInclude());
@@ -4649,7 +4647,7 @@
 
   // But having "Secure" shouldn't change anything
   cc = CanonicalCookie::Create(secure_url, "a=b; SameSite=Lax; Secure",
-                               base::Time::Now(), absl::nullopt, absl::nullopt,
+                               base::Time::Now(), std::nullopt, std::nullopt,
                                /*block_truncated=*/true, &status);
   EXPECT_TRUE(cc);
   EXPECT_TRUE(status.IsInclude());
@@ -4661,7 +4659,7 @@
   // An insecure url without "Secure" should get a non-secure source scheme and
   // a default port.
   cc = CanonicalCookie::Create(insecure_url, "a=b; SameSite=Lax",
-                               base::Time::Now(), absl::nullopt, absl::nullopt,
+                               base::Time::Now(), std::nullopt, std::nullopt,
                                /*block_truncated=*/true, &status);
   EXPECT_TRUE(cc);
   EXPECT_TRUE(status.IsInclude());
@@ -4674,7 +4672,7 @@
   // modified port. It should also get a warning that a secure source scheme was
   // tentatively allowed.
   cc = CanonicalCookie::Create(insecure_url, "a=b; SameSite=Lax; Secure",
-                               base::Time::Now(), absl::nullopt, absl::nullopt,
+                               base::Time::Now(), std::nullopt, std::nullopt,
                                /*block_truncated=*/true, &status);
   EXPECT_TRUE(cc);
   EXPECT_TRUE(status.IsInclude());
@@ -4687,7 +4685,7 @@
   // An insecure url with a non-default port without "Secure" should get a
   // non-secure source scheme and keep its port.
   cc = CanonicalCookie::Create(insecure_url_custom_port, "a=b; SameSite=Lax",
-                               base::Time::Now(), absl::nullopt, absl::nullopt,
+                               base::Time::Now(), std::nullopt, std::nullopt,
                                /*block_truncated=*/true, &status);
   EXPECT_TRUE(cc);
   EXPECT_TRUE(status.IsInclude());
@@ -4701,7 +4699,7 @@
   // source scheme was tentatively allowed.
   cc = CanonicalCookie::Create(
       insecure_url_custom_port, "a=b; SameSite=Lax; Secure", base::Time::Now(),
-      absl::nullopt, absl::nullopt, /*block_truncated=*/true, &status);
+      std::nullopt, std::nullopt, /*block_truncated=*/true, &status);
   EXPECT_TRUE(cc);
   EXPECT_TRUE(status.IsInclude());
   EXPECT_TRUE(status.HasExactlyWarningReasonsForTesting(
@@ -4727,7 +4725,7 @@
       secure_url, "a", "b", "example.com", "", base::Time(), base::Time(),
       base::Time(), /*secure=*/false, /*http_only=*/false,
       CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT,
-      /*partition_key=*/absl::nullopt, &status);
+      /*partition_key=*/std::nullopt, &status);
   EXPECT_TRUE(cc);
   EXPECT_TRUE(status.IsInclude());
   EXPECT_FALSE(status.ShouldWarn());
@@ -4740,7 +4738,7 @@
       secure_url, "a", "b", "example.com", "", base::Time(), base::Time(),
       base::Time(), /*secure=*/true, /*http_only=*/false,
       CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT,
-      /*partition_key=*/absl::nullopt, &status);
+      /*partition_key=*/std::nullopt, &status);
   EXPECT_TRUE(cc);
   EXPECT_TRUE(status.IsInclude());
   EXPECT_FALSE(status.ShouldWarn());
@@ -4754,7 +4752,7 @@
       insecure_url, "a", "b", "example.com", "", base::Time(), base::Time(),
       base::Time(), /*secure=*/false, /*http_only=*/false,
       CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT,
-      /*partition_key=*/absl::nullopt, &status);
+      /*partition_key=*/std::nullopt, &status);
   EXPECT_TRUE(cc);
   EXPECT_TRUE(status.IsInclude());
   EXPECT_FALSE(status.ShouldWarn());
@@ -4769,7 +4767,7 @@
       insecure_url, "a", "b", "example.com", "", base::Time(), base::Time(),
       base::Time(), /*secure=*/true, /*http_only=*/false,
       CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT,
-      /*partition_key=*/absl::nullopt, &status);
+      /*partition_key=*/std::nullopt, &status);
   EXPECT_TRUE(cc);
   EXPECT_TRUE(status.IsInclude());
   EXPECT_TRUE(status.HasExactlyWarningReasonsForTesting(
@@ -4784,7 +4782,7 @@
       insecure_url_custom_port, "a", "b", "example.com", "", base::Time(),
       base::Time(), base::Time(), /*secure=*/false, /*http_only=*/false,
       CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT,
-      /*partition_key=*/absl::nullopt, &status);
+      /*partition_key=*/std::nullopt, &status);
   EXPECT_TRUE(cc);
   EXPECT_TRUE(status.IsInclude());
   EXPECT_FALSE(status.ShouldWarn());
@@ -4799,7 +4797,7 @@
       insecure_url_custom_port, "a", "b", "example.com", "", base::Time(),
       base::Time(), base::Time(), /*secure=*/true, /*http_only=*/false,
       CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT,
-      /*partition_key=*/absl::nullopt, &status);
+      /*partition_key=*/std::nullopt, &status);
   EXPECT_TRUE(cc);
   EXPECT_TRUE(status.IsInclude());
   EXPECT_TRUE(status.HasExactlyWarningReasonsForTesting(
@@ -4818,7 +4816,7 @@
       "A", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
       one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, CookieSourceScheme::kSecure, 87);
+      std::nullopt /*partition_key*/, CookieSourceScheme::kSecure, 87);
   EXPECT_TRUE(cc);
   EXPECT_EQ("A", cc->Name());
   EXPECT_EQ("B", cc->Value());
@@ -4843,7 +4841,7 @@
       "A\n", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
       one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, CookieSourceScheme::kSecure, 80));
+      std::nullopt /*partition_key*/, CookieSourceScheme::kSecure, 80));
 
   // If the port information gets corrupted out of the valid range
   // FromStorage() should result in a PORT_INVALID.
@@ -4851,7 +4849,7 @@
       "A", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
       one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, CookieSourceScheme::kSecure, 80000);
+      std::nullopt /*partition_key*/, CookieSourceScheme::kSecure, 80000);
 
   EXPECT_EQ(cc2->SourcePort(), url::PORT_INVALID);
 
@@ -4860,7 +4858,7 @@
       "A", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
       one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, CookieSourceScheme::kSecure,
+      std::nullopt /*partition_key*/, CookieSourceScheme::kSecure,
       url::PORT_UNSPECIFIED);
   EXPECT_EQ(cc3->SourcePort(), url::PORT_UNSPECIFIED);
 
@@ -4869,7 +4867,7 @@
       "A", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
       one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, CookieSourceScheme::kSecure,
+      std::nullopt /*partition_key*/, CookieSourceScheme::kSecure,
       url::PORT_INVALID);
   EXPECT_EQ(cc4->SourcePort(), url::PORT_INVALID);
 }
@@ -5470,7 +5468,7 @@
 
   std::unique_ptr<CanonicalCookie> cookie_with_long_path =
       CanonicalCookie::Create(url, "A=B; Path=/" + long_path, current_time,
-                              absl::nullopt, absl::nullopt,
+                              std::nullopt, std::nullopt,
                               /*block_truncated=*/true, &status);
   CookieAccessResult cookie_access_result(status);
   CookieOptions cookie_with_long_path_options;
@@ -5833,7 +5831,7 @@
       "A", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
       one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, CookieSourceScheme::kSecure, 87));
+      std::nullopt /*partition_key*/, CookieSourceScheme::kSecure, 87));
 
   histograms.ExpectBucketCount(kFromStorageWithValidLengthHistogram, kInValid,
                                0);
@@ -5846,12 +5844,12 @@
       kCookieBig, "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
       one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, CookieSourceScheme::kSecure, 87));
+      std::nullopt /*partition_key*/, CookieSourceScheme::kSecure, 87));
   EXPECT_TRUE(CanonicalCookie::FromStorage(
       "A", kCookieBig, "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
       one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-      absl::nullopt /*partition_key*/, CookieSourceScheme::kSecure, 87));
+      std::nullopt /*partition_key*/, CookieSourceScheme::kSecure, 87));
 
   histograms.ExpectBucketCount(kFromStorageWithValidLengthHistogram, kInValid,
                                2);
@@ -6018,13 +6016,13 @@
 
   CanonicalCookie::Create(
       GURL("https://www.example.com/"), "__Secure-abc=123; Secure",
-      base::Time::Now() /* Creation time */, absl::nullopt /* Server Time */,
-      absl::nullopt /* cookie_partition_key */);
+      base::Time::Now() /* Creation time */, std::nullopt /* Server Time */,
+      std::nullopt /* cookie_partition_key */);
 
   CanonicalCookie::Create(
       GURL("https://www.example.com/"), "__Host-abc=123; Secure; Path=/",
-      base::Time::Now() /* Creation time */, absl::nullopt /* Server Time */,
-      absl::nullopt /* cookie_partition_key */);
+      base::Time::Now() /* Creation time */, std::nullopt /* Server Time */,
+      std::nullopt /* cookie_partition_key */);
 
   // Cookie prefixes shouldn't count.
   histograms.ExpectTotalCount(kDoubleUnderscorePrefixHistogram, 2);
@@ -6032,34 +6030,34 @@
 
   CanonicalCookie::Create(GURL("https://www.example.com/"), "f__oo=bar",
                           base::Time::Now() /* Creation time */,
-                          absl::nullopt /* Server Time */,
-                          absl::nullopt /* cookie_partition_key */);
+                          std::nullopt /* Server Time */,
+                          std::nullopt /* cookie_partition_key */);
 
   CanonicalCookie::Create(GURL("https://www.example.com/"), "foo=__bar",
                           base::Time::Now() /* Creation time */,
-                          absl::nullopt /* Server Time */,
-                          absl::nullopt /* cookie_partition_key */);
+                          std::nullopt /* Server Time */,
+                          std::nullopt /* cookie_partition_key */);
 
   CanonicalCookie::Create(GURL("https://www.example.com/"), "_foo=bar",
                           base::Time::Now() /* Creation time */,
-                          absl::nullopt /* Server Time */,
-                          absl::nullopt /* cookie_partition_key */);
+                          std::nullopt /* Server Time */,
+                          std::nullopt /* cookie_partition_key */);
 
   CanonicalCookie::Create(GURL("https://www.example.com/"), "_f_oo=bar",
                           base::Time::Now() /* Creation time */,
-                          absl::nullopt /* Server Time */,
-                          absl::nullopt /* cookie_partition_key */);
+                          std::nullopt /* Server Time */,
+                          std::nullopt /* cookie_partition_key */);
 
   // These should be counted.
   CanonicalCookie::Create(GURL("https://www.example.com/"), "__foo=bar",
                           base::Time::Now() /* Creation time */,
-                          absl::nullopt /* Server Time */,
-                          absl::nullopt /* cookie_partition_key */);
+                          std::nullopt /* Server Time */,
+                          std::nullopt /* cookie_partition_key */);
 
   CanonicalCookie::Create(GURL("https://www.example.com/"), "___foo=bar",
                           base::Time::Now() /* Creation time */,
-                          absl::nullopt /* Server Time */,
-                          absl::nullopt /* cookie_partition_key */);
+                          std::nullopt /* Server Time */,
+                          std::nullopt /* cookie_partition_key */);
 
   histograms.ExpectTotalCount(kDoubleUnderscorePrefixHistogram, 8);
   histograms.ExpectBucketCount(kDoubleUnderscorePrefixHistogram, false, 6);
@@ -6088,7 +6086,7 @@
 
   // Nonced-partitioned cookie should always be 3p context.
   auto partition_key_with_nonce =
-      absl::make_optional(CookiePartitionKey::FromURLForTesting(
+      std::make_optional(CookiePartitionKey::FromURLForTesting(
           GURL("https://x.y"), base::UnguessableToken::Create()));
   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
                   "A", "B", "x.y", "/foo/bar", base::Time(), base::Time(),
diff --git a/net/cookies/cookie_access_delegate.h b/net/cookies/cookie_access_delegate.h
index 0eec248..f43f9d8e 100644
--- a/net/cookies/cookie_access_delegate.h
+++ b/net/cookies/cookie_access_delegate.h
@@ -5,6 +5,8 @@
 #ifndef NET_COOKIES_COOKIE_ACCESS_DELEGATE_H_
 #define NET_COOKIES_COOKIE_ACCESS_DELEGATE_H_
 
+#include <optional>
+
 #include "base/containers/flat_map.h"
 #include "base/containers/flat_set.h"
 #include "base/functional/callback_forward.h"
@@ -16,7 +18,6 @@
 #include "net/first_party_sets/first_party_set_entry.h"
 #include "net/first_party_sets/first_party_set_metadata.h"
 #include "net/first_party_sets/first_party_sets_cache_filter.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace net {
@@ -59,7 +60,7 @@
   // with the result. The callback will be invoked iff the return value is
   // nullopt; i.e. a result will be provided via return value or callback, but
   // not both, and not neither.
-  [[nodiscard]] virtual absl::optional<
+  [[nodiscard]] virtual std::optional<
       std::pair<FirstPartySetMetadata, FirstPartySetsCacheFilter::MatchInfo>>
   ComputeFirstPartySetMetadataMaybeAsync(
       const net::SchemefulSite& site,
@@ -76,7 +77,7 @@
   // with the result. The callback will be invoked iff the return value is
   // nullopt; i.e. a result will be provided via return value or callback, but
   // not both, and not neither.
-  [[nodiscard]] virtual absl::optional<
+  [[nodiscard]] virtual std::optional<
       base::flat_map<net::SchemefulSite, net::FirstPartySetEntry>>
   FindFirstPartySetEntries(
       const base::flat_set<net::SchemefulSite>& sites,
diff --git a/net/cookies/cookie_change_dispatcher.h b/net/cookies/cookie_change_dispatcher.h
index 62cfee9..68f9db1 100644
--- a/net/cookies/cookie_change_dispatcher.h
+++ b/net/cookies/cookie_change_dispatcher.h
@@ -140,7 +140,7 @@
   AddCallbackForCookie(
       const GURL& url,
       const std::string& name,
-      const absl::optional<CookiePartitionKey>& cookie_partition_key,
+      const std::optional<CookiePartitionKey>& cookie_partition_key,
       CookieChangeCallback callback) = 0;
 
   // Observe changes to the cookies that would be sent for a request to `url`.
@@ -153,7 +153,7 @@
   [[nodiscard]] virtual std::unique_ptr<CookieChangeSubscription>
   AddCallbackForUrl(
       const GURL& url,
-      const absl::optional<CookiePartitionKey>& cookie_partition_key,
+      const std::optional<CookiePartitionKey>& cookie_partition_key,
       CookieChangeCallback callback) = 0;
 
   // Observe all the CookieStore's changes.
diff --git a/net/cookies/cookie_deletion_info.h b/net/cookies/cookie_deletion_info.h
index 40f4443..c1d82f9 100644
--- a/net/cookies/cookie_deletion_info.h
+++ b/net/cookies/cookie_deletion_info.h
@@ -5,6 +5,7 @@
 #ifndef NET_COOKIES_COOKIE_DELETION_INFO_H_
 #define NET_COOKIES_COOKIE_DELETION_INFO_H_
 
+#include <optional>
 #include <set>
 #include <string>
 
@@ -12,7 +13,6 @@
 #include "net/cookies/canonical_cookie.h"
 #include "net/cookies/cookie_constants.h"
 #include "net/cookies/cookie_partition_key_collection.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -111,14 +111,14 @@
   SessionControl session_control = SessionControl::IGNORE_CONTROL;
 
   // If has a value then cookie.Host() must equal |host|.
-  absl::optional<std::string> host;
+  std::optional<std::string> host;
 
   // If has a value then cookie.Name() must equal |name|.
-  absl::optional<std::string> name;
+  std::optional<std::string> name;
 
   // If has a value then will match if the cookie being evaluated would be
   // included for a request of |url|.
-  absl::optional<GURL> url;
+  std::optional<GURL> url;
 
   // If has a value then any cookie with a domain/ip contained in this set
   // will be deleted (assuming other fields match).
@@ -128,7 +128,7 @@
   // Note: |domains_and_ips_to_ignore| takes precedence. For example if this
   // has a value of ["A", "B"] and |domains_and_ips_to_ignore| is ["B", "C"]
   // then only "A" will be deleted.
-  absl::optional<std::set<std::string>> domains_and_ips_to_delete;
+  std::optional<std::set<std::string>> domains_and_ips_to_delete;
 
   // If has a value then any cookie with a domain/ip contained in this set
   // will be ignored (and not deleted).
@@ -136,10 +136,10 @@
   // ".example.com".
   //
   // See precedence note above.
-  absl::optional<std::set<std::string>> domains_and_ips_to_ignore;
+  std::optional<std::set<std::string>> domains_and_ips_to_ignore;
 
   // Used only for testing purposes.
-  absl::optional<std::string> value_for_testing;
+  std::optional<std::string> value_for_testing;
 
   // Cookie partition collection. Partitioned cookies are not deleted if their
   // partition key is not in the collection. By default, it clears cookies in
diff --git a/net/cookies/cookie_deletion_info_unittest.cc b/net/cookies/cookie_deletion_info_unittest.cc
index 8543e96..487f8c59 100644
--- a/net/cookies/cookie_deletion_info_unittest.cc
+++ b/net/cookies/cookie_deletion_info_unittest.cc
@@ -500,8 +500,8 @@
   // Cookie with unspecified SameSite.
   auto cookie = CanonicalCookie::Create(GURL("https://www.example.com"),
                                         "cookie=1", base::Time::Now(),
-                                        /*server_time=*/absl::nullopt,
-                                        /*cookie_partition_key=*/absl::nullopt);
+                                        /*server_time=*/std::nullopt,
+                                        /*cookie_partition_key=*/std::nullopt);
 
   CookieDeletionInfo delete_info;
   delete_info.url = GURL("https://www.example.com/path");
@@ -530,24 +530,24 @@
       {kPartitionKey, kOtherPartitionKey});
   const CookiePartitionKeyCollection kAllKeysKeychain =
       CookiePartitionKeyCollection::ContainsAll();
-  const absl::optional<CookiePartitionKey> kPartitionKeyOpt =
-      absl::make_optional(kPartitionKey);
+  const std::optional<CookiePartitionKey> kPartitionKeyOpt =
+      std::make_optional(kPartitionKey);
   const CookiePartitionKeyCollection kOtherKeySingletonKeychain(
       kOtherPartitionKey);
 
   struct TestCase {
     const std::string desc;
     const CookiePartitionKeyCollection filter_cookie_partition_key_collection;
-    const absl::optional<CookiePartitionKey> cookie_partition_key;
+    const std::optional<CookiePartitionKey> cookie_partition_key;
     bool expects_match;
   } test_cases[] = {
       // Unpartitioned cookie always matches
-      {"Unpartitioned empty keychain", kEmptyKeychain, absl::nullopt, true},
-      {"Unpartitioned singleton keychain", kSingletonKeychain, absl::nullopt,
+      {"Unpartitioned empty keychain", kEmptyKeychain, std::nullopt, true},
+      {"Unpartitioned singleton keychain", kSingletonKeychain, std::nullopt,
        true},
-      {"Unpartitioned multiple keys", kMultipleKeysKeychain, absl::nullopt,
+      {"Unpartitioned multiple keys", kMultipleKeysKeychain, std::nullopt,
        true},
-      {"Unpartitioned all keys", kAllKeysKeychain, absl::nullopt, true},
+      {"Unpartitioned all keys", kAllKeysKeychain, std::nullopt, true},
       // Partitioned cookie only matches keychains which contain its partition
       // key.
       {"Partitioned empty keychain", kEmptyKeychain, kPartitionKeyOpt, false},
@@ -565,7 +565,7 @@
     auto cookie = CanonicalCookie::Create(
         GURL("https://www.example.com"),
         "__Host-foo=bar; Secure; Path=/; Partitioned", base::Time::Now(),
-        /*server_time=*/absl::nullopt, test_case.cookie_partition_key);
+        /*server_time=*/std::nullopt, test_case.cookie_partition_key);
     CookieDeletionInfo delete_info;
     delete_info.cookie_partition_key_collection =
         test_case.filter_cookie_partition_key_collection;
@@ -580,12 +580,12 @@
 TEST(CookieDeletionInfoTest, MatchesExcludeUnpartitionedCookies) {
   struct TestCase {
     const std::string desc;
-    const absl::optional<CookiePartitionKey> cookie_partition_key;
+    const std::optional<CookiePartitionKey> cookie_partition_key;
     bool partitioned_state_only;
     bool expects_match;
   } test_cases[] = {
-      {"Unpartitioned cookie not excluded", absl::nullopt, false, true},
-      {"Unpartitioned cookie excluded", absl::nullopt, true, false},
+      {"Unpartitioned cookie not excluded", std::nullopt, false, true},
+      {"Unpartitioned cookie excluded", std::nullopt, true, false},
       {"Partitioned cookie when unpartitioned not excluded",
        CookiePartitionKey::FromURLForTesting(GURL("https://foo.com")), false,
        true},
@@ -607,7 +607,7 @@
     auto cookie = CanonicalCookie::Create(
         GURL("https://www.example.com"),
         "__Host-foo=bar; Secure; Path=/; Partitioned", base::Time::Now(),
-        /*server_time=*/absl::nullopt, test_case.cookie_partition_key);
+        /*server_time=*/std::nullopt, test_case.cookie_partition_key);
     CookieDeletionInfo delete_info;
     delete_info.partitioned_state_only = test_case.partitioned_state_only;
     EXPECT_EQ(test_case.expects_match,
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc
index b8f378f..5452880 100644
--- a/net/cookies/cookie_monster.cc
+++ b/net/cookies/cookie_monster.cc
@@ -46,6 +46,7 @@
 
 #include <functional>
 #include <numeric>
+#include <optional>
 #include <set>
 #include <utility>
 
@@ -81,7 +82,6 @@
 #include "net/http/http_util.h"
 #include "net/log/net_log.h"
 #include "net/log/net_log_values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/origin.h"
 #include "url/third_party/mozilla/url_parse.h"
 #include "url/url_canon.h"
@@ -427,7 +427,7 @@
     const GURL& source_url,
     const CookieOptions& options,
     SetCookiesCallback callback,
-    absl::optional<CookieAccessResult> cookie_access_result) {
+    std::optional<CookieAccessResult> cookie_access_result) {
   DCHECK(cookie->IsCanonical());
 
   std::string domain = cookie->Domain();
@@ -1011,7 +1011,7 @@
 
     // Ensure no equivalent cookies for this host.
     TrimDuplicateCookiesForKey(key, cur_range_begin, cur_range_end,
-                               absl::nullopt);
+                               std::nullopt);
   }
 
   for (auto cookie_partition_it = partitioned_cookies_.begin();
@@ -1030,7 +1030,7 @@
 
       // Ensure no equivalent cookies for this host and cookie partition key.
       TrimDuplicateCookiesForKey(key, cur_range_begin, cur_range_end,
-                                 absl::make_optional(cur_cookie_partition_it));
+                                 std::make_optional(cur_cookie_partition_it));
     }
   }
 }
@@ -1045,7 +1045,7 @@
     const std::string& key,
     CookieMap::iterator begin,
     CookieMap::iterator end,
-    absl::optional<PartitionedCookieMap::iterator> cookie_partition_it) {
+    std::optional<PartitionedCookieMap::iterator> cookie_partition_it) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   // Set of cookies ordered by creation time.
@@ -1389,7 +1389,7 @@
     bool already_expired,
     base::Time* creation_date_to_inherit,
     CookieInclusionStatus* status,
-    absl::optional<PartitionedCookieMap::iterator> cookie_partition_it) {
+    std::optional<PartitionedCookieMap::iterator> cookie_partition_it) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(!status->HasExclusionReason(
       CookieInclusionStatus::EXCLUDE_OVERWRITE_SECURE));
@@ -1622,7 +1622,7 @@
     const GURL& source_url,
     const CookieOptions& options,
     SetCookiesCallback callback,
-    absl::optional<CookieAccessResult> cookie_access_result) {
+    std::optional<CookieAccessResult> cookie_access_result) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   bool delegate_treats_url_as_trustworthy =
@@ -1646,7 +1646,7 @@
 
   base::Time creation_date_to_inherit;
 
-  absl::optional<PartitionedCookieMap::iterator> cookie_partition_it;
+  std::optional<PartitionedCookieMap::iterator> cookie_partition_it;
   bool should_try_to_delete_duplicates = true;
 
   if (cc->IsPartitioned()) {
@@ -1656,7 +1656,7 @@
       // duplicates.
       should_try_to_delete_duplicates = false;
     } else {
-      cookie_partition_it = absl::make_optional(it);
+      cookie_partition_it = std::make_optional(it);
     }
   }
 
@@ -1695,8 +1695,7 @@
       }
     }
 
-    absl::optional<CookiePartitionKey> cookie_partition_key =
-        cc->PartitionKey();
+    std::optional<CookiePartitionKey> cookie_partition_key = cc->PartitionKey();
     CHECK_EQ(cc->IsPartitioned(), cookie_partition_key.has_value());
 
     // Realize that we might be setting an expired cookie, and the only point
@@ -2426,7 +2425,7 @@
             GURL(base::StrCat({url::kHttpsScheme, "://", domain})));
       }
     }
-    absl::optional<base::flat_map<SchemefulSite, FirstPartySetEntry>>
+    std::optional<base::flat_map<SchemefulSite, FirstPartySetEntry>>
         maybe_sets = cookie_access_delegate()->FindFirstPartySetEntries(
             sites,
             base::BindOnce(&CookieMonster::RecordPeriodicFirstPartySetsStats,
@@ -2621,19 +2620,19 @@
   return CookieSentToSamePort::kNo;
 }
 
-absl::optional<bool> CookieMonster::SiteHasCookieInOtherPartition(
+std::optional<bool> CookieMonster::SiteHasCookieInOtherPartition(
     const net::SchemefulSite& site,
-    const absl::optional<CookiePartitionKey>& partition_key) const {
+    const std::optional<CookiePartitionKey>& partition_key) const {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   // If the partition key is null, it implies the partitioned cookies feature is
   // not enabled.
   if (!partition_key)
-    return absl::nullopt;
+    return std::nullopt;
 
   std::string domain = site.GetURL().host();
   if (store_ && !finished_fetching_all_cookies_ &&
       !keys_loaded_.count(domain)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   for (const auto& it : partitioned_cookies_) {
diff --git a/net/cookies/cookie_monster.h b/net/cookies/cookie_monster.h
index 6871ed3..e8202c9 100644
--- a/net/cookies/cookie_monster.h
+++ b/net/cookies/cookie_monster.h
@@ -12,6 +12,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
@@ -35,7 +36,6 @@
 #include "net/cookies/cookie_monster_change_dispatcher.h"
 #include "net/cookies/cookie_store.h"
 #include "net/log/net_log_with_source.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace net {
@@ -184,8 +184,8 @@
       const GURL& source_url,
       const CookieOptions& options,
       SetCookiesCallback callback,
-      absl::optional<CookieAccessResult> cookie_access_result =
-          absl::nullopt) override;
+      std::optional<CookieAccessResult> cookie_access_result =
+          std::nullopt) override;
   void GetCookieListWithOptionsAsync(const GURL& url,
                                      const CookieOptions& options,
                                      const CookiePartitionKeyCollection& s,
@@ -208,9 +208,9 @@
   CookieChangeDispatcher& GetChangeDispatcher() override;
   void SetCookieableSchemes(const std::vector<std::string>& schemes,
                             SetCookieableSchemesCallback callback) override;
-  absl::optional<bool> SiteHasCookieInOtherPartition(
+  std::optional<bool> SiteHasCookieInOtherPartition(
       const net::SchemefulSite& site,
-      const absl::optional<CookiePartitionKey>& partition_key) const override;
+      const std::optional<CookiePartitionKey>& partition_key) const override;
 
   // Enables writing session cookies into the cookie database. If this this
   // method is called, it must be called before first use of the instance
@@ -401,7 +401,7 @@
       const GURL& source_url,
       const CookieOptions& options,
       SetCookiesCallback callback,
-      absl::optional<CookieAccessResult> cookie_access_result = absl::nullopt);
+      std::optional<CookieAccessResult> cookie_access_result = std::nullopt);
 
   void GetAllCookies(GetAllCookiesCallback callback);
 
@@ -480,7 +480,7 @@
       const std::string& key,
       CookieMap::iterator begin,
       CookieMap::iterator end,
-      absl::optional<PartitionedCookieMap::iterator> cookie_partition_it);
+      std::optional<PartitionedCookieMap::iterator> cookie_partition_it);
 
   void SetDefaultCookieableSchemes();
 
@@ -536,7 +536,7 @@
       bool already_expired,
       base::Time* creation_date_to_inherit,
       CookieInclusionStatus* status,
-      absl::optional<PartitionedCookieMap::iterator> cookie_partition_it);
+      std::optional<PartitionedCookieMap::iterator> cookie_partition_it);
 
   // Inserts `cc` into cookies_. Returns an iterator that points to the inserted
   // cookie in `cookies_`. Guarantee: all iterators to `cookies_` remain valid.
diff --git a/net/cookies/cookie_monster_change_dispatcher.cc b/net/cookies/cookie_monster_change_dispatcher.cc
index 61bd41e..1e04b43f 100644
--- a/net/cookies/cookie_monster_change_dispatcher.cc
+++ b/net/cookies/cookie_monster_change_dispatcher.cc
@@ -147,7 +147,7 @@
 CookieMonsterChangeDispatcher::AddCallbackForCookie(
     const GURL& url,
     const std::string& name,
-    const absl::optional<CookiePartitionKey>& cookie_partition_key,
+    const std::optional<CookiePartitionKey>& cookie_partition_key,
     CookieChangeCallback callback) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
@@ -163,7 +163,7 @@
 std::unique_ptr<CookieChangeSubscription>
 CookieMonsterChangeDispatcher::AddCallbackForUrl(
     const GURL& url,
-    const absl::optional<CookiePartitionKey>& cookie_partition_key,
+    const std::optional<CookiePartitionKey>& cookie_partition_key,
     CookieChangeCallback callback) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
diff --git a/net/cookies/cookie_monster_change_dispatcher.h b/net/cookies/cookie_monster_change_dispatcher.h
index d6f44914..03a9b745 100644
--- a/net/cookies/cookie_monster_change_dispatcher.h
+++ b/net/cookies/cookie_monster_change_dispatcher.h
@@ -54,11 +54,11 @@
   [[nodiscard]] std::unique_ptr<CookieChangeSubscription> AddCallbackForCookie(
       const GURL& url,
       const std::string& name,
-      const absl::optional<CookiePartitionKey>& cookie_partition_key,
+      const std::optional<CookiePartitionKey>& cookie_partition_key,
       CookieChangeCallback callback) override;
   [[nodiscard]] std::unique_ptr<CookieChangeSubscription> AddCallbackForUrl(
       const GURL& url,
-      const absl::optional<CookiePartitionKey>& cookie_partition_key,
+      const std::optional<CookiePartitionKey>& cookie_partition_key,
       CookieChangeCallback callback) override;
   [[nodiscard]] std::unique_ptr<CookieChangeSubscription>
   AddCallbackForAllChanges(CookieChangeCallback callback) override;
diff --git a/net/cookies/cookie_monster_perftest.cc b/net/cookies/cookie_monster_perftest.cc
index 0323f3d..48b0485 100644
--- a/net/cookies/cookie_monster_perftest.cc
+++ b/net/cookies/cookie_monster_perftest.cc
@@ -2,7 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "net/cookies/cookie_monster.h"
+
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "base/functional/bind.h"
@@ -14,13 +17,11 @@
 #include "base/time/time.h"
 #include "base/timer/elapsed_timer.h"
 #include "net/cookies/canonical_cookie.h"
-#include "net/cookies/cookie_monster.h"
 #include "net/cookies/cookie_monster_store_test.h"
 #include "net/cookies/cookie_util.h"
 #include "net/cookies/parsed_cookie.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/perf/perf_result_reporter.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace net {
@@ -96,8 +97,8 @@
                  const GURL& gurl,
                  const std::string& cookie_line) {
     auto cookie = CanonicalCookie::Create(
-        gurl, cookie_line, base::Time::Now(), absl::nullopt /* server_time */,
-        absl::nullopt /* cookie_partition_key */);
+        gurl, cookie_line, base::Time::Now(), std::nullopt /* server_time */,
+        std::nullopt /* cookie_partition_key */);
     cm->SetCanonicalCookieAsync(
         std::move(cookie), gurl, options_,
         base::BindOnce(&SetCookieCallback::Run, base::Unretained(this)));
diff --git a/net/cookies/cookie_monster_unittest.cc b/net/cookies/cookie_monster_unittest.cc
index 89a941c..4935b90d 100644
--- a/net/cookies/cookie_monster_unittest.cc
+++ b/net/cookies/cookie_monster_unittest.cc
@@ -8,6 +8,7 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -60,7 +61,6 @@
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/third_party/mozilla/url_parse.h"
 #include "url/url_constants.h"
@@ -208,13 +208,13 @@
       const GURL& url,
       const std::string& cookie_line,
       base::Time creation_time,
-      absl::optional<CookiePartitionKey> cookie_partition_key = absl::nullopt) {
+      std::optional<CookiePartitionKey> cookie_partition_key = std::nullopt) {
     DCHECK(cm);
     DCHECK(!creation_time.is_null());
     ResultSavingCookieCallback<CookieAccessResult> callback;
     cm->SetCanonicalCookieAsync(
         CanonicalCookie::Create(url, cookie_line, creation_time,
-                                absl::nullopt /* server_time */,
+                                std::nullopt /* server_time */,
                                 cookie_partition_key),
         url, CookieOptions::MakeAllInclusive(), callback.MakeCallback());
     callback.WaitUntilDone();
@@ -1065,8 +1065,8 @@
   ResultSavingCookieCallback<CookieAccessResult> call1;
   cookie_monster_->SetCanonicalCookieAsync(
       CanonicalCookie::Create(http_www_foo_.url(), "A=B", base::Time::Now(),
-                              absl::nullopt /* server_time */,
-                              absl::nullopt /* cookie_partition_key */),
+                              std::nullopt /* server_time */,
+                              std::nullopt /* cookie_partition_key */),
       http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
       call1.MakeCallback());
   base::RunLoop().RunUntilIdle();
@@ -1080,8 +1080,8 @@
   ResultSavingCookieCallback<CookieAccessResult> call2;
   cookie_monster_->SetCanonicalCookieAsync(
       CanonicalCookie::Create(http_www_foo_.url(), "X=Y", base::Time::Now(),
-                              absl::nullopt /* server_time */,
-                              absl::nullopt /* cookie_partition_key */),
+                              std::nullopt /* server_time */,
+                              std::nullopt /* cookie_partition_key */),
       http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
       call2.MakeCallback());
   ASSERT_TRUE(call2.was_run());
@@ -1368,8 +1368,8 @@
 
   cookie_monster_->SetCanonicalCookieAsync(
       CanonicalCookie::Create(http_www_foo_.url(), "A=B", base::Time::Now(),
-                              absl::nullopt /* server_time */,
-                              absl::nullopt /* cookie_partition_key */),
+                              std::nullopt /* server_time */,
+                              std::nullopt /* cookie_partition_key */),
       http_www_foo_.url(), CookieOptions::MakeAllInclusive(),
       set_cookies_callback.MakeCallback());
 
@@ -1815,14 +1815,14 @@
   GURL http_url("http://host/path");
 
   base::Time now = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   EXPECT_TRUE(
       CreateAndSetCookieReturnStatus(cm.get(), http_url, "x=1").IsInclude());
   EXPECT_TRUE(
       SetCanonicalCookieReturnAccessResult(
           cm.get(),
           CanonicalCookie::Create(http_url, "y=1", now, server_time,
-                                  absl::nullopt /* cookie_partition_key */),
+                                  std::nullopt /* cookie_partition_key */),
           http_url, false /*modify_httponly*/)
           .status.IsInclude());
 
@@ -1833,7 +1833,7 @@
       SetCanonicalCookieReturnAccessResult(
           cm.get(),
           CanonicalCookie::Create(foo_url, "y=1", now, server_time,
-                                  absl::nullopt /* cookie_partition_key */),
+                                  std::nullopt /* cookie_partition_key */),
           foo_url, false /*modify_httponly*/)
           .status.HasExactlyExclusionReasonsForTesting(
               {CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME}));
@@ -1844,7 +1844,7 @@
       SetCanonicalCookieReturnAccessResult(
           cm_foo.get(),
           CanonicalCookie::Create(foo_url, "y=1", now, server_time,
-                                  absl::nullopt /* cookie_partition_key */),
+                                  std::nullopt /* cookie_partition_key */),
           foo_url, false /*modify_httponly*/)
           .status.IsInclude());
 
@@ -1855,7 +1855,7 @@
       SetCanonicalCookieReturnAccessResult(
           cm_foo.get(),
           CanonicalCookie::Create(http_url, "y=1", now, server_time,
-                                  absl::nullopt /* cookie_partition_key */),
+                                  std::nullopt /* cookie_partition_key */),
           http_url, false /*modify_httponly*/)
           .status.HasExactlyExclusionReasonsForTesting(
               {CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME}));
@@ -1875,13 +1875,13 @@
   EXPECT_FALSE(cookie_scheme_callback.result());
 
   base::Time now = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   GURL foo_url("foo://host/path");
   EXPECT_TRUE(
       SetCanonicalCookieReturnAccessResult(
           cm.get(),
           CanonicalCookie::Create(foo_url, "y=1", now, server_time,
-                                  absl::nullopt /* cookie_partition_key */),
+                                  std::nullopt /* cookie_partition_key */),
           foo_url, false /*modify_httponly*/)
           .status.HasExactlyExclusionReasonsForTesting(
               {CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME}));
@@ -1920,13 +1920,13 @@
       CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite3.com"));
   EXPECT_TRUE(CreateAndSetCookie(
       cm.get(), https_www_bar_.url(), "__Host-K=L; secure; path=/; partitioned",
-      options, absl::nullopt, absl::nullopt, cookie_partition_key1));
+      options, std::nullopt, std::nullopt, cookie_partition_key1));
   EXPECT_TRUE(CreateAndSetCookie(
       cm.get(), https_www_bar_.url(), "__Host-M=N; secure; path=/; partitioned",
-      options, absl::nullopt, absl::nullopt, cookie_partition_key2));
+      options, std::nullopt, std::nullopt, cookie_partition_key2));
   EXPECT_TRUE(CreateAndSetCookie(
       cm.get(), https_www_bar_.url(), "__Host-O=P; secure; path=/; partitioned",
-      options, absl::nullopt, absl::nullopt, cookie_partition_key3));
+      options, std::nullopt, std::nullopt, cookie_partition_key3));
 
   const Time last_access_date(GetFirstCookieAccessDate(cm.get()));
 
@@ -2263,12 +2263,12 @@
 
   EXPECT_TRUE(SetCookie(cm.get(), https_www_bar_.url(),
                         "__Host-A=B; secure; path=/",
-                        /*cookie_partition_key=*/absl::nullopt));
+                        /*cookie_partition_key=*/std::nullopt));
   // Set a cookie with a Max-Age. Since we only parse integers for this
   // attribute, 1 second is the minimum allowable time.
   EXPECT_TRUE(SetCookie(cm.get(), https_www_bar_.url(),
                         "__Host-C=D; secure; path=/; max-age=1",
-                        /*cookie_partition_key=*/absl::nullopt));
+                        /*cookie_partition_key=*/std::nullopt));
 
   CookieList cookies = GetAllCookiesForURL(cm.get(), https_www_bar_.url(),
                                            CookiePartitionKeyCollection());
@@ -2319,12 +2319,12 @@
 
   EXPECT_TRUE(SetCookie(cm.get(), https_www_bar_.url(),
                         "__Host-A=B; secure; path=/",
-                        /*cookie_partition_key=*/absl::nullopt));
+                        /*cookie_partition_key=*/std::nullopt));
   // Set a cookie with a Max-Age. Since we only parse integers for this
   // attribute, 1 second is the minimum allowable time.
   EXPECT_TRUE(SetCookie(cm.get(), https_www_bar_.url(),
                         "__Host-C=D; secure; path=/; max-age=1",
-                        /*cookie_partition_key=*/absl::nullopt));
+                        /*cookie_partition_key=*/std::nullopt));
 
   GetAllCookiesCallback get_cookies_callback1;
   cm->GetAllCookiesAsync(get_cookies_callback1.MakeCallback());
@@ -2389,11 +2389,11 @@
                         "__Host-C=D; secure; path=/; partitioned",
                         cookie_partition_key));
   EXPECT_TRUE(SetCookie(cm.get(), https_www_bar_.url(),
-                        "__Host-E=F; secure; path=/", absl::nullopt));
+                        "__Host-E=F; secure; path=/", std::nullopt));
 
   auto cookie = CanonicalCookie::Create(
       https_www_bar_.url(), "__Host-A=B; secure; path=/; partitioned",
-      /*creation_time=*/Time::Now(), /*server_time=*/absl::nullopt,
+      /*creation_time=*/Time::Now(), /*server_time=*/std::nullopt,
       cookie_partition_key);
   ASSERT_TRUE(cookie);
 
@@ -2496,17 +2496,17 @@
   // ===> This one is the WINNER (biggest creation time).  <====
   auto cc = CanonicalCookie::Create(
       cookie_url, "__Host-Z=a; Secure; Path=/; Partitioned; Max-Age=3456000",
-      Time::Now() + base::Days(2), absl::nullopt, cookie_partition_key);
+      Time::Now() + base::Days(2), std::nullopt, cookie_partition_key);
   initial_cookies.push_back(std::move(cc));
 
   cc = CanonicalCookie::Create(
       cookie_url, "__Host-Z=b; Secure; Path=/; Partitioned; Max-Age=3456000",
-      Time::Now(), absl::nullopt, cookie_partition_key);
+      Time::Now(), std::nullopt, cookie_partition_key);
   initial_cookies.push_back(std::move(cc));
 
   cc = CanonicalCookie::Create(
       cookie_url, "__Host-Z=c; Secure; Path=/; Partitioned; Max-Age=3456000",
-      Time::Now() + base::Days(1), absl::nullopt, cookie_partition_key);
+      Time::Now() + base::Days(1), std::nullopt, cookie_partition_key);
   initial_cookies.push_back(std::move(cc));
 
   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
@@ -2592,28 +2592,28 @@
   std::vector<std::unique_ptr<CanonicalCookie>> initial_cookies;
   auto cc = CanonicalCookie::Create(
       cookie_url, "__Host-X=1; Secure; Path=/; Partitioned; Max-Age=3456000",
-      now, absl::nullopt, cookie_partition_key);
+      now, std::nullopt, cookie_partition_key);
   initial_cookies.push_back(std::move(cc));
   cc = CanonicalCookie::Create(
       cookie_url, "__Host-X=2; Secure; Path=/; Partitioned; Max-Age=3456000",
-      now, absl::nullopt, cookie_partition_key);
+      now, std::nullopt, cookie_partition_key);
   initial_cookies.push_back(std::move(cc));
   cc = CanonicalCookie::Create(
       cookie_url, "__Host-X=3; Secure; Path=/; Partitioned; Max-Age=3456000",
-      now, absl::nullopt, cookie_partition_key);
+      now, std::nullopt, cookie_partition_key);
   initial_cookies.push_back(std::move(cc));
 
   cc = CanonicalCookie::Create(
       cookie_url, "__Host-Y=1; Secure; Path=/; Partitioned; Max-Age=3456000",
-      earlier, absl::nullopt, cookie_partition_key);
+      earlier, std::nullopt, cookie_partition_key);
   initial_cookies.push_back(std::move(cc));
   cc = CanonicalCookie::Create(
       cookie_url, "__Host-Y=2; Secure; Path=/; Partitioned; Max-Age=3456000",
-      earlier, absl::nullopt, cookie_partition_key);
+      earlier, std::nullopt, cookie_partition_key);
   initial_cookies.push_back(std::move(cc));
   cc = CanonicalCookie::Create(
       cookie_url, "__Host-Y=3; Secure; Path=/; Partitioned; Max-Age=3456000",
-      earlier, absl::nullopt, cookie_partition_key);
+      earlier, std::nullopt, cookie_partition_key);
   initial_cookies.push_back(std::move(cc));
 
   // Inject our initial cookies into the mock PersistentCookieStore.
@@ -2933,8 +2933,8 @@
   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
 
   auto cookie = CanonicalCookie::Create(
-      kUrl, "a=b", base::Time::Now(), absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */);
+      kUrl, "a=b", base::Time::Now(), std::nullopt /* server_time */,
+      std::nullopt /* cookie_partition_key */);
   ResultSavingCookieCallback<CookieAccessResult> set_cookie_callback;
   cm->SetCanonicalCookieAsync(std::move(cookie), kUrl,
                               CookieOptions::MakeAllInclusive(),
@@ -2997,8 +2997,8 @@
   // When passed to the CookieMonster, it takes ownership of the pointed to
   // cookies.
   cookies.push_back(CanonicalCookie::Create(
-      kUrl, "a=b", base::Time::Now(), absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */));
+      kUrl, "a=b", base::Time::Now(), std::nullopt /* server_time */,
+      std::nullopt /* cookie_partition_key */));
   ASSERT_TRUE(cookies[0]);
   store->TakeCallbackAt(0).Run(std::move(cookies));
 
@@ -3024,8 +3024,8 @@
   cm->GetAllCookiesAsync(get_cookies_callback1.MakeCallback());
 
   auto cookie = CanonicalCookie::Create(
-      kUrl, "a=b", base::Time::Now(), absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */);
+      kUrl, "a=b", base::Time::Now(), std::nullopt /* server_time */,
+      std::nullopt /* cookie_partition_key */);
   ResultSavingCookieCallback<CookieAccessResult> set_cookie_callback;
   cm->SetCanonicalCookieAsync(std::move(cookie), kUrl,
                               CookieOptions::MakeAllInclusive(),
@@ -3072,15 +3072,15 @@
 
   // Get all cookies task that queues a task to set a cookie when executed.
   auto cookie = CanonicalCookie::Create(
-      kUrl, "a=b", base::Time::Now(), absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */);
+      kUrl, "a=b", base::Time::Now(), std::nullopt /* server_time */,
+      std::nullopt /* cookie_partition_key */);
   ResultSavingCookieCallback<CookieAccessResult> set_cookie_callback;
   cm->GetAllCookiesAsync(base::BindOnce(
       &RunClosureOnAllCookiesReceived,
       base::BindOnce(&CookieStore::SetCanonicalCookieAsync,
                      base::Unretained(cm.get()), std::move(cookie), kUrl,
                      CookieOptions::MakeAllInclusive(),
-                     set_cookie_callback.MakeCallback(), absl::nullopt)));
+                     set_cookie_callback.MakeCallback(), std::nullopt)));
 
   // Get cookie task. Queued before the delete task is executed, so should not
   // see the set cookie.
@@ -3301,10 +3301,9 @@
 TEST_F(CookieMonsterTest, InvalidExpiryTime) {
   std::string cookie_line =
       std::string(kValidCookieLine) + "; expires=Blarg arg arg";
-  std::unique_ptr<CanonicalCookie> cookie(
-      CanonicalCookie::Create(http_www_foo_.url(), cookie_line, Time::Now(),
-                              absl::nullopt /* server_time */,
-                              absl::nullopt /* cookie_partition_key */));
+  std::unique_ptr<CanonicalCookie> cookie(CanonicalCookie::Create(
+      http_www_foo_.url(), cookie_line, Time::Now(),
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */));
   ASSERT_FALSE(cookie->IsPersistent());
 }
 
@@ -3524,24 +3523,19 @@
   std::vector<std::unique_ptr<CanonicalCookie>> initial_cookies;
   initial_cookies.push_back(CanonicalCookie::Create(
       GURL("http://domain1.test"), "A=1", base::Time::Now(),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */));
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */));
   initial_cookies.push_back(CanonicalCookie::Create(
       GURL("http://domain2.test"), "A=1", base::Time::Now(),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */));
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */));
   initial_cookies.push_back(CanonicalCookie::Create(
       GURL("http://sub.domain2.test"), "A=1", base::Time::Now(),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */));
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */));
   initial_cookies.push_back(CanonicalCookie::Create(
       GURL("http://domain3.test"), "A=1", base::Time::Now(),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */));
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */));
   initial_cookies.push_back(CanonicalCookie::Create(
       GURL("http://domain3.test"), "B=1", base::Time::Now(),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */));
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */));
   store->SetLoadExpectation(true /* return_value */,
                             std::move(initial_cookies));
   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
@@ -3663,7 +3657,7 @@
   auto set_cookie =
       [&](const std::string& name, int cookie_value_size_kb,
           const std::string& domain, CookieSameSite same_site,
-          const absl::optional<CookiePartitionKey>& partition_key) {
+          const std::optional<CookiePartitionKey>& partition_key) {
         auto cc = CanonicalCookie::CreateUnsafeCookieForTesting(
             name, std::string(cookie_value_size_kb * 1024, '0'), domain, "/",
             base::Time(), base::Time::Now() + base::Minutes(59), base::Time(),
@@ -3678,7 +3672,7 @@
 
   {  // Add unpartitioned cookie.
     base::HistogramTester histogram_tester;
-    set_cookie("a", 2, "a.url", CookieSameSite::NO_RESTRICTION, absl::nullopt);
+    set_cookie("a", 2, "a.url", CookieSameSite::NO_RESTRICTION, std::nullopt);
     ASSERT_TRUE(cm->DoRecordPeriodicStatsForTesting());
 
     histogram_tester.ExpectUniqueSample("Cookie.CookieJarSize",
@@ -3713,7 +3707,7 @@
   {  // Add unpartitioned cookie from another domain. Is also SameSite=Lax to
      // ensure the counter includes SameSite cookies.
     base::HistogramTester histogram_tester;
-    set_cookie("c", 4, "c.url", CookieSameSite::LAX_MODE, absl::nullopt);
+    set_cookie("c", 4, "c.url", CookieSameSite::LAX_MODE, std::nullopt);
     ASSERT_TRUE(cm->DoRecordPeriodicStatsForTesting());
 
     histogram_tester.ExpectUniqueSample("Cookie.CookieJarSize",
@@ -3966,8 +3960,8 @@
   {
     auto cookie = CanonicalCookie::Create(
         insecure_localhost, "from_insecure_localhost=1; Secure",
-        base::Time::Now(), absl::nullopt /* server_time */,
-        absl::nullopt /* cookie_partition_key */);
+        base::Time::Now(), std::nullopt /* server_time */,
+        std::nullopt /* cookie_partition_key */);
     ASSERT_TRUE(cookie);
     CookieInclusionStatus status =
         SetCanonicalCookieReturnAccessResult(cm.get(), std::move(cookie),
@@ -3983,8 +3977,8 @@
   {
     auto cookie = CanonicalCookie::Create(
         secure_localhost, "from_secure_localhost=1; Secure", base::Time::Now(),
-        absl::nullopt /* server_time */,
-        absl::nullopt /* cookie_partition_key */);
+        std::nullopt /* server_time */,
+        std::nullopt /* cookie_partition_key */);
     ASSERT_TRUE(cookie);
     CookieInclusionStatus status =
         SetCanonicalCookieReturnAccessResult(cm.get(), std::move(cookie),
@@ -4035,8 +4029,7 @@
   // Set a secure, httponly cookie from a secure origin
   auto preexisting_cookie = CanonicalCookie::Create(
       https_www_foo_.url(), "A=B;Secure;HttpOnly", base::Time::Now(),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */);
   CookieAccessResult access_result = SetCanonicalCookieReturnAccessResult(
       cm.get(), std::move(preexisting_cookie), https_www_foo_.url(),
       true /* can_modify_httponly */);
@@ -4052,10 +4045,9 @@
 
   // Set a non-Secure cookie from an insecure origin that is
   // equivalent to the pre-existing Secure cookie.
-  auto bad_cookie =
-      CanonicalCookie::Create(http_www_foo_.url(), "A=D", base::Time::Now(),
-                              absl::nullopt /* server_time */,
-                              absl::nullopt /* cookie_partition_key */);
+  auto bad_cookie = CanonicalCookie::Create(
+      http_www_foo_.url(), "A=D", base::Time::Now(),
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */);
   // Allow modifying HttpOnly, so that we don't skip preexisting cookies for
   // being HttpOnly.
   access_result = SetCanonicalCookieReturnAccessResult(
@@ -4086,8 +4078,7 @@
   // trying to shadow a secure cookie.
   bad_cookie = CanonicalCookie::Create(
       http_www_foo_.url(), "A=E; path=/some/path", base::Time::Now(),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */);
   // Allow modifying HttpOnly, so that we don't skip preexisting cookies for
   // being HttpOnly.
   access_result = SetCanonicalCookieReturnAccessResult(
@@ -4117,8 +4108,7 @@
   // Test skipping equivalent cookie for HttpOnly only.
   bad_cookie = CanonicalCookie::Create(
       https_www_foo_.url(), "A=E; Secure", base::Time::Now(),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */);
   access_result = SetCanonicalCookieReturnAccessResult(
       cm.get(), std::move(bad_cookie), https_www_foo_.url(),
       false /* can_modify_httponly */);
@@ -4145,7 +4135,7 @@
 
   auto preexisting_cookie = CanonicalCookie::Create(
       https_www_foo_.url(), "__Host-A=B; Secure; Path=/; Partitioned; HttpOnly",
-      base::Time::Now(), absl::nullopt /* server_time */,
+      base::Time::Now(), std::nullopt /* server_time */,
       cookie_partition_key1 /* cookie_partition_key */);
   CookieAccessResult access_result = SetCanonicalCookieReturnAccessResult(
       cm.get(), std::move(preexisting_cookie), https_www_foo_.url(),
@@ -4161,8 +4151,7 @@
   // Should not overwrite HttpOnly cookie.
   auto bad_cookie = CanonicalCookie::Create(
       https_www_foo_.url(), "__Host-A=D; Secure; Path=/; Partitioned",
-      base::Time::Now(), absl::nullopt /* server_time */,
-      cookie_partition_key1);
+      base::Time::Now(), std::nullopt /* server_time */, cookie_partition_key1);
   access_result = SetCanonicalCookieReturnAccessResult(
       cm.get(), std::move(bad_cookie), https_www_foo_.url(),
       false /* can_modify_httponly */);
@@ -4189,8 +4178,8 @@
 
     auto preexisting_cookie_https = CanonicalCookie::Create(
         https_www_foo_.url(), "A=PreexistingHttps443", base::Time::Now(),
-        /*server_time=*/absl::nullopt,
-        /*cookie_partition_key=*/absl::nullopt);
+        /*server_time=*/std::nullopt,
+        /*cookie_partition_key=*/std::nullopt);
 
     CookieAccessResult access_result = SetCanonicalCookieReturnAccessResult(
         cm_.get(), std::move(preexisting_cookie_https), https_www_foo_.url(),
@@ -4201,8 +4190,8 @@
         https_www_foo_.url(),
         "A=PreexistingDomainHttps443; Domain=" + https_www_foo_.domain(),
         base::Time::Now(),
-        /*server_time=*/absl::nullopt,
-        /*cookie_partition_key=*/absl::nullopt);
+        /*server_time=*/std::nullopt,
+        /*cookie_partition_key=*/std::nullopt);
 
     access_result = SetCanonicalCookieReturnAccessResult(
         cm_.get(), std::move(preexisting_domain_cookie_https),
@@ -4226,8 +4215,8 @@
 
     auto differ_by_scheme_only = CanonicalCookie::Create(
         foo_made_http, "A=InsertedHttp443", base::Time::Now(),
-        /*server_time=*/absl::nullopt,
-        /*cookie_partition_key=*/absl::nullopt);
+        /*server_time=*/std::nullopt,
+        /*cookie_partition_key=*/std::nullopt);
 
     CookieAccessResult access_result = SetCanonicalCookieReturnAccessResult(
         cm_.get(), std::move(differ_by_scheme_only), foo_made_http,
@@ -4244,8 +4233,8 @@
 
     auto differ_by_port_only = CanonicalCookie::Create(
         foo_made_80, "A=InsertedHttps80", base::Time::Now(),
-        /*server_time=*/absl::nullopt,
-        /*cookie_partition_key=*/absl::nullopt);
+        /*server_time=*/std::nullopt,
+        /*cookie_partition_key=*/std::nullopt);
 
     CookieAccessResult access_result = SetCanonicalCookieReturnAccessResult(
         cm_.get(), std::move(differ_by_port_only), foo_made_80,
@@ -4264,8 +4253,8 @@
         foo_made_80,
         "A=InsertedDomainHttps80; Domain=" + https_www_foo_.domain(),
         base::Time::Now(),
-        /*server_time=*/absl::nullopt,
-        /*cookie_partition_key=*/absl::nullopt);
+        /*server_time=*/std::nullopt,
+        /*cookie_partition_key=*/std::nullopt);
 
     CookieAccessResult access_result = SetCanonicalCookieReturnAccessResult(
         cm_.get(), std::move(differ_by_port_only), foo_made_80,
@@ -4453,8 +4442,8 @@
 
     auto basic_cookie = CanonicalCookie::Create(
         https_www_foo_.url(), "A=basic", base::Time::Now(),
-        absl::nullopt /* server_time */,
-        absl::nullopt /* cookie_partition_key */);
+        std::nullopt /* server_time */,
+        std::nullopt /* cookie_partition_key */);
 
     // When there are duplicate cookies the most recent one is kept. So, this
     // one.
@@ -4471,8 +4460,8 @@
 
     auto http_cookie =
         CanonicalCookie::Create(foo_with_http, "A=http", base::Time::Now(),
-                                absl::nullopt /* server_time */,
-                                absl::nullopt /* cookie_partition_key */);
+                                std::nullopt /* server_time */,
+                                std::nullopt /* cookie_partition_key */);
 
     http_cookie->SetCreationDate(middle_time);
     starting_list_.push_back(std::move(http_cookie));
@@ -4483,16 +4472,16 @@
 
     auto port_450_cookie =
         CanonicalCookie::Create(foo_with_450, "A=port450", base::Time::Now(),
-                                absl::nullopt /* server_time */,
-                                absl::nullopt /* cookie_partition_key */);
+                                std::nullopt /* server_time */,
+                                std::nullopt /* cookie_partition_key */);
     port_450_cookie->SetCreationDate(least_recent_time);
     starting_list_.push_back(std::move(port_450_cookie));
 
     auto basic_domain_cookie = CanonicalCookie::Create(
         https_www_foo_.url(),
         "A=basic_domain; Domain=" + https_www_foo_.domain(), base::Time::Now(),
-        absl::nullopt /* server_time */,
-        absl::nullopt /* cookie_partition_key */);
+        std::nullopt /* server_time */,
+        std::nullopt /* cookie_partition_key */);
 
     // When there are duplicate domain cookies the most recent one is kept. So,
     // this one.
@@ -4501,8 +4490,8 @@
 
     auto http_domain_cookie = CanonicalCookie::Create(
         foo_with_http, "A=http_domain; Domain=" + https_www_foo_.domain(),
-        base::Time::Now(), absl::nullopt /* server_time */,
-        absl::nullopt /* cookie_partition_key */);
+        base::Time::Now(), std::nullopt /* server_time */,
+        std::nullopt /* cookie_partition_key */);
 
     http_domain_cookie->SetCreationDate(middle_time);
     starting_list_.push_back(std::move(http_domain_cookie));
@@ -4511,8 +4500,8 @@
     // considered a duplicate.
     auto port_450_domain_cookie = CanonicalCookie::Create(
         foo_with_450, "A=port450_domain; Domain=" + https_www_foo_.domain(),
-        base::Time::Now(), absl::nullopt /* server_time */,
-        absl::nullopt /* cookie_partition_key */);
+        base::Time::Now(), std::nullopt /* server_time */,
+        std::nullopt /* cookie_partition_key */);
     port_450_domain_cookie->SetCreationDate(least_recent_time);
     starting_list_.push_back(std::move(port_450_domain_cookie));
 
@@ -4610,8 +4599,7 @@
   // Set a secure, httponly cookie from a secure origin
   auto preexisting_cookie = CanonicalCookie::Create(
       https_www_foo_.url(), "A=B;Secure;HttpOnly", base::Time::Now(),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */);
   CookieAccessResult access_result = SetCanonicalCookieReturnAccessResult(
       cm.get(), std::move(preexisting_cookie), https_www_foo_.url(),
       true /* can_modify_httponly */);
@@ -4619,10 +4607,9 @@
 
   // Attempt to set a new cookie with the same name that is not Secure or
   // Httponly from an insecure scheme.
-  auto cookie =
-      CanonicalCookie::Create(http_www_foo_.url(), "A=B", base::Time::Now(),
-                              absl::nullopt /* server_time */,
-                              absl::nullopt /* cookie_partition_key */);
+  auto cookie = CanonicalCookie::Create(
+      http_www_foo_.url(), "A=B", base::Time::Now(),
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */);
   access_result = SetCanonicalCookieReturnAccessResult(
       cm.get(), std::move(cookie), http_www_foo_.url(),
       false /* can_modify_httponly */);
@@ -4647,8 +4634,7 @@
 
   auto preexisting_cookie = CanonicalCookie::Create(
       http_www_foo_.url(), "cookie=foo", base::Time::Now(),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */);
   CookieAccessResult access_result = SetCanonicalCookieReturnAccessResult(
       cm.get(), std::move(preexisting_cookie), http_www_foo_.url(),
       false /* can_modify_httponly */);
@@ -4656,8 +4642,7 @@
 
   auto bad_cookie = CanonicalCookie::Create(
       http_www_foo_.url(), "cookie=bar;secure", base::Time::Now(),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */);
   CookieAccessResult access_result2 = SetCanonicalCookieReturnAccessResult(
       cm.get(), std::move(bad_cookie), http_www_foo_.url(),
       false /* can_modify_httponly */);
@@ -5271,8 +5256,8 @@
   GURL cookie_url("http://a.com/");
   cm.SetCanonicalCookieAsync(
       CanonicalCookie::Create(cookie_url, "A=B", base::Time::Now(),
-                              absl::nullopt /* server_time */,
-                              absl::nullopt /* cookie_partition_key */),
+                              std::nullopt /* server_time */,
+                              std::nullopt /* cookie_partition_key */),
       cookie_url, CookieOptions::MakeAllInclusive(),
       callback_set.MakeCallback());
 
@@ -5349,8 +5334,8 @@
   GURL url("http://www.example.com");
   std::string cookie_line = "foo=bar";
   CookieOptions options = CookieOptions::MakeAllInclusive();
-  absl::optional<base::Time> server_time = absl::nullopt;
-  absl::optional<CookiePartitionKey> partition_key = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
+  std::optional<CookiePartitionKey> partition_key = std::nullopt;
   CookieMonster cm(nullptr, nullptr);
 
   // Write a cookie created at |t1|.
@@ -5392,8 +5377,8 @@
   CookieInclusionStatus status;
   // Cookie can be created successfully; SameSite is not checked on Creation.
   auto cookie = CanonicalCookie::Create(url, cookie_line, base::Time::Now(),
-                                        /*server_time=*/absl::nullopt,
-                                        /*cookie_partition_key=*/absl::nullopt,
+                                        /*server_time=*/std::nullopt,
+                                        /*cookie_partition_key=*/std::nullopt,
                                         /*block_truncated=*/true, &status);
   ASSERT_TRUE(cookie != nullptr);
   ASSERT_TRUE(status.IsInclude());
@@ -5416,9 +5401,8 @@
   // Cookie can be created successfully from an any url. Secure is not checked
   // on Create.
   auto cookie = CanonicalCookie::Create(
-      http_url, cookie_line, base::Time::Now(), /*server_time=*/absl::nullopt,
-      /*cookie_partition_key=*/absl::nullopt, /*block_truncated=*/true,
-      &status);
+      http_url, cookie_line, base::Time::Now(), /*server_time=*/std::nullopt,
+      /*cookie_partition_key=*/std::nullopt, /*block_truncated=*/true, &status);
 
   ASSERT_TRUE(cookie != nullptr);
   ASSERT_TRUE(status.IsInclude());
@@ -5441,8 +5425,8 @@
   CookieInclusionStatus status;
   // Cookie can be created successfully; HttpOnly is not checked on Create.
   auto cookie = CanonicalCookie::Create(url, cookie_line, base::Time::Now(),
-                                        /*server_time=*/absl::nullopt,
-                                        /*cookie_partition_key=*/absl::nullopt,
+                                        /*server_time=*/std::nullopt,
+                                        /*cookie_partition_key=*/std::nullopt,
                                         /*block_truncated=*/true, &status);
 
   ASSERT_TRUE(cookie != nullptr);
@@ -5523,8 +5507,8 @@
     GURL url = test.is_url_secure ? secure_url : insecure_url;
     base::Time creation_time = base::Time::Now() - test.creation_time_delta;
     auto cookie = CanonicalCookie::Create(
-        url, test.cookie_line, creation_time, absl::nullopt /* server_time */,
-        absl::nullopt /* cookie_partition_key */);
+        url, test.cookie_line, creation_time, std::nullopt /* server_time */,
+        std::nullopt /* cookie_partition_key */);
     // Make a copy so we can delete it after the test.
     CanonicalCookie cookie_copy = *cookie;
     CookieAccessResult result = SetCanonicalCookieReturnAccessResult(
@@ -5597,15 +5581,14 @@
   std::vector<std::unique_ptr<CanonicalCookie>> initial_cookies;
   GURL url("http://www.foo.com");
   initial_cookies.push_back(CanonicalCookie::Create(
-      url, "X=1; path=/", base::Time::Now(), absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */));
+      url, "X=1; path=/", base::Time::Now(), std::nullopt /* server_time */,
+      std::nullopt /* cookie_partition_key */));
   initial_cookies.push_back(CanonicalCookie::Create(
-      url, "Y=1; path=/", base::Time::Now(), absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */));
+      url, "Y=1; path=/", base::Time::Now(), std::nullopt /* server_time */,
+      std::nullopt /* cookie_partition_key */));
   initial_cookies.push_back(CanonicalCookie::Create(
       url, "Y=2; path=/", base::Time::Now() + base::Days(1),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */));
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */));
 
   // Execute the load
   store->TakeCallbackAt(0).Run(std::move(initial_cookies));
@@ -5975,8 +5958,8 @@
 
   auto unspecified_cookie = CanonicalCookie::Create(
       GURL("https://www.foo.com/withoutport"), "C=D; Path=/withoutport",
-      base::Time::Now(), /* server_time */ absl::nullopt,
-      /* cookie_partition_key */ absl::nullopt);
+      base::Time::Now(), /* server_time */ std::nullopt,
+      /* cookie_partition_key */ std::nullopt);
   // Force to be unspecified.
   unspecified_cookie->SetSourcePort(url::PORT_UNSPECIFIED);
   EXPECT_TRUE(SetCanonicalCookieReturnAccessResult(
@@ -5987,8 +5970,8 @@
 
   auto invalid_cookie = CanonicalCookie::Create(
       GURL("https://www.foo.com/invalidport"), "E=F; Path=/invalidport",
-      base::Time::Now(), /* server_time */ absl::nullopt,
-      /* cookie_partition_key */ absl::nullopt);
+      base::Time::Now(), /* server_time */ std::nullopt,
+      /* cookie_partition_key */ std::nullopt);
   // Force to be invalid.
   invalid_cookie->SetSourcePort(99999);
   EXPECT_TRUE(SetCanonicalCookieReturnAccessResult(
@@ -6149,11 +6132,11 @@
 
   access_delegate_->SetFirstPartySets({
       {owner1,
-       net::FirstPartySetEntry(owner1, net::SiteType::kPrimary, absl::nullopt)},
+       net::FirstPartySetEntry(owner1, net::SiteType::kPrimary, std::nullopt)},
       {member1, net::FirstPartySetEntry(owner1, net::SiteType::kAssociated, 0)},
       {member2, net::FirstPartySetEntry(owner1, net::SiteType::kAssociated, 1)},
       {owner2,
-       net::FirstPartySetEntry(owner2, net::SiteType::kPrimary, absl::nullopt)},
+       net::FirstPartySetEntry(owner2, net::SiteType::kPrimary, std::nullopt)},
       {member3, net::FirstPartySetEntry(owner2, net::SiteType::kAssociated, 0)},
       {member4, net::FirstPartySetEntry(owner2, net::SiteType::kAssociated, 1)},
   });
@@ -6202,11 +6185,11 @@
   EXPECT_TRUE(CreateAndSetCookie(
       cm.get(), https_www_foo_.url(),
       "__Host-B=1; Secure; HttpOnly; Path=/; Partitioned", options,
-      absl::nullopt, absl::nullopt, anonymous_iframe_key));
+      std::nullopt, std::nullopt, anonymous_iframe_key));
   EXPECT_TRUE(CreateAndSetCookie(
       cm.get(), https_www_foo_.url(),
       "__Host-C=0; Secure; HttpOnly; Path=/; Partitioned", options,
-      absl::nullopt, absl::nullopt, anonymous_iframe_key));
+      std::nullopt, std::nullopt, anonymous_iframe_key));
 
   // Check cookies from outside the anonymous iframe:
   EXPECT_THAT(GetAllCookiesForURL(cm.get(), https_www_foo_.url()),
@@ -6243,7 +6226,7 @@
   // Set partitioned cookie.
   EXPECT_TRUE(CreateAndSetCookie(
       cm.get(), url, "foo=bar; Secure; SameSite=None; Partitioned", options,
-      absl::nullopt, absl::nullopt, partition_key));
+      std::nullopt, std::nullopt, partition_key));
 
   // Should return false with that cookie's partition key.
   EXPECT_THAT(cm->SiteHasCookieInOtherPartition(site, partition_key),
@@ -6259,7 +6242,7 @@
   // Set a nonced partitioned cookie with a different partition key.
   EXPECT_TRUE(CreateAndSetCookie(
       cm.get(), url, "foo=bar; Secure; SameSite=None; Partitioned", options,
-      absl::nullopt, absl::nullopt,
+      std::nullopt, std::nullopt,
       CookiePartitionKey::FromURLForTesting(GURL("https://nottoplevelsite.com"),
                                             base::UnguessableToken::Create())));
 
@@ -6270,7 +6253,7 @@
   // Set unpartitioned cookie.
   EXPECT_TRUE(CreateAndSetCookie(cm.get(), url,
                                  "bar=baz; Secure; SameSite=None;", options,
-                                 absl::nullopt, absl::nullopt));
+                                 std::nullopt, std::nullopt));
 
   // Should still return false with the original cookie's partition key. This
   // method only considers partitioned cookies.
@@ -6279,7 +6262,7 @@
 
   // Should return nullopt when the partition key is nullopt.
   EXPECT_FALSE(
-      cm->SiteHasCookieInOtherPartition(site, /*partition_key=*/absl::nullopt));
+      cm->SiteHasCookieInOtherPartition(site, /*partition_key=*/std::nullopt));
 }
 
 // Test that domain cookies which shadow origin cookies are excluded when scheme
@@ -6288,7 +6271,7 @@
   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   CookieOptions options = CookieOptions::MakeAllInclusive();
   options.set_return_excluded_cookies();
 
@@ -6325,14 +6308,14 @@
 
   auto origin_cookie1 = CanonicalCookie::Create(
       https_www_foo_.url(), "foo1=origin", creation_time, server_time,
-      /*cookie_partition_key=*/absl::nullopt);
+      /*cookie_partition_key=*/std::nullopt);
   auto origin_cookie2 = CanonicalCookie::Create(
       https_www_foo_.url(), "foo2=origin", creation_time, server_time,
-      /*cookie_partition_key=*/absl::nullopt);
+      /*cookie_partition_key=*/std::nullopt);
 
   auto domain_cookie1 = CanonicalCookie::Create(
       https_www_foo_.url(), "foo1=domain; Domain=" + https_www_foo_.domain(),
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt);
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt);
 
   // Shadowing domain cookie after the origin cookie.
   cookie_ptrs = {origin_cookie1.get(), origin_cookie2.get(),
@@ -6354,7 +6337,7 @@
 
   auto domain_cookie2 = CanonicalCookie::Create(
       https_www_foo_.url(), "foo2=domain; Domain=" + https_www_foo_.domain(),
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt);
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt);
 
   // Multiple different shadowing domain cookies.
   cookie_ptrs = {domain_cookie1.get(), origin_cookie2.get(),
@@ -6367,7 +6350,7 @@
 
   auto domain_cookie3 = CanonicalCookie::Create(
       https_www_foo_.url(), "foo3=domain; Domain=" + https_www_foo_.domain(),
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt);
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt);
 
   // Non-shadowing domain cookie should be included.
   cookie_ptrs = {domain_cookie1.get(), origin_cookie2.get(),
@@ -6382,7 +6365,7 @@
 
   auto sub_domain_cookie1 = CanonicalCookie::Create(
       https_www_foo_.url(), "foo1=subdomain; Domain=" + https_www_foo_.host(),
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt);
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt);
 
   // If there are multiple domain cookies that shadow the same cookie, they
   // should all be excluded.
@@ -6407,7 +6390,7 @@
   auto path_origin_cookie1 = CanonicalCookie::Create(
       https_www_foo_.url(), "foo1=pathorigin; Path=/bar", creation_time,
       server_time,
-      /*cookie_partition_key=*/absl::nullopt);
+      /*cookie_partition_key=*/std::nullopt);
 
   // Origin cookies on different paths may not be shadowed, even if the
   // origin cookie wouldn't be included on this request.
@@ -6421,7 +6404,7 @@
 
   auto insecure_origin_cookie1 = CanonicalCookie::Create(
       http_www_foo_.url(), "foo1=insecureorigin", creation_time, server_time,
-      /*cookie_partition_key=*/absl::nullopt);
+      /*cookie_partition_key=*/std::nullopt);
   EXPECT_EQ(insecure_origin_cookie1->SourceScheme(),
             CookieSourceScheme::kNonSecure);
 
@@ -6440,7 +6423,7 @@
   auto insecure_domain_cookie1 = CanonicalCookie::Create(
       http_www_foo_.url(),
       "foo1=insecuredomain; Domain=" + http_www_foo_.domain(), creation_time,
-      server_time, /*cookie_partition_key=*/absl::nullopt);
+      server_time, /*cookie_partition_key=*/std::nullopt);
 
   // Domain cookies that are excluded due to scheme binding shouldn't also be
   // exclude because of shadowing.
@@ -6477,16 +6460,16 @@
   auto trust_origin_cookie1 =
       CanonicalCookie::Create(http_www_trustworthy.url(), "foo1=trustorigin",
                               creation_time, server_time,
-                              /*cookie_partition_key=*/absl::nullopt);
+                              /*cookie_partition_key=*/std::nullopt);
 
   auto secure_trust_domain_cookie1 = CanonicalCookie::Create(
       https_www_trustworthy.url(),
       "foo1=securetrustdomain; Domain=" + https_www_trustworthy.domain(),
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt);
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt);
   auto secure_trust_domain_cookie2 = CanonicalCookie::Create(
       https_www_trustworthy.url(),
       "foo2=securetrustdomain; Domain=" + https_www_trustworthy.domain(),
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt);
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt);
 
   // Securely set domain cookies are excluded when shadowing trustworthy-ly set
   // origin cookies.
@@ -6502,15 +6485,15 @@
   auto trust_domain_cookie1 = CanonicalCookie::Create(
       http_www_trustworthy.url(),
       "foo1=trustdomain; Domain=" + http_www_trustworthy.domain(),
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt);
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt);
   auto trust_domain_cookie2 = CanonicalCookie::Create(
       http_www_trustworthy.url(),
       "foo2=trustdomain; Domain=" + http_www_trustworthy.domain(),
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt);
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt);
   auto secure_trust_origin_cookie1 = CanonicalCookie::Create(
       https_www_trustworthy.url(), "foo1=securetrustorigin", creation_time,
       server_time,
-      /*cookie_partition_key=*/absl::nullopt);
+      /*cookie_partition_key=*/std::nullopt);
 
   // Trustworthy-ly set domain cookies are excluded when shadowing securely set
   // origin cookies.
@@ -6526,7 +6509,7 @@
   auto port_origin_cookie1 =
       CanonicalCookie::Create(https_www_foo_.url(), "foo1=differentportorigin",
                               creation_time, server_time,
-                              /*cookie_partition_key=*/absl::nullopt);
+                              /*cookie_partition_key=*/std::nullopt);
   port_origin_cookie1->SetSourcePort(123);
 
   // Origin cookies that have warnings due to port binding don't affect domain
@@ -6597,7 +6580,7 @@
   auto store = base::MakeRefCounted<MockPersistentCookieStore>();
   auto cm = std::make_unique<CookieMonster>(store.get(), net::NetLog::Get());
   base::Time creation_time = base::Time::Now();
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   CookieOptions options = CookieOptions::MakeAllInclusive();
   options.set_return_excluded_cookies();
 
@@ -6671,14 +6654,14 @@
 
   auto origin_cookie1 = CanonicalCookie::Create(
       https_www_foo_.url(), "foo1=origin", creation_time, server_time,
-      /*cookie_partition_key=*/absl::nullopt);
+      /*cookie_partition_key=*/std::nullopt);
   auto origin_cookie2 = CanonicalCookie::Create(
       https_www_foo_.url(), "foo2=origin", creation_time, server_time,
-      /*cookie_partition_key=*/absl::nullopt);
+      /*cookie_partition_key=*/std::nullopt);
 
   auto domain_cookie1 = CanonicalCookie::Create(
       https_www_foo_.url(), "foo1=domain; Domain=" + https_www_foo_.domain(),
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt);
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt);
 
   // Shadowing domain cookie after the origin cookie.
   cookie_ptrs = {origin_cookie1.get(), origin_cookie2.get(),
@@ -6700,7 +6683,7 @@
 
   auto domain_cookie2 = CanonicalCookie::Create(
       https_www_foo_.url(), "foo2=domain; Domain=" + https_www_foo_.domain(),
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt);
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt);
 
   // Multiple different shadowing domain cookies.
   cookie_ptrs = {domain_cookie1.get(), origin_cookie2.get(),
@@ -6714,7 +6697,7 @@
 
   auto domain_cookie3 = CanonicalCookie::Create(
       https_www_foo_.url(), "foo3=domain; Domain=" + https_www_foo_.domain(),
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt);
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt);
 
   // Non-shadowing domain cookie shouldn't have a warning.
   cookie_ptrs = {domain_cookie1.get(), origin_cookie2.get(),
@@ -6729,7 +6712,7 @@
 
   auto sub_domain_cookie1 = CanonicalCookie::Create(
       https_www_foo_.url(), "foo1=subdomain; Domain=" + https_www_foo_.host(),
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt);
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt);
 
   // If there are multiple domain cookies that shadow the same cookie, they
   // should all have a warning.
@@ -6753,7 +6736,7 @@
   auto path_origin_cookie1 = CanonicalCookie::Create(
       https_www_foo_.url(), "foo1=pathorigin; Path=/bar", creation_time,
       server_time,
-      /*cookie_partition_key=*/absl::nullopt);
+      /*cookie_partition_key=*/std::nullopt);
 
   // Origin cookies on different paths may not be shadowed, even if the
   // origin cookie wouldn't be included on this request.
@@ -6766,7 +6749,7 @@
 
   auto insecure_origin_cookie1 = CanonicalCookie::Create(
       http_www_foo_.url(), "foo1=insecureorigin", creation_time, server_time,
-      /*cookie_partition_key=*/absl::nullopt);
+      /*cookie_partition_key=*/std::nullopt);
   EXPECT_EQ(insecure_origin_cookie1->SourceScheme(),
             CookieSourceScheme::kNonSecure);
 
@@ -6784,7 +6767,7 @@
   auto insecure_domain_cookie1 = CanonicalCookie::Create(
       http_www_foo_.url(),
       "foo1=insecuredomain; Domain=" + http_www_foo_.domain(), creation_time,
-      server_time, /*cookie_partition_key=*/absl::nullopt);
+      server_time, /*cookie_partition_key=*/std::nullopt);
 
   // Domain cookies that are excluded due to scheme binding shouldn't also get a
   // shadow warning.
@@ -6822,16 +6805,16 @@
   auto trust_origin_cookie1 =
       CanonicalCookie::Create(http_www_trustworthy.url(), "foo1=trustorigin",
                               creation_time, server_time,
-                              /*cookie_partition_key=*/absl::nullopt);
+                              /*cookie_partition_key=*/std::nullopt);
 
   auto secure_trust_domain_cookie1 = CanonicalCookie::Create(
       https_www_trustworthy.url(),
       "foo1=securetrustdomain; Domain=" + https_www_trustworthy.domain(),
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt);
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt);
   auto secure_trust_domain_cookie2 = CanonicalCookie::Create(
       https_www_trustworthy.url(),
       "foo2=securetrustdomain; Domain=" + https_www_trustworthy.domain(),
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt);
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt);
 
   // Securely set domain cookie has warning when shadowing trustworthy-ly set
   // origin cookies.
@@ -6847,15 +6830,15 @@
   auto trust_domain_cookie1 = CanonicalCookie::Create(
       http_www_trustworthy.url(),
       "foo1=trustdomain; Domain=" + http_www_trustworthy.domain(),
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt);
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt);
   auto trust_domain_cookie2 = CanonicalCookie::Create(
       http_www_trustworthy.url(),
       "foo2=trustdomain; Domain=" + http_www_trustworthy.domain(),
-      creation_time, server_time, /*cookie_partition_key=*/absl::nullopt);
+      creation_time, server_time, /*cookie_partition_key=*/std::nullopt);
   auto secure_trust_origin_cookie1 = CanonicalCookie::Create(
       https_www_trustworthy.url(), "foo1=securetrustorigin", creation_time,
       server_time,
-      /*cookie_partition_key=*/absl::nullopt);
+      /*cookie_partition_key=*/std::nullopt);
 
   // Trustworthy-ly set domain cookies are excluded when shadowing securely set
   // origin cookies.
@@ -6870,7 +6853,7 @@
   auto port_origin_cookie1 =
       CanonicalCookie::Create(https_www_foo_.url(), "foo1=differentportorigin",
                               creation_time, server_time,
-                              /*cookie_partition_key=*/absl::nullopt);
+                              /*cookie_partition_key=*/std::nullopt);
   port_origin_cookie1->SetSourcePort(123);
 
   // Origin cookies that have warnings due to port binding don't affect domain
@@ -6971,7 +6954,7 @@
           https_www_foo_.url(), "A", "B", https_www_foo_.url().host(), "/",
           new_creation, new_expiry, base::Time(), true, false,
           CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-          absl::nullopt),
+          std::nullopt),
       https_www_foo_.url(), false));
   EXPECT_THAT(
       GetAllCookies(cookie_monster.get()),
@@ -7014,7 +6997,7 @@
           https_www_foo_.url(), "A", "B", https_www_foo_.url().host(), "/",
           new_creation, new_expiry, base::Time(), true, false,
           CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-          absl::nullopt),
+          std::nullopt),
       https_www_foo_.url(), false));
   EXPECT_THAT(
       GetAllCookies(cookie_monster.get()),
@@ -7042,7 +7025,7 @@
           https_www_foo_.url(), "A", "B", https_www_foo_.url().host(), "/",
           original_creation, original_expiry, base::Time(), true, false,
           CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-          absl::nullopt),
+          std::nullopt),
       https_www_foo_.url(), false));
   EXPECT_THAT(
       GetAllCookies(cookie_monster.get()),
@@ -7058,7 +7041,7 @@
           https_www_foo_.url(), "A", "B", https_www_foo_.url().host(), "/",
           new_creation, new_expiry, base::Time(), true, false,
           CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-          absl::nullopt),
+          std::nullopt),
       https_www_foo_.url(), false));
   EXPECT_THAT(
       GetAllCookies(cookie_monster.get()),
@@ -7086,7 +7069,7 @@
           https_www_foo_.url(), "A", "B", https_www_foo_.url().host(), "/",
           original_creation, original_expiry, base::Time(), true, false,
           CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-          absl::nullopt),
+          std::nullopt),
       https_www_foo_.url(), false));
   EXPECT_TRUE(GetAllCookies(cookie_monster.get()).empty());
 
@@ -7099,7 +7082,7 @@
           https_www_foo_.url(), "A", "B", https_www_foo_.url().host(), "/",
           new_creation, new_expiry, base::Time(), true, false,
           CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
-          absl::nullopt),
+          std::nullopt),
       https_www_foo_.url(), false));
   EXPECT_THAT(GetAllCookies(cookie_monster.get()),
               ElementsAre(MatchesCookieNameValueCreationExpiry(
diff --git a/net/cookies/cookie_partition_key.cc b/net/cookies/cookie_partition_key.cc
index d3ba6de..2645193f 100644
--- a/net/cookies/cookie_partition_key.cc
+++ b/net/cookies/cookie_partition_key.cc
@@ -19,7 +19,7 @@
 
 CookiePartitionKey::CookiePartitionKey(
     const SchemefulSite& site,
-    absl::optional<base::UnguessableToken> nonce)
+    std::optional<base::UnguessableToken> nonce)
     : site_(site), nonce_(nonce) {}
 
 CookiePartitionKey::CookiePartitionKey(const GURL& url)
@@ -54,7 +54,7 @@
 }
 
 // static
-bool CookiePartitionKey::Serialize(const absl::optional<CookiePartitionKey>& in,
+bool CookiePartitionKey::Serialize(const std::optional<CookiePartitionKey>& in,
                                    std::string& out) {
   if (!in) {
     out = kEmptyCookiePartitionKey;
@@ -72,9 +72,9 @@
 
 // static
 bool CookiePartitionKey::Deserialize(const std::string& in,
-                                     absl::optional<CookiePartitionKey>& out) {
+                                     std::optional<CookiePartitionKey>& out) {
   if (in == kEmptyCookiePartitionKey) {
-    out = absl::nullopt;
+    out = std::nullopt;
     return true;
   }
   if (!base::FeatureList::IsEnabled(features::kPartitionedCookies)) {
@@ -88,40 +88,40 @@
     DLOG(WARNING) << "Cannot deserialize opaque origin to CookiePartitionKey";
     return false;
   }
-  out = absl::make_optional(CookiePartitionKey(schemeful_site, absl::nullopt));
+  out = std::make_optional(CookiePartitionKey(schemeful_site, std::nullopt));
   return true;
 }
 
-absl::optional<CookiePartitionKey> CookiePartitionKey::FromNetworkIsolationKey(
+std::optional<CookiePartitionKey> CookiePartitionKey::FromNetworkIsolationKey(
     const NetworkIsolationKey& network_isolation_key) {
   if (!base::FeatureList::IsEnabled(features::kPartitionedCookies)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  const absl::optional<base::UnguessableToken>& nonce =
+  const std::optional<base::UnguessableToken>& nonce =
       network_isolation_key.GetNonce();
 
   // Use frame site for nonced partitions. Since the nonce is unique, this still
   // creates a unique partition key. The reason we use the frame site is to
   // align CookiePartitionKey's implementation of nonced partitions with
   // StorageKey's. See https://crbug.com/1440765.
-  const absl::optional<SchemefulSite>& partition_key_site =
+  const std::optional<SchemefulSite>& partition_key_site =
       nonce ? network_isolation_key.GetFrameSiteForCookiePartitionKey(
                   NetworkIsolationKey::CookiePartitionKeyPassKey())
             : network_isolation_key.GetTopFrameSite();
   if (!partition_key_site)
-    return absl::nullopt;
+    return std::nullopt;
 
   return net::CookiePartitionKey(*partition_key_site, nonce);
 }
 
 // static
-absl::optional<net::CookiePartitionKey>
+std::optional<net::CookiePartitionKey>
 CookiePartitionKey::FromStorageKeyComponents(
     const SchemefulSite& site,
-    const absl::optional<base::UnguessableToken>& nonce) {
+    const std::optional<base::UnguessableToken>& nonce) {
   if (!base::FeatureList::IsEnabled(features::kPartitionedCookies)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return CookiePartitionKey::FromWire(site, nonce);
 }
diff --git a/net/cookies/cookie_partition_key.h b/net/cookies/cookie_partition_key.h
index 1c90d6c..3bd9385 100644
--- a/net/cookies/cookie_partition_key.h
+++ b/net/cookies/cookie_partition_key.h
@@ -5,12 +5,12 @@
 #ifndef NET_COOKIES_COOKIE_PARTITION_KEY_H_
 #define NET_COOKIES_COOKIE_PARTITION_KEY_H_
 
+#include <optional>
 #include <string>
 
 #include "net/base/net_export.h"
 #include "net/base/network_isolation_key.h"
 #include "net/base/schemeful_site.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace net {
@@ -43,26 +43,25 @@
   // TODO(crbug.com/1225444) Investigate ways to persist partition keys with
   // opaque origins if a browser session is restored.
   [[nodiscard]] static bool Serialize(
-      const absl::optional<CookiePartitionKey>& in,
+      const std::optional<CookiePartitionKey>& in,
       std::string& out);
   // Deserializes the result of the method above.
-  // If the result is absl::nullopt, the resulting cookie is not partitioned.
+  // If the result is std::nullopt, the resulting cookie is not partitioned.
   //
   // Returns if the resulting partition key is valid.
-  [[nodiscard]] static bool Deserialize(
-      const std::string& in,
-      absl::optional<CookiePartitionKey>& out);
+  [[nodiscard]] static bool Deserialize(const std::string& in,
+                                        std::optional<CookiePartitionKey>& out);
 
   static CookiePartitionKey FromURLForTesting(
       const GURL& url,
-      const absl::optional<base::UnguessableToken> nonce = absl::nullopt) {
+      const std::optional<base::UnguessableToken> nonce = std::nullopt) {
     return nonce ? CookiePartitionKey(SchemefulSite(url), nonce)
                  : CookiePartitionKey(url);
   }
 
   // Create a partition key from a network isolation key. Partition key is
   // derived from the key's top-frame site.
-  static absl::optional<CookiePartitionKey> FromNetworkIsolationKey(
+  static std::optional<CookiePartitionKey> FromNetworkIsolationKey(
       const NetworkIsolationKey& network_isolation_key);
 
   // Create a new CookiePartitionKey from the site of an existing
@@ -70,7 +69,7 @@
   // which were already created using Deserialize or FromNetworkIsolationKey.
   static CookiePartitionKey FromWire(
       const SchemefulSite& site,
-      absl::optional<base::UnguessableToken> nonce = absl::nullopt) {
+      std::optional<base::UnguessableToken> nonce = std::nullopt) {
     return CookiePartitionKey(site, nonce);
   }
 
@@ -86,17 +85,17 @@
   // TODO(crbug.com/1225444) Consider removing this factory method and
   // `from_script_` flag when BlinkStorageKey is available in
   // ServiceWorkerGlobalScope.
-  static absl::optional<CookiePartitionKey> FromScript() {
-    return absl::make_optional(CookiePartitionKey(true));
+  static std::optional<CookiePartitionKey> FromScript() {
+    return std::make_optional(CookiePartitionKey(true));
   }
 
   // Create a new CookiePartitionKey from the components of a StorageKey.
   // Forwards to FromWire, but unlike that method in this one the optional nonce
   // argument has no default. It also checks that cookie partitioning is enabled
   // before returning a valid key, which FromWire does not check.
-  static absl::optional<CookiePartitionKey> FromStorageKeyComponents(
+  static std::optional<CookiePartitionKey> FromStorageKeyComponents(
       const SchemefulSite& top_level_site,
-      const absl::optional<base::UnguessableToken>& nonce);
+      const std::optional<base::UnguessableToken>& nonce);
 
   const SchemefulSite& site() const { return site_; }
 
@@ -106,15 +105,15 @@
   // Cookie partition keys whose internal site is opaque cannot be serialized.
   bool IsSerializeable() const;
 
-  const absl::optional<base::UnguessableToken>& nonce() const { return nonce_; }
+  const std::optional<base::UnguessableToken>& nonce() const { return nonce_; }
 
-  static bool HasNonce(const absl::optional<CookiePartitionKey>& key) {
+  static bool HasNonce(const std::optional<CookiePartitionKey>& key) {
     return key && key->nonce();
   }
 
  private:
   explicit CookiePartitionKey(const SchemefulSite& site,
-                              absl::optional<base::UnguessableToken> nonce);
+                              std::optional<base::UnguessableToken> nonce);
   explicit CookiePartitionKey(const GURL& url);
   explicit CookiePartitionKey(bool from_script);
 
@@ -123,7 +122,7 @@
 
   // Having a nonce is a way to force a transient opaque `CookiePartitionKey`
   // for non-opaque origins.
-  absl::optional<base::UnguessableToken> nonce_;
+  std::optional<base::UnguessableToken> nonce_;
 };
 
 // Used so that CookiePartitionKeys can be the arguments of DCHECK_EQ.
diff --git a/net/cookies/cookie_partition_key_collection.h b/net/cookies/cookie_partition_key_collection.h
index eac9659..77211006 100644
--- a/net/cookies/cookie_partition_key_collection.h
+++ b/net/cookies/cookie_partition_key_collection.h
@@ -41,7 +41,7 @@
   }
 
   static CookiePartitionKeyCollection FromOptional(
-      const absl::optional<CookiePartitionKey>& opt_key) {
+      const std::optional<CookiePartitionKey>& opt_key) {
     return opt_key ? CookiePartitionKeyCollection(opt_key.value())
                    : CookiePartitionKeyCollection();
   }
diff --git a/net/cookies/cookie_partition_key_collection_unittest.cc b/net/cookies/cookie_partition_key_collection_unittest.cc
index 8c9cd9b1..67df3dd 100644
--- a/net/cookies/cookie_partition_key_collection_unittest.cc
+++ b/net/cookies/cookie_partition_key_collection_unittest.cc
@@ -57,12 +57,12 @@
 
 TEST(CookiePartitionKeyCollectionTest, FromOptional) {
   CookiePartitionKeyCollection key_collection =
-      CookiePartitionKeyCollection::FromOptional(absl::nullopt);
+      CookiePartitionKeyCollection::FromOptional(std::nullopt);
   EXPECT_TRUE(key_collection.IsEmpty());
   EXPECT_FALSE(key_collection.ContainsAllKeys());
 
   key_collection = CookiePartitionKeyCollection::FromOptional(
-      absl::make_optional<CookiePartitionKey>(
+      std::make_optional<CookiePartitionKey>(
           CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com"))));
   EXPECT_FALSE(key_collection.IsEmpty());
   EXPECT_FALSE(key_collection.ContainsAllKeys());
diff --git a/net/cookies/cookie_partition_key_fuzzer.cc b/net/cookies/cookie_partition_key_fuzzer.cc
index 8aef48e..67021f3 100644
--- a/net/cookies/cookie_partition_key_fuzzer.cc
+++ b/net/cookies/cookie_partition_key_fuzzer.cc
@@ -26,8 +26,8 @@
   if (!url.is_valid())
     return 0;
 
-  absl::optional<CookiePartitionKey> partition_key =
-      absl::make_optional(CookiePartitionKey::FromURLForTesting(url));
+  std::optional<CookiePartitionKey> partition_key =
+      std::make_optional(CookiePartitionKey::FromURLForTesting(url));
 
   bool is_opaque = url::Origin::Create(url).opaque();
   std::string tmp;
@@ -36,7 +36,7 @@
   CHECK_NE(is_opaque, CookiePartitionKey::Deserialize(url_str, partition_key));
 
   if (!is_opaque) {
-    CHECK(absl::make_optional(CookiePartitionKey::FromURLForTesting(url)) ==
+    CHECK(std::make_optional(CookiePartitionKey::FromURLForTesting(url)) ==
           partition_key);
   }
 
diff --git a/net/cookies/cookie_partition_key_unittest.cc b/net/cookies/cookie_partition_key_unittest.cc
index 9088c4bb4..04437cc2 100644
--- a/net/cookies/cookie_partition_key_unittest.cc
+++ b/net/cookies/cookie_partition_key_unittest.cc
@@ -34,12 +34,12 @@
 TEST_P(CookiePartitionKeyTest, Serialization) {
   base::UnguessableToken nonce = base::UnguessableToken::Create();
   struct {
-    absl::optional<CookiePartitionKey> input;
+    std::optional<CookiePartitionKey> input;
     bool expected_ret;
     std::string expected_output;
   } cases[] = {
       // No partition key
-      {absl::nullopt, true, kEmptyCookiePartitionKey},
+      {std::nullopt, true, kEmptyCookiePartitionKey},
       // Partition key present
       {CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite.com")),
        true, "https://toplevelsite.com"},
@@ -58,7 +58,7 @@
            SchemefulSite(GURL("https://cookiesite.com")), nonce)),
        false, ""},
       // Invalid partition key
-      {absl::make_optional(
+      {std::make_optional(
            CookiePartitionKey::FromURLForTesting(GURL("abc123foobar!!"))),
        false, ""},
   };
@@ -81,16 +81,16 @@
   struct {
     std::string input;
     bool expected_ret;
-    absl::optional<CookiePartitionKey> expected_output;
+    std::optional<CookiePartitionKey> expected_output;
   } cases[] = {
-      {kEmptyCookiePartitionKey, true, absl::nullopt},
+      {kEmptyCookiePartitionKey, true, std::nullopt},
       {"https://toplevelsite.com", true,
        CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite.com"))},
-      {"abc123foobar!!", false, absl::nullopt},
+      {"abc123foobar!!", false, std::nullopt},
   };
 
   for (const auto& tc : cases) {
-    absl::optional<CookiePartitionKey> got;
+    std::optional<CookiePartitionKey> got;
     if (PartitionedCookiesEnabled()) {
       EXPECT_EQ(tc.expected_ret,
                 CookiePartitionKey::Deserialize(tc.input, got));
@@ -119,12 +119,12 @@
   struct TestCase {
     const std::string desc;
     const NetworkIsolationKey network_isolation_key;
-    const absl::optional<CookiePartitionKey> expected;
+    const std::optional<CookiePartitionKey> expected;
   } test_cases[] = {
       {
           "Empty",
           NetworkIsolationKey(),
-          absl::nullopt,
+          std::nullopt,
       },
       {
           "WithTopLevelSite",
@@ -151,7 +151,7 @@
     }
     feature_list.InitWithFeatures(enabled_features, disabled_features);
 
-    absl::optional<CookiePartitionKey> got =
+    std::optional<CookiePartitionKey> got =
         CookiePartitionKey::FromNetworkIsolationKey(
             test_case.network_isolation_key);
 
@@ -169,12 +169,12 @@
 TEST_P(CookiePartitionKeyTest, FromWire) {
   struct TestCase {
     const GURL url;
-    const absl::optional<base::UnguessableToken> nonce;
+    const std::optional<base::UnguessableToken> nonce;
   } test_cases[] = {
-      {GURL("https://foo.com"), absl::nullopt},
-      {GURL(), absl::nullopt},
+      {GURL("https://foo.com"), std::nullopt},
+      {GURL(), std::nullopt},
       {GURL("https://foo.com"),
-       absl::make_optional(base::UnguessableToken::Create())},
+       std::make_optional(base::UnguessableToken::Create())},
   };
 
   for (const auto& test_case : test_cases) {
@@ -189,7 +189,7 @@
 TEST_P(CookiePartitionKeyTest, FromStorageKeyComponents) {
   struct TestCase {
     const GURL url;
-    const absl::optional<base::UnguessableToken> nonce = absl::nullopt;
+    const std::optional<base::UnguessableToken> nonce = std::nullopt;
   } test_cases[] = {
       {GURL("https://foo.com")},
       {GURL()},
@@ -199,7 +199,7 @@
   for (const auto& test_case : test_cases) {
     auto want =
         CookiePartitionKey::FromURLForTesting(test_case.url, test_case.nonce);
-    absl::optional<CookiePartitionKey> got =
+    std::optional<CookiePartitionKey> got =
         CookiePartitionKey::FromStorageKeyComponents(want.site(), want.nonce());
     if (PartitionedCookiesEnabled()) {
       EXPECT_EQ(got, want);
diff --git a/net/cookies/cookie_store.cc b/net/cookies/cookie_store.cc
index 8b73d3f..0299475d 100644
--- a/net/cookies/cookie_store.cc
+++ b/net/cookies/cookie_store.cc
@@ -43,10 +43,10 @@
   cookie_access_delegate_ = std::move(delegate);
 }
 
-absl::optional<bool> CookieStore::SiteHasCookieInOtherPartition(
+std::optional<bool> CookieStore::SiteHasCookieInOtherPartition(
     const net::SchemefulSite& site,
-    const absl::optional<CookiePartitionKey>& partition_key) const {
-  return absl::nullopt;
+    const std::optional<CookiePartitionKey>& partition_key) const {
+  return std::nullopt;
 }
 
 }  // namespace net
diff --git a/net/cookies/cookie_store.h b/net/cookies/cookie_store.h
index 61fd008..3f0be99 100644
--- a/net/cookies/cookie_store.h
+++ b/net/cookies/cookie_store.h
@@ -10,6 +10,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -21,7 +22,6 @@
 #include "net/cookies/cookie_deletion_info.h"
 #include "net/cookies/cookie_options.h"
 #include "net/cookies/cookie_partition_key_collection.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class GURL;
 
@@ -74,8 +74,8 @@
       const GURL& source_url,
       const CookieOptions& options,
       SetCookiesCallback callback,
-      absl::optional<CookieAccessResult> cookie_access_result =
-          absl::nullopt) = 0;
+      std::optional<CookieAccessResult> cookie_access_result =
+          std::nullopt) = 0;
 
   // Obtains a CookieList for the given |url| and |options|. The returned
   // cookies are passed into |callback|, ordered by longest path, then earliest
@@ -174,9 +174,9 @@
   // Will return nullopt if cookies have not finished loading.
   // If the partition key is null, the method assumes it is because partitioned
   // cookies are disabled.
-  virtual absl::optional<bool> SiteHasCookieInOtherPartition(
+  virtual std::optional<bool> SiteHasCookieInOtherPartition(
       const net::SchemefulSite& site,
-      const absl::optional<CookiePartitionKey>& cookie_partition_key) const;
+      const std::optional<CookiePartitionKey>& cookie_partition_key) const;
 
  private:
   // Used to determine whether a particular cookie should be subject to legacy
diff --git a/net/cookies/cookie_store_change_unittest.h b/net/cookies/cookie_store_change_unittest.h
index be89df1..925aef87 100644
--- a/net/cookies/cookie_store_change_unittest.h
+++ b/net/cookies/cookie_store_change_unittest.h
@@ -725,14 +725,14 @@
   this->CreateAndSetCookie(
       cs, GURL("https://www.example2.com"),
       "__Host-a=1; Secure; Path=/; Partitioned",
-      CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
-      absl::nullopt /* system_time */,
+      CookieOptions::MakeAllInclusive(), std::nullopt /* server_time */,
+      std::nullopt /* system_time */,
       CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")));
   this->CreateAndSetCookie(
       cs, GURL("https://www.example2.com"),
       "__Host-a=2; Secure; Path=/; Partitioned; Max-Age=7200",
-      CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
-      absl::nullopt /* system_time */,
+      CookieOptions::MakeAllInclusive(), std::nullopt /* server_time */,
+      std::nullopt /* system_time */,
       CookiePartitionKey::FromURLForTesting(GURL("https://www.bar.com"),
                                             base::UnguessableToken::Create()));
   this->DeliverChangeNotifications();
@@ -747,7 +747,7 @@
   std::vector<CookieChangeInfo> cookie_changes;
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -765,7 +765,7 @@
   this->DeliverChangeNotifications();
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -781,7 +781,7 @@
   std::vector<CookieChangeInfo> cookie_changes;
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -808,7 +808,7 @@
   std::vector<CookieChangeInfo> cookie_changes;
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -852,7 +852,7 @@
   std::vector<CookieChangeInfo> cookie_changes;
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->www_foo_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->www_foo_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -906,7 +906,7 @@
   std::vector<CookieChangeInfo> cookie_changes;
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -936,7 +936,7 @@
   std::vector<CookieChangeInfo> cookie_changes;
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -985,7 +985,7 @@
   std::vector<CookieChangeInfo> cookie_changes;
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->www_foo_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->www_foo_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -1051,7 +1051,7 @@
   std::vector<CookieChangeInfo> cookie_changes;
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -1095,7 +1095,7 @@
   std::vector<CookieChangeInfo> cookie_changes;
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->www_foo_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->www_foo_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -1191,7 +1191,7 @@
   std::vector<CookieChangeInfo> cookie_changes;
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->www_foo_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->www_foo_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -1252,7 +1252,7 @@
   std::vector<CookieChangeInfo> cookie_changes;
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -1288,13 +1288,13 @@
   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
   std::unique_ptr<CookieChangeSubscription> subscription1 =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_1)));
   std::unique_ptr<CookieChangeSubscription> subscription2 =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_2)));
@@ -1345,7 +1345,7 @@
   std::vector<CookieChangeInfo> cookie_changes;
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -1372,7 +1372,7 @@
   std::vector<CookieChangeInfo> cookie_changes;
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -1417,13 +1417,13 @@
   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
   std::unique_ptr<CookieChangeSubscription> subscription1 =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_1)));
   std::unique_ptr<CookieChangeSubscription> subscription2 =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_2)));
@@ -1478,13 +1478,13 @@
   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
   std::unique_ptr<CookieChangeSubscription> subscription1 =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_1)));
   std::unique_ptr<CookieChangeSubscription> subscription2 =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_bar_com_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_bar_com_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_2)));
@@ -1522,13 +1522,13 @@
   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
   std::unique_ptr<CookieChangeSubscription> subscription1 =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_1)));
   std::unique_ptr<CookieChangeSubscription> subscription2 =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_bar_com_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_bar_com_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_2)));
@@ -1566,13 +1566,13 @@
   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
   std::unique_ptr<CookieChangeSubscription> subscription1 =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_1)));
   std::unique_ptr<CookieChangeSubscription> subscription2 =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->www_foo_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->www_foo_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_2)));
@@ -1622,19 +1622,19 @@
   std::vector<CookieChangeInfo> cookie_changes_3;
   std::unique_ptr<CookieChangeSubscription> subscription1 =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_1)));
   std::unique_ptr<CookieChangeSubscription> subscription2 =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_bar_com_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_bar_com_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_2)));
   std::unique_ptr<CookieChangeSubscription> subscription3 =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->www_foo_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->www_foo_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_3)));
@@ -1699,13 +1699,13 @@
   std::vector<CookieChangeInfo> cookie_changes_1, cookie_changes_2;
   std::unique_ptr<CookieChangeSubscription> subscription1 =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_1)));
   std::unique_ptr<CookieChangeSubscription> subscription2 =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          this->http_www_foo_.url(), absl::nullopt /* cookie_partition_key */,
+          this->http_www_foo_.url(), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_2)));
@@ -1738,7 +1738,7 @@
   std::vector<CookieChangeInfo> cookie_changes;
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForUrl(
-          GURL("http://domain1.test"), absl::nullopt /* cookie_partition_key */,
+          GURL("http://domain1.test"), std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -1778,15 +1778,15 @@
   this->CreateAndSetCookie(
       cs, GURL("https://www.example.com/"),
       "__Host-b=2; Secure; Path=/; Partitioned",
-      CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
-      absl::nullopt /* system_time */,
+      CookieOptions::MakeAllInclusive(), std::nullopt /* server_time */,
+      std::nullopt /* system_time */,
       CookiePartitionKey::FromURLForTesting(GURL("https://sub.foo.com")));
   // Partitioned cookie with a different partition key
   this->CreateAndSetCookie(
       cs, GURL("https://www.example.com"),
       "__Host-c=3; Secure; Path=/; Partitioned",
-      CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
-      absl::nullopt /* system_time */,
+      CookieOptions::MakeAllInclusive(), std::nullopt /* server_time */,
+      std::nullopt /* system_time */,
       CookiePartitionKey::FromURLForTesting(GURL("https://www.bar.com")));
   this->DeliverChangeNotifications();
 
@@ -1805,7 +1805,7 @@
   std::unique_ptr<CookieChangeSubscription> other_subscription =
       cs->GetChangeDispatcher().AddCallbackForUrl(
           GURL("https://www.example.com/"),
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&other_cookie_changes)));
@@ -1813,8 +1813,8 @@
   this->CreateAndSetCookie(
       cs, GURL("https://www.example.com"),
       "__Host-b=2; Secure; Path=/; Partitioned; Max-Age=7200",
-      CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
-      absl::nullopt /* system_time */,
+      CookieOptions::MakeAllInclusive(), std::nullopt /* server_time */,
+      std::nullopt /* system_time */,
       CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")));
   this->DeliverChangeNotifications();
   ASSERT_EQ(0u, other_cookie_changes.size());
@@ -1852,8 +1852,8 @@
   this->CreateAndSetCookie(
       cs, GURL("https://www.example.com"),
       "__Host-a=2; Secure; Path=/; Partitioned",
-      CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
-      absl::nullopt /* system_time */,
+      CookieOptions::MakeAllInclusive(), std::nullopt /* server_time */,
+      std::nullopt /* system_time */,
       CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")));
   this->DeliverChangeNotifications();
   ASSERT_EQ(0u, cookie_changes.size());
@@ -1862,8 +1862,8 @@
   this->CreateAndSetCookie(cs, GURL("https://www.example.com"),
                            "__Host-a=3; Secure; Path=/; Partitioned",
                            CookieOptions::MakeAllInclusive(),
-                           absl::nullopt /* server_time */,
-                           absl::nullopt /* system_time */,
+                           std::nullopt /* server_time */,
+                           std::nullopt /* system_time */,
                            CookiePartitionKey::FromURLForTesting(
                                GURL("https://www.foo.com"), nonce));
   this->DeliverChangeNotifications();
@@ -1879,7 +1879,7 @@
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->http_www_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -1898,7 +1898,7 @@
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->http_www_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -1915,7 +1915,7 @@
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->http_www_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -1943,7 +1943,7 @@
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->www_foo_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -1985,7 +1985,7 @@
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->www_foo_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -2045,7 +2045,7 @@
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->http_www_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -2076,7 +2076,7 @@
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->www_foo_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -2121,7 +2121,7 @@
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->www_foo_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -2192,7 +2192,7 @@
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->http_www_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -2237,7 +2237,7 @@
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->www_foo_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -2341,7 +2341,7 @@
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->www_foo_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -2404,7 +2404,7 @@
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->www_foo_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -2444,14 +2444,14 @@
   std::unique_ptr<CookieChangeSubscription> subscription1 =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->www_foo_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_1)));
   std::unique_ptr<CookieChangeSubscription> subscription2 =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->www_foo_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_2)));
@@ -2509,7 +2509,7 @@
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->www_foo_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -2539,7 +2539,7 @@
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->www_foo_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -2587,14 +2587,14 @@
   std::unique_ptr<CookieChangeSubscription> subscription1 =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->www_foo_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_1)));
   std::unique_ptr<CookieChangeSubscription> subscription2 =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->www_foo_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_2)));
@@ -2655,14 +2655,14 @@
   std::unique_ptr<CookieChangeSubscription> subscription1 =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->http_www_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_1)));
   std::unique_ptr<CookieChangeSubscription> subscription2 =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->http_bar_com_.url(), "ghi",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_2)));
@@ -2701,14 +2701,14 @@
   std::unique_ptr<CookieChangeSubscription> subscription1 =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->http_www_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_1)));
   std::unique_ptr<CookieChangeSubscription> subscription2 =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->http_bar_com_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_2)));
@@ -2747,14 +2747,14 @@
   std::unique_ptr<CookieChangeSubscription> subscription1 =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->http_www_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_1)));
   std::unique_ptr<CookieChangeSubscription> subscription2 =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->http_www_foo_.url(), "ghi",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_2)));
@@ -2793,14 +2793,14 @@
   std::unique_ptr<CookieChangeSubscription> subscription1 =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->http_www_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_1)));
   std::unique_ptr<CookieChangeSubscription> subscription2 =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->www_foo_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_2)));
@@ -2852,28 +2852,28 @@
   std::unique_ptr<CookieChangeSubscription> subscription1 =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->http_www_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_1)));
   std::unique_ptr<CookieChangeSubscription> subscription2 =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->http_www_foo_.url(), "hij",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_2)));
   std::unique_ptr<CookieChangeSubscription> subscription3 =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->http_bar_com_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_3)));
   std::unique_ptr<CookieChangeSubscription> subscription4 =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->www_foo_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_4)));
@@ -2960,14 +2960,14 @@
   std::unique_ptr<CookieChangeSubscription> subscription1 =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->http_www_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_1)));
   std::unique_ptr<CookieChangeSubscription> subscription2 =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           this->http_www_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes_2)));
@@ -2996,7 +2996,7 @@
   std::unique_ptr<CookieChangeSubscription> subscription =
       this->GetCookieStore()->GetChangeDispatcher().AddCallbackForCookie(
           this->http_www_foo_.url(), "abc",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -3022,7 +3022,7 @@
   std::unique_ptr<CookieChangeSubscription> subscription =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           GURL("http://domain1.test"), "cookie",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&cookie_changes)));
@@ -3062,15 +3062,15 @@
   this->CreateAndSetCookie(
       cs, GURL("https://www.example.com"),
       "__Host-a=2; Secure; Path=/; Partitioned",
-      CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
-      absl::nullopt /* system_time */,
+      CookieOptions::MakeAllInclusive(), std::nullopt /* server_time */,
+      std::nullopt /* system_time */,
       CookiePartitionKey::FromURLForTesting(GURL("https://sub.foo.com")));
   // Partitioned cookie with a different partition key
   this->CreateAndSetCookie(
       cs, GURL("https://www.example.com"),
       "__Host-a=3; Secure; Path=/; Partitioned",
-      CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
-      absl::nullopt /* system_time */,
+      CookieOptions::MakeAllInclusive(), std::nullopt /* server_time */,
+      std::nullopt /* system_time */,
       CookiePartitionKey::FromURLForTesting(GURL("https://www.bar.com")));
   this->DeliverChangeNotifications();
 
@@ -3088,7 +3088,7 @@
   std::unique_ptr<CookieChangeSubscription> other_subscription =
       cs->GetChangeDispatcher().AddCallbackForCookie(
           GURL("https://www.example.com"), "__Host-a",
-          absl::nullopt /* cookie_partition_key */,
+          std::nullopt /* cookie_partition_key */,
           base::BindRepeating(
               &CookieStoreChangeTestBase<TypeParam>::OnCookieChange,
               base::Unretained(&other_cookie_changes)));
@@ -3096,8 +3096,8 @@
   this->CreateAndSetCookie(
       cs, GURL("https://www.example.com"),
       "__Host-a=2; Secure; Path=/; Partitioned; Max-Age=7200",
-      CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
-      absl::nullopt /* system_time */,
+      CookieOptions::MakeAllInclusive(), std::nullopt /* server_time */,
+      std::nullopt /* system_time */,
       CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")));
   this->DeliverChangeNotifications();
   ASSERT_EQ(0u, other_cookie_changes.size());
@@ -3135,8 +3135,8 @@
   this->CreateAndSetCookie(
       cs, GURL("https://www.example.com"),
       "__Host-a=2; Secure; Path=/; Partitioned",
-      CookieOptions::MakeAllInclusive(), absl::nullopt /* server_time */,
-      absl::nullopt /* system_time */,
+      CookieOptions::MakeAllInclusive(), std::nullopt /* server_time */,
+      std::nullopt /* system_time */,
       CookiePartitionKey::FromURLForTesting(GURL("https://www.foo.com")));
   this->DeliverChangeNotifications();
   ASSERT_EQ(0u, cookie_changes.size());
@@ -3145,8 +3145,8 @@
   this->CreateAndSetCookie(cs, GURL("https://www.example.com"),
                            "__Host-a=3; Secure; Path=/; Partitioned",
                            CookieOptions::MakeAllInclusive(),
-                           absl::nullopt /* server_time */,
-                           absl::nullopt /* system_time */,
+                           std::nullopt /* server_time */,
+                           std::nullopt /* system_time */,
                            CookiePartitionKey::FromURLForTesting(
                                GURL("https://www.foo.com"), nonce));
   this->DeliverChangeNotifications();
diff --git a/net/cookies/cookie_store_test_helpers.cc b/net/cookies/cookie_store_test_helpers.cc
index 9c8d170..031fcfc3 100644
--- a/net/cookies/cookie_store_test_helpers.cc
+++ b/net/cookies/cookie_store_test_helpers.cc
@@ -4,6 +4,7 @@
 
 #include "net/cookies/cookie_store_test_helpers.h"
 
+#include <optional>
 #include <string>
 #include <utility>
 
@@ -16,7 +17,6 @@
 #include "net/cookies/cookie_store.h"
 #include "net/cookies/cookie_util.h"
 #include "net/http/http_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 using net::registry_controlled_domains::GetDomainAndRegistry;
@@ -51,7 +51,7 @@
 DelayedCookieMonsterChangeDispatcher::AddCallbackForCookie(
     const GURL& url,
     const std::string& name,
-    const absl::optional<CookiePartitionKey>& cookie_partition_key,
+    const std::optional<CookiePartitionKey>& cookie_partition_key,
     CookieChangeCallback callback) {
   ADD_FAILURE();
   return nullptr;
@@ -59,7 +59,7 @@
 std::unique_ptr<CookieChangeSubscription>
 DelayedCookieMonsterChangeDispatcher::AddCallbackForUrl(
     const GURL& url,
-    const absl::optional<CookiePartitionKey>& cookie_partition_key,
+    const std::optional<CookiePartitionKey>& cookie_partition_key,
     CookieChangeCallback callback) {
   ADD_FAILURE();
   return nullptr;
@@ -98,7 +98,7 @@
     const GURL& source_url,
     const CookieOptions& options,
     SetCookiesCallback callback,
-    absl::optional<CookieAccessResult> cookie_access_result) {
+    std::optional<CookieAccessResult> cookie_access_result) {
   did_run_ = false;
   cookie_monster_->SetCanonicalCookieAsync(
       std::move(cookie), source_url, options,
diff --git a/net/cookies/cookie_store_test_helpers.h b/net/cookies/cookie_store_test_helpers.h
index ea91b1a..da9caebd 100644
--- a/net/cookies/cookie_store_test_helpers.h
+++ b/net/cookies/cookie_store_test_helpers.h
@@ -5,18 +5,17 @@
 #ifndef NET_COOKIES_COOKIE_STORE_TEST_HELPERS_H_
 #define NET_COOKIES_COOKIE_STORE_TEST_HELPERS_H_
 
-#include "net/cookies/cookie_monster.h"
-
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "base/functional/callback_forward.h"
 #include "base/synchronization/lock.h"
 #include "net/cookies/cookie_change_dispatcher.h"
+#include "net/cookies/cookie_monster.h"
 #include "net/log/net_log_with_source.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class GURL;
 
@@ -37,11 +36,11 @@
   [[nodiscard]] std::unique_ptr<CookieChangeSubscription> AddCallbackForCookie(
       const GURL& url,
       const std::string& name,
-      const absl::optional<CookiePartitionKey>& cookie_partition_key,
+      const std::optional<CookiePartitionKey>& cookie_partition_key,
       CookieChangeCallback callback) override;
   [[nodiscard]] std::unique_ptr<CookieChangeSubscription> AddCallbackForUrl(
       const GURL& url,
-      const absl::optional<CookiePartitionKey>& cookie_partition_key,
+      const std::optional<CookiePartitionKey>& cookie_partition_key,
       CookieChangeCallback callback) override;
   [[nodiscard]] std::unique_ptr<CookieChangeSubscription>
   AddCallbackForAllChanges(CookieChangeCallback callback) override;
@@ -65,8 +64,8 @@
       const GURL& source_url,
       const CookieOptions& options,
       SetCookiesCallback callback,
-      const absl::optional<CookieAccessResult> cookie_access_result =
-          absl::nullopt) override;
+      const std::optional<CookieAccessResult> cookie_access_result =
+          std::nullopt) override;
 
   void GetCookieListWithOptionsAsync(
       const GURL& url,
diff --git a/net/cookies/cookie_store_unittest.h b/net/cookies/cookie_store_unittest.h
index 2e982014..1959869 100644
--- a/net/cookies/cookie_store_unittest.h
+++ b/net/cookies/cookie_store_unittest.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
@@ -27,7 +28,6 @@
 #include "net/cookies/cookie_store_test_helpers.h"
 #include "net/cookies/test_cookie_access_delegate.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 #if BUILDFLAG(IS_IOS)
@@ -218,9 +218,9 @@
       const GURL& url,
       const std::string& cookie_line,
       const CookieOptions& options,
-      absl::optional<base::Time> server_time = absl::nullopt,
-      absl::optional<base::Time> system_time = absl::nullopt,
-      absl::optional<CookiePartitionKey> cookie_partition_key = absl::nullopt) {
+      std::optional<base::Time> server_time = std::nullopt,
+      std::optional<base::Time> system_time = std::nullopt,
+      std::optional<CookiePartitionKey> cookie_partition_key = std::nullopt) {
     // Ensure a different Creation date to guarantee sort order for testing
     static base::Time last = base::Time::Min();
     last = base::Time::Now() == last ? last + base::Microseconds(1)
@@ -266,8 +266,8 @@
       options.set_include_httponly();
     options.set_same_site_cookie_context(
         net::CookieOptions::SameSiteCookieContext::MakeInclusive());
-    return CreateAndSetCookie(cs, url, cookie_line, options, absl::nullopt,
-                              absl::make_optional(system_time));
+    return CreateAndSetCookie(cs, url, cookie_line, options, std::nullopt,
+                              std::make_optional(system_time));
   }
 
   bool SetCookieWithServerTime(CookieStore* cs,
@@ -280,21 +280,21 @@
     options.set_same_site_cookie_context(
         net::CookieOptions::SameSiteCookieContext::MakeInclusive());
     return CreateAndSetCookie(cs, url, cookie_line, options,
-                              absl::make_optional(server_time));
+                              std::make_optional(server_time));
   }
 
   bool SetCookie(
       CookieStore* cs,
       const GURL& url,
       const std::string& cookie_line,
-      absl::optional<CookiePartitionKey> cookie_partition_key = absl::nullopt) {
+      std::optional<CookiePartitionKey> cookie_partition_key = std::nullopt) {
     CookieOptions options;
     if (!CookieStoreTestTraits::supports_http_only)
       options.set_include_httponly();
     options.set_same_site_cookie_context(
         net::CookieOptions::SameSiteCookieContext::MakeInclusive());
-    return CreateAndSetCookie(cs, url, cookie_line, options, absl::nullopt,
-                              absl::nullopt, cookie_partition_key);
+    return CreateAndSetCookie(cs, url, cookie_line, options, std::nullopt,
+                              std::nullopt, cookie_partition_key);
   }
 
   CookieInclusionStatus CreateAndSetCookieReturnStatus(
@@ -303,8 +303,8 @@
       const std::string& cookie_line) {
     CookieInclusionStatus create_status;
     auto cookie = CanonicalCookie::Create(
-        url, cookie_line, base::Time::Now(), /*server_time=*/absl::nullopt,
-        /*cookie_partition_key=*/absl::nullopt, /*block_truncated=*/true,
+        url, cookie_line, base::Time::Now(), /*server_time=*/std::nullopt,
+        /*cookie_partition_key=*/std::nullopt, /*block_truncated=*/true,
         &create_status);
     if (!cookie)
       return create_status;
@@ -473,7 +473,7 @@
   std::unique_ptr<CanonicalCookie> cc(CanonicalCookie::CreateSanitizedCookie(
       this->www_foo_foo_.url(), "A", "B", std::string(), "/foo", one_hour_ago,
       one_hour_from_now, base::Time(), false, false,
-      CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, absl::nullopt));
+      CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, std::nullopt));
   ASSERT_TRUE(cc);
   EXPECT_TRUE(this->SetCanonicalCookie(
       cs, std::move(cc), this->www_foo_foo_.url(), true /*modify_httponly*/));
@@ -483,7 +483,7 @@
   cc = CanonicalCookie::CreateSanitizedCookie(
       this->www_foo_bar_.url(), "C", "D", this->www_foo_bar_.domain(), "/bar",
       two_hours_ago, base::Time(), one_hour_ago, false, true,
-      CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, absl::nullopt);
+      CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, std::nullopt);
   ASSERT_TRUE(cc);
   EXPECT_TRUE(this->SetCanonicalCookie(
       cs, std::move(cc), this->www_foo_bar_.url(), true /*modify_httponly*/));
@@ -495,7 +495,7 @@
   cc = CanonicalCookie::CreateSanitizedCookie(
       this->http_www_foo_.url(), "E", "F", std::string(), std::string(),
       base::Time(), base::Time(), base::Time(), true, false,
-      CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, absl::nullopt);
+      CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, std::nullopt);
   ASSERT_TRUE(cc);
   EXPECT_FALSE(this->SetCanonicalCookie(
       cs, std::move(cc), this->http_www_foo_.url(), true /*modify_httponly*/));
@@ -503,7 +503,7 @@
   cc = CanonicalCookie::CreateSanitizedCookie(
       this->https_www_foo_.url(), "E", "F", std::string(), std::string(),
       base::Time(), base::Time(), base::Time(), true, false,
-      CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, absl::nullopt);
+      CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, std::nullopt);
   ASSERT_TRUE(cc);
   EXPECT_TRUE(this->SetCanonicalCookie(
       cs, std::move(cc), this->https_www_foo_.url(), true /*modify_httponly*/));
@@ -629,7 +629,7 @@
   CookieInclusionStatus status;
   auto cookie = CanonicalCookie::Create(
       this->http_www_foo_.url(), "foo=1; Secure", base::Time::Now(),
-      /*server_time=*/absl::nullopt, /*cookie_partition_key=*/absl::nullopt,
+      /*server_time=*/std::nullopt, /*cookie_partition_key=*/std::nullopt,
       /*block_truncated=*/true, &status);
   EXPECT_TRUE(cookie->SecureAttribute());
   EXPECT_TRUE(status.IsInclude());
@@ -679,8 +679,8 @@
     CookieInclusionStatus create_status;
     auto c = CanonicalCookie::Create(this->http_www_foo_.url(),
                                      "bar=1; HttpOnly", base::Time::Now(),
-                                     /*server_time=*/absl::nullopt,
-                                     /*cookie_partition_key=*/absl::nullopt,
+                                     /*server_time=*/std::nullopt,
+                                     /*cookie_partition_key=*/std::nullopt,
                                      /*block_truncated=*/true, &create_status);
     EXPECT_TRUE(c->IsHttpOnly());
     EXPECT_TRUE(create_status.IsInclude());
@@ -1313,8 +1313,8 @@
   this->MatchCookieLines(cookie_line,
                          this->GetCookiesWithOptions(cs, url, options));
 
-  absl::optional<base::Time> server_time =
-      absl::make_optional(base::Time::Now() - base::Hours(1));
+  std::optional<base::Time> server_time =
+      std::make_optional(base::Time::Now() - base::Hours(1));
   this->CreateAndSetCookie(cs, url, set_cookie_line, options, server_time);
   this->MatchCookieLines(cookie_line,
                          this->GetCookiesWithOptions(cs, url, options));
diff --git a/net/cookies/cookie_util.cc b/net/cookies/cookie_util.cc
index 7e65dda..252309f 100644
--- a/net/cookies/cookie_util.cc
+++ b/net/cookies/cookie_util.cc
@@ -138,7 +138,7 @@
 ComputeSameSiteContextResult ComputeSameSiteContext(
     const std::vector<GURL>& url_chain,
     const SiteForCookies& site_for_cookies,
-    const absl::optional<url::Origin>& initiator,
+    const std::optional<url::Origin>& initiator,
     bool is_http,
     bool is_main_frame_navigation,
     bool compute_schemefully) {
@@ -254,7 +254,7 @@
 CookieOptions::SameSiteCookieContext ComputeSameSiteContextForSet(
     const std::vector<GURL>& url_chain,
     const SiteForCookies& site_for_cookies,
-    const absl::optional<url::Origin>& initiator,
+    const std::optional<url::Origin>& initiator,
     bool is_http,
     bool is_main_frame_navigation) {
   CookieOptions::SameSiteCookieContext same_site_context;
@@ -701,7 +701,7 @@
     const std::string& http_method,
     const std::vector<GURL>& url_chain,
     const SiteForCookies& site_for_cookies,
-    const absl::optional<url::Origin>& initiator,
+    const std::optional<url::Origin>& initiator,
     bool is_main_frame_navigation,
     bool force_ignore_site_for_cookies) {
   // Set SameSiteCookieContext according to the rules laid out in
@@ -768,7 +768,7 @@
 NET_EXPORT CookieOptions::SameSiteCookieContext
 ComputeSameSiteContextForScriptGet(const GURL& url,
                                    const SiteForCookies& site_for_cookies,
-                                   const absl::optional<url::Origin>& initiator,
+                                   const std::optional<url::Origin>& initiator,
                                    bool force_ignore_site_for_cookies) {
   if (force_ignore_site_for_cookies)
     return CookieOptions::SameSiteCookieContext::MakeInclusive();
@@ -788,7 +788,7 @@
 CookieOptions::SameSiteCookieContext ComputeSameSiteContextForResponse(
     const std::vector<GURL>& url_chain,
     const SiteForCookies& site_for_cookies,
-    const absl::optional<url::Origin>& initiator,
+    const std::optional<url::Origin>& initiator,
     bool is_main_frame_navigation,
     bool force_ignore_site_for_cookies) {
   if (force_ignore_site_for_cookies)
@@ -853,7 +853,7 @@
   // with the url. We don't check the redirect chain for script access to
   // cookies (only the URL itself).
   return ComputeSameSiteContextForSet(
-      {url}, site_for_cookies, absl::nullopt /* initiator */,
+      {url}, site_for_cookies, std::nullopt /* initiator */,
       false /* is_http */, false /* is_main_frame_navigation */);
 }
 
@@ -899,7 +899,7 @@
   return base::FeatureList::IsEnabled(features::kSchemefulSameSite);
 }
 
-absl::optional<
+std::optional<
     std::pair<FirstPartySetMetadata, FirstPartySetsCacheFilter::MatchInfo>>
 ComputeFirstPartySetMetadataMaybeAsync(
     const SchemefulSite& request_site,
diff --git a/net/cookies/cookie_util.h b/net/cookies/cookie_util.h
index 3631129..058b9ee 100644
--- a/net/cookies/cookie_util.h
+++ b/net/cookies/cookie_util.h
@@ -5,6 +5,7 @@
 #ifndef NET_COOKIES_COOKIE_UTIL_H_
 #define NET_COOKIES_COOKIE_UTIL_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -18,7 +19,6 @@
 #include "net/cookies/site_for_cookies.h"
 #include "net/first_party_sets/first_party_set_metadata.h"
 #include "net/first_party_sets/first_party_sets_cache_filter.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/origin.h"
 
 class GURL;
@@ -198,7 +198,7 @@
 // `initiator` is the origin ultimately responsible for getting the request
 // issued. It may be different from `site_for_cookies`.
 //
-// absl::nullopt for `initiator` denotes that the navigation was initiated by
+// std::nullopt for `initiator` denotes that the navigation was initiated by
 // the user directly interacting with the browser UI, e.g. entering a URL
 // or selecting a bookmark.
 //
@@ -223,7 +223,7 @@
 ComputeSameSiteContextForRequest(const std::string& http_method,
                                  const std::vector<GURL>& url_chain,
                                  const SiteForCookies& site_for_cookies,
-                                 const absl::optional<url::Origin>& initiator,
+                                 const std::optional<url::Origin>& initiator,
                                  bool is_main_frame_navigation,
                                  bool force_ignore_site_for_cookies);
 
@@ -233,7 +233,7 @@
 NET_EXPORT CookieOptions::SameSiteCookieContext
 ComputeSameSiteContextForScriptGet(const GURL& url,
                                    const SiteForCookies& site_for_cookies,
-                                   const absl::optional<url::Origin>& initiator,
+                                   const std::optional<url::Origin>& initiator,
                                    bool force_ignore_site_for_cookies);
 
 // Determines which of the cookies for the request URL can be set from a network
@@ -251,7 +251,7 @@
 NET_EXPORT CookieOptions::SameSiteCookieContext
 ComputeSameSiteContextForResponse(const std::vector<GURL>& url_chain,
                                   const SiteForCookies& site_for_cookies,
-                                  const absl::optional<url::Origin>& initiator,
+                                  const std::optional<url::Origin>& initiator,
                                   bool is_main_frame_navigation,
                                   bool force_ignore_site_for_cookies);
 
@@ -290,7 +290,7 @@
 // asynchronously with the result. The callback will be invoked iff the return
 // value is nullopt; i.e. a result will be provided via return value or
 // callback, but not both, and not neither.
-[[nodiscard]] NET_EXPORT absl::optional<
+[[nodiscard]] NET_EXPORT std::optional<
     std::pair<FirstPartySetMetadata, FirstPartySetsCacheFilter::MatchInfo>>
 ComputeFirstPartySetMetadataMaybeAsync(
     const SchemefulSite& request_site,
diff --git a/net/cookies/cookie_util_unittest.cc b/net/cookies/cookie_util_unittest.cc
index 4c69e92..edf6811 100644
--- a/net/cookies/cookie_util_unittest.cc
+++ b/net/cookies/cookie_util_unittest.cc
@@ -2,7 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "net/cookies/cookie_util.h"
+
 #include <memory>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <utility>
@@ -18,10 +21,8 @@
 #include "net/base/features.h"
 #include "net/cookies/cookie_constants.h"
 #include "net/cookies/cookie_options.h"
-#include "net/cookies/cookie_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/origin.h"
 
 namespace net {
@@ -587,16 +588,16 @@
     // It shouldn't depend on the cookie's secureness or actual source scheme.
     cookies.push_back(
         CanonicalCookie::Create(insecure_url, test.cookie, base::Time::Now(),
-                                absl::nullopt /* server_time */,
-                                absl::nullopt /* cookie_partition_key */));
+                                std::nullopt /* server_time */,
+                                std::nullopt /* cookie_partition_key */));
     cookies.push_back(
         CanonicalCookie::Create(secure_url, test.cookie, base::Time::Now(),
-                                absl::nullopt /* server_time */,
-                                absl::nullopt /* cookie_partition_key */));
+                                std::nullopt /* server_time */,
+                                std::nullopt /* cookie_partition_key */));
     cookies.push_back(CanonicalCookie::Create(
         secure_url, test.cookie + "; Secure", base::Time::Now(),
-        absl::nullopt /* server_time */,
-        absl::nullopt /* cookie_partition_key */));
+        std::nullopt /* server_time */,
+        std::nullopt /* cookie_partition_key */));
     for (const auto& cookie : cookies) {
       GURL simulated_source =
           cookie_util::SimulatedCookieSource(*cookie, test.source_scheme);
@@ -823,7 +824,7 @@
     return cross_site_sfc;
   }
 
-  std::vector<absl::optional<url::Origin>> GetAllInitiators() const {
+  std::vector<std::optional<url::Origin>> GetAllInitiators() const {
     return {kBrowserInitiated,   kOpaqueInitiator,
             kSiteInitiator,      kSecureSiteInitiator,
             kCrossSiteInitiator, kSecureCrossSiteInitiator,
@@ -831,8 +832,8 @@
             kUnrelatedInitiator};
   }
 
-  std::vector<absl::optional<url::Origin>> GetSameSiteInitiators() const {
-    std::vector<absl::optional<url::Origin>> same_site_initiators{
+  std::vector<std::optional<url::Origin>> GetSameSiteInitiators() const {
+    std::vector<std::optional<url::Origin>> same_site_initiators{
         kBrowserInitiated, kSiteInitiator, kSubdomainInitiator};
     // If schemeless, the cross-scheme origins are also same-site.
     if (!IsSchemeful()) {
@@ -842,11 +843,11 @@
     return same_site_initiators;
   }
 
-  std::vector<absl::optional<url::Origin>> GetCrossSiteInitiators() const {
-    std::vector<absl::optional<url::Origin>> cross_site_initiators;
-    std::vector<absl::optional<url::Origin>> same_site_initiators =
+  std::vector<std::optional<url::Origin>> GetCrossSiteInitiators() const {
+    std::vector<std::optional<url::Origin>> cross_site_initiators;
+    std::vector<std::optional<url::Origin>> same_site_initiators =
         GetSameSiteInitiators();
-    for (const absl::optional<url::Origin>& initiator : GetAllInitiators()) {
+    for (const std::optional<url::Origin>& initiator : GetAllInitiators()) {
       if (!base::Contains(same_site_initiators, initiator))
         cross_site_initiators.push_back(initiator);
     }
@@ -920,23 +921,23 @@
   const SiteForCookies kSecureCrossSiteForCookies =
       SiteForCookies::FromUrl(kSecureCrossSiteUrl);
   // Initiator origin.
-  const absl::optional<url::Origin> kBrowserInitiated = absl::nullopt;
-  const absl::optional<url::Origin> kOpaqueInitiator =
-      absl::make_optional(url::Origin());
-  const absl::optional<url::Origin> kSiteInitiator =
-      absl::make_optional(url::Origin::Create(kSiteUrl));
-  const absl::optional<url::Origin> kSecureSiteInitiator =
-      absl::make_optional(url::Origin::Create(kSecureSiteUrl));
-  const absl::optional<url::Origin> kCrossSiteInitiator =
-      absl::make_optional(url::Origin::Create(kCrossSiteUrl));
-  const absl::optional<url::Origin> kSecureCrossSiteInitiator =
-      absl::make_optional(url::Origin::Create(kSecureCrossSiteUrl));
-  const absl::optional<url::Origin> kSubdomainInitiator =
-      absl::make_optional(url::Origin::Create(kSubdomainUrl));
-  const absl::optional<url::Origin> kSecureSubdomainInitiator =
-      absl::make_optional(url::Origin::Create(kSecureSubdomainUrl));
-  const absl::optional<url::Origin> kUnrelatedInitiator =
-      absl::make_optional(url::Origin::Create(GURL("https://unrelated.test/")));
+  const std::optional<url::Origin> kBrowserInitiated = std::nullopt;
+  const std::optional<url::Origin> kOpaqueInitiator =
+      std::make_optional(url::Origin());
+  const std::optional<url::Origin> kSiteInitiator =
+      std::make_optional(url::Origin::Create(kSiteUrl));
+  const std::optional<url::Origin> kSecureSiteInitiator =
+      std::make_optional(url::Origin::Create(kSecureSiteUrl));
+  const std::optional<url::Origin> kCrossSiteInitiator =
+      std::make_optional(url::Origin::Create(kCrossSiteUrl));
+  const std::optional<url::Origin> kSecureCrossSiteInitiator =
+      std::make_optional(url::Origin::Create(kSecureCrossSiteUrl));
+  const std::optional<url::Origin> kSubdomainInitiator =
+      std::make_optional(url::Origin::Create(kSubdomainUrl));
+  const std::optional<url::Origin> kSecureSubdomainInitiator =
+      std::make_optional(url::Origin::Create(kSecureSubdomainUrl));
+  const std::optional<url::Origin> kUnrelatedInitiator =
+      std::make_optional(url::Origin::Create(GURL("https://unrelated.test/")));
 
  protected:
   base::test::ScopedFeatureList feature_list_;
@@ -948,7 +949,7 @@
   for (const GURL& url : GetSameSiteUrls()) {
     for (const SiteForCookies& site_for_cookies :
          GetCrossSiteSitesForCookies()) {
-      for (const absl::optional<url::Origin>& initiator : GetAllInitiators()) {
+      for (const std::optional<url::Origin>& initiator : GetAllInitiators()) {
         for (const std::string& method : {"GET", "POST", "PUT", "HEAD"}) {
           EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
                           url, site_for_cookies, initiator,
@@ -1009,7 +1010,7 @@
 
   for (const GURL& url : GetSameSiteUrls()) {
     for (const SiteForCookies& site_for_cookies : sites_for_cookies) {
-      for (const absl::optional<url::Origin>& initiator : GetAllInitiators()) {
+      for (const std::optional<url::Origin>& initiator : GetAllInitiators()) {
         for (const std::string& method : {"GET", "POST", "PUT", "HEAD"}) {
           EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
                           url, site_for_cookies, initiator,
@@ -1050,7 +1051,7 @@
     for (const SiteForCookies& site_for_cookies :
          GetSameSiteSitesForCookies()) {
       // Cross-site initiator -> it's same-site lax.
-      for (const absl::optional<url::Origin>& initiator :
+      for (const std::optional<url::Origin>& initiator :
            GetCrossSiteInitiators()) {
         EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
                         url, site_for_cookies, initiator,
@@ -1059,7 +1060,7 @@
       }
 
       // Same-site initiator -> it's same-site strict.
-      for (const absl::optional<url::Origin>& initiator :
+      for (const std::optional<url::Origin>& initiator :
            GetSameSiteInitiators()) {
         EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
                         url, site_for_cookies, initiator,
@@ -1124,7 +1125,7 @@
     for (const SiteForCookies& site_for_cookies :
          GetSameSiteSitesForCookies()) {
       // Same-Site initiator -> it's same-site strict.
-      for (const absl::optional<url::Origin>& initiator :
+      for (const std::optional<url::Origin>& initiator :
            GetSameSiteInitiators()) {
         for (const std::string& method : {"GET", "POST", "PUT", "HEAD"}) {
           for (bool is_main_frame_navigation :
@@ -1139,7 +1140,7 @@
       }
 
       // Cross-Site initiator -> it's same-site lax iff the method is safe.
-      for (const absl::optional<url::Origin>& initiator :
+      for (const std::optional<url::Origin>& initiator :
            GetCrossSiteInitiators()) {
         // For main frame navigations, the context is Lax (or Lax-unsafe).
         for (const std::string& method : {"GET", "HEAD"}) {
@@ -1387,7 +1388,7 @@
     std::vector<SiteForCookies> sites_for_cookies =
         test_case.site_for_cookies_is_same_site ? GetSameSiteSitesForCookies()
                                                 : GetCrossSiteSitesForCookies();
-    std::vector<absl::optional<url::Origin>> initiators =
+    std::vector<std::optional<url::Origin>> initiators =
         test_case.initiator_is_same_site ? GetSameSiteInitiators()
                                          : GetCrossSiteInitiators();
     ContextType expected_context_type =
@@ -1401,7 +1402,7 @@
                   .expected_context_type_for_main_frame_navigation_without_chain;
     for (const std::vector<GURL>& url_chain : url_chains) {
       for (const SiteForCookies& site_for_cookies : sites_for_cookies) {
-        for (const absl::optional<url::Origin>& initiator : initiators) {
+        for (const std::optional<url::Origin>& initiator : initiators) {
           EXPECT_THAT(
               cookie_util::ComputeSameSiteContextForRequest(
                   test_case.method, url_chain, site_for_cookies, initiator,
@@ -1491,7 +1492,7 @@
          GetSameSiteSitesForCookies()) {
       // For main frame navigations, setting all SameSite cookies is allowed
       // regardless of initiator.
-      for (const absl::optional<url::Origin>& initiator : GetAllInitiators()) {
+      for (const std::optional<url::Origin>& initiator : GetAllInitiators()) {
         if (!CanBeMainFrameNavigation(url, site_for_cookies))
           break;
         EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
@@ -1503,7 +1504,7 @@
 
       // For non-main-frame-navigation requests, the context should be lax iff
       // the initiator is same-site, and cross-site otherwise.
-      for (const absl::optional<url::Origin>& initiator :
+      for (const std::optional<url::Origin>& initiator :
            GetSameSiteInitiators()) {
         EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
                         {url}, site_for_cookies, initiator,
@@ -1511,7 +1512,7 @@
                         false /* force_ignore_site_for_cookies */),
                     ContextTypeIs(ContextType::SAME_SITE_LAX));
       }
-      for (const absl::optional<url::Origin>& initiator :
+      for (const std::optional<url::Origin>& initiator :
            GetCrossSiteInitiators()) {
         EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
                         {url}, site_for_cookies, initiator,
@@ -1581,7 +1582,7 @@
   // (ws/wss requests cannot be main frame navigations.)
 
   // Same-site initiators.
-  for (const absl::optional<url::Origin>& initiator : GetSameSiteInitiators()) {
+  for (const std::optional<url::Origin>& initiator : GetSameSiteInitiators()) {
     EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
                     {kWsUrl}, kSiteForCookies, initiator,
                     false /* is_main_frame_navigation */,
@@ -1589,8 +1590,7 @@
                 ContextTypeIs(ContextType::SAME_SITE_LAX));
   }
   // Cross-site initiators.
-  for (const absl::optional<url::Origin>& initiator :
-       GetCrossSiteInitiators()) {
+  for (const std::optional<url::Origin>& initiator : GetCrossSiteInitiators()) {
     EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
                     {kWsUrl}, kSiteForCookies, initiator,
                     false /* is_main_frame_navigation */,
@@ -1653,7 +1653,7 @@
     std::vector<SiteForCookies> sites_for_cookies =
         test_case.site_for_cookies_is_same_site ? GetSameSiteSitesForCookies()
                                                 : GetCrossSiteSitesForCookies();
-    std::vector<absl::optional<url::Origin>> initiators =
+    std::vector<std::optional<url::Origin>> initiators =
         test_case.initiator_is_same_site ? GetSameSiteInitiators()
                                          : GetCrossSiteInitiators();
     ContextType expected_context_type =
@@ -1667,7 +1667,7 @@
                   .expected_context_type_for_main_frame_navigation_without_chain;
     for (const std::vector<GURL>& url_chain : url_chains) {
       for (const SiteForCookies& site_for_cookies : sites_for_cookies) {
-        for (const absl::optional<url::Origin>& initiator : initiators) {
+        for (const std::optional<url::Origin>& initiator : initiators) {
           EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
                           url_chain, site_for_cookies, initiator,
                           false /* is_main_frame_navigation */,
@@ -1756,7 +1756,7 @@
   // (STRICT for get or LAX for set).
   for (const GURL& url : GetAllUrls()) {
     for (const SiteForCookies& site_for_cookies : GetAllSitesForCookies()) {
-      for (const absl::optional<url::Origin>& initiator : GetAllInitiators()) {
+      for (const std::optional<url::Origin>& initiator : GetAllInitiators()) {
         for (const std::string& method : {"GET", "POST", "PUT", "HEAD"}) {
           EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
                           url, site_for_cookies, initiator,
diff --git a/net/cookies/test_cookie_access_delegate.cc b/net/cookies/test_cookie_access_delegate.cc
index f577350e..b2081b5 100644
--- a/net/cookies/test_cookie_access_delegate.cc
+++ b/net/cookies/test_cookie_access_delegate.cc
@@ -59,7 +59,7 @@
   return false;
 }
 
-absl::optional<
+std::optional<
     std::pair<FirstPartySetMetadata, FirstPartySetsCacheFilter::MatchInfo>>
 TestCookieAccessDelegate::ComputeFirstPartySetMetadataMaybeAsync(
     const SchemefulSite& site,
@@ -67,8 +67,8 @@
     base::OnceCallback<void(FirstPartySetMetadata,
                             FirstPartySetsCacheFilter::MatchInfo)> callback)
     const {
-  absl::optional<FirstPartySetEntry> top_frame_owner =
-      top_frame_site ? FindFirstPartySetEntry(*top_frame_site) : absl::nullopt;
+  std::optional<FirstPartySetEntry> top_frame_owner =
+      top_frame_site ? FindFirstPartySetEntry(*top_frame_site) : std::nullopt;
   FirstPartySetMetadata metadata(
       base::OptionalToPtr(FindFirstPartySetEntry(site)),
       base::OptionalToPtr(top_frame_owner));
@@ -79,28 +79,28 @@
     base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
         FROM_HERE,
         base::BindOnce(std::move(callback), std::move(metadata), match_info));
-    return absl::nullopt;
+    return std::nullopt;
   }
   return std::pair(std::move(metadata), match_info);
 }
 
-absl::optional<FirstPartySetEntry>
+std::optional<FirstPartySetEntry>
 TestCookieAccessDelegate::FindFirstPartySetEntry(
     const SchemefulSite& site) const {
   auto entry = first_party_sets_.find(site);
 
-  return entry != first_party_sets_.end() ? absl::make_optional(entry->second)
-                                          : absl::nullopt;
+  return entry != first_party_sets_.end() ? std::make_optional(entry->second)
+                                          : std::nullopt;
 }
 
-absl::optional<base::flat_map<SchemefulSite, FirstPartySetEntry>>
+std::optional<base::flat_map<SchemefulSite, FirstPartySetEntry>>
 TestCookieAccessDelegate::FindFirstPartySetEntries(
     const base::flat_set<SchemefulSite>& sites,
     base::OnceCallback<void(base::flat_map<SchemefulSite, FirstPartySetEntry>)>
         callback) const {
   std::vector<std::pair<SchemefulSite, FirstPartySetEntry>> mapping;
   for (const SchemefulSite& site : sites) {
-    absl::optional<FirstPartySetEntry> entry = FindFirstPartySetEntry(site);
+    std::optional<FirstPartySetEntry> entry = FindFirstPartySetEntry(site);
     if (entry)
       mapping.emplace_back(site, *entry);
   }
@@ -110,13 +110,13 @@
 }
 
 template <class T>
-absl::optional<T> TestCookieAccessDelegate::RunMaybeAsync(
+std::optional<T> TestCookieAccessDelegate::RunMaybeAsync(
     T result,
     base::OnceCallback<void(T)> callback) const {
   if (invoke_callbacks_asynchronously_) {
     base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
         FROM_HERE, base::BindOnce(std::move(callback), std::move(result)));
-    return absl::nullopt;
+    return std::nullopt;
   }
   return result;
 }
diff --git a/net/cookies/test_cookie_access_delegate.h b/net/cookies/test_cookie_access_delegate.h
index 3f1ae96..7799c292 100644
--- a/net/cookies/test_cookie_access_delegate.h
+++ b/net/cookies/test_cookie_access_delegate.h
@@ -6,6 +6,7 @@
 #define NET_COOKIES_TEST_COOKIE_ACCESS_DELEGATE_H_
 
 #include <map>
+#include <optional>
 #include <set>
 #include <string>
 
@@ -18,7 +19,6 @@
 #include "net/first_party_sets/first_party_set_entry.h"
 #include "net/first_party_sets/first_party_set_metadata.h"
 #include "net/first_party_sets/first_party_sets_cache_filter.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -41,7 +41,7 @@
       const GURL& url,
       const SiteForCookies& site_for_cookies) const override;
   bool ShouldTreatUrlAsTrustworthy(const GURL& url) const override;
-  absl::optional<
+  std::optional<
       std::pair<FirstPartySetMetadata, FirstPartySetsCacheFilter::MatchInfo>>
   ComputeFirstPartySetMetadataMaybeAsync(
       const SchemefulSite& site,
@@ -49,7 +49,7 @@
       base::OnceCallback<void(FirstPartySetMetadata,
                               FirstPartySetsCacheFilter::MatchInfo)> callback)
       const override;
-  absl::optional<base::flat_map<SchemefulSite, FirstPartySetEntry>>
+  std::optional<base::flat_map<SchemefulSite, FirstPartySetEntry>>
   FindFirstPartySetEntries(
       const base::flat_set<SchemefulSite>& sites,
       base::OnceCallback<
@@ -84,7 +84,7 @@
 
  private:
   // Finds a FirstPartySetEntry for the given site, if one exists.
-  absl::optional<FirstPartySetEntry> FindFirstPartySetEntry(
+  std::optional<FirstPartySetEntry> FindFirstPartySetEntry(
       const SchemefulSite& site) const;
 
   // Discard any leading dot in the domain string.
@@ -93,8 +93,8 @@
   // Invokes the given `callback` asynchronously or returns the result
   // synchronously, depending on the configuration of this instance.
   template <class T>
-  absl::optional<T> RunMaybeAsync(T result,
-                                  base::OnceCallback<void(T)> callback) const;
+  std::optional<T> RunMaybeAsync(T result,
+                                 base::OnceCallback<void(T)> callback) const;
 
   std::map<std::string, CookieAccessSemantics> expectations_;
   std::map<std::string, bool> ignore_samesite_restrictions_schemes_;
diff --git a/net/disk_cache/backend_unittest.cc b/net/disk_cache/backend_unittest.cc
index 53b43ce..41877ef 100644
--- a/net/disk_cache/backend_unittest.cc
+++ b/net/disk_cache/backend_unittest.cc
@@ -5,6 +5,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 
 #include "base/containers/queue.h"
 #include "base/files/file.h"
@@ -61,7 +62,6 @@
 #include "net/test/gtest_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using disk_cache::EntryResult;
 using net::test::IsError;
@@ -831,8 +831,7 @@
   net::TestCompletionCallback cb;
 
   // Blocking shouldn't be needed to create the cache.
-  absl::optional<base::ScopedDisallowBlocking> disallow_blocking(
-      absl::in_place);
+  std::optional<base::ScopedDisallowBlocking> disallow_blocking(std::in_place);
   std::unique_ptr<disk_cache::BackendImpl> cache(
       std::make_unique<disk_cache::BackendImpl>(cache_path_, nullptr, nullptr,
                                                 net::DISK_CACHE, nullptr));
diff --git a/net/disk_cache/blockfile/block_files.cc b/net/disk_cache/blockfile/block_files.cc
index ebdf034b..f164cab0 100644
--- a/net/disk_cache/blockfile/block_files.cc
+++ b/net/disk_cache/blockfile/block_files.cc
@@ -7,6 +7,7 @@
 #include <atomic>
 #include <limits>
 #include <memory>
+#include <optional>
 
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -17,7 +18,6 @@
 #include "net/disk_cache/blockfile/file_lock.h"
 #include "net/disk_cache/blockfile/stress_support.h"
 #include "net/disk_cache/cache_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using base::TimeTicks;
 
@@ -350,7 +350,7 @@
   if (deep)
     file->Write(zero_buffer_.data(), size, offset);
 
-  absl::optional<FileType> type_to_delete;
+  std::optional<FileType> type_to_delete;
   {
     // Block Header can't outlive file's buffer.
     BlockHeader file_header(file);
diff --git a/net/disk_cache/cache_util.cc b/net/disk_cache/cache_util.cc
index e41fe434..2a8a5be1 100644
--- a/net/disk_cache/cache_util.cc
+++ b/net/disk_cache/cache_util.cc
@@ -59,7 +59,7 @@
 
 void CleanupTemporaryDirectories(const base::FilePath& path) {
   const base::FilePath dirname = path.DirName();
-  const absl::optional<base::SafeBaseName> basename =
+  const std::optional<base::SafeBaseName> basename =
       base::SafeBaseName::Create(path);
   if (!basename.has_value()) {
     return;
@@ -72,7 +72,7 @@
 
 bool MoveDirectoryToTemporaryDirectory(const base::FilePath& path) {
   const base::FilePath dirname = path.DirName();
-  const absl::optional<base::SafeBaseName> basename =
+  const std::optional<base::SafeBaseName> basename =
       base::SafeBaseName::Create(path);
   if (!basename.has_value()) {
     return false;
diff --git a/net/disk_cache/cache_util_unittest.cc b/net/disk_cache/cache_util_unittest.cc
index 8d6cb6c..3c3742e4 100644
--- a/net/disk_cache/cache_util_unittest.cc
+++ b/net/disk_cache/cache_util_unittest.cc
@@ -124,7 +124,7 @@
       // Caveat: On ChromeOS, we leave the top-level directory ("Cache") so
       // it must be "Cache" or "old_Cache_000".
       const base::FilePath dirname = path.DirName();
-      absl::optional<base::SafeBaseName> basename =
+      std::optional<base::SafeBaseName> basename =
           base::SafeBaseName::Create(path);
       ASSERT_EQ(dirname, tmp_dir_.GetPath());
       ASSERT_TRUE(basename.has_value());
diff --git a/net/disk_cache/disk_cache.cc b/net/disk_cache/disk_cache.cc
index eb0f34b4..2becc40 100644
--- a/net/disk_cache/disk_cache.cc
+++ b/net/disk_cache/disk_cache.cc
@@ -266,7 +266,7 @@
       : enumerator_(path) {}
   ~TrivialFileEnumerator() override = default;
 
-  absl::optional<FileEnumerationEntry> Next() override {
+  std::optional<FileEnumerationEntry> Next() override {
     return enumerator_.Next();
   }
   bool HasError() const override { return enumerator_.HasError(); }
@@ -601,7 +601,7 @@
   return base::ReplaceFile(from_path, to_path, error);
 }
 
-absl::optional<base::File::Info> TrivialFileOperations::GetFileInfo(
+std::optional<base::File::Info> TrivialFileOperations::GetFileInfo(
     const base::FilePath& path) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(path.IsAbsolute());
@@ -611,7 +611,7 @@
 
   base::File::Info file_info;
   if (!base::GetFileInfo(path, &file_info)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return file_info;
 }
diff --git a/net/disk_cache/disk_cache.h b/net/disk_cache/disk_cache.h
index cfeb141..f6effa221 100644
--- a/net/disk_cache/disk_cache.h
+++ b/net/disk_cache/disk_cache.h
@@ -11,6 +11,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -25,7 +26,6 @@
 #include "net/base/net_errors.h"
 #include "net/base/net_export.h"
 #include "net/base/request_priority.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class FilePath;
@@ -631,7 +631,7 @@
     // Returns the next file in the directory, if any. Returns nullopt if there
     // are no further files (including the error case). The path of the
     // returned entry should be a full path.
-    virtual absl::optional<FileEnumerationEntry> Next() = 0;
+    virtual std::optional<FileEnumerationEntry> Next() = 0;
 
     // Returns true if we've found an error during traversal.
     virtual bool HasError() const = 0;
@@ -662,7 +662,7 @@
                            base::File::Error* error) = 0;
 
   // Returns information about the given path.
-  virtual absl::optional<base::File::Info> GetFileInfo(
+  virtual std::optional<base::File::Info> GetFileInfo(
       const base::FilePath& path) = 0;
 
   // Creates an object that can be used to enumerate files in the specified
@@ -729,7 +729,7 @@
   bool ReplaceFile(const base::FilePath& from_path,
                    const base::FilePath& to_path,
                    base::File::Error* error) override;
-  absl::optional<base::File::Info> GetFileInfo(
+  std::optional<base::File::Info> GetFileInfo(
       const base::FilePath& path) override;
   std::unique_ptr<FileEnumerator> EnumerateFiles(
       const base::FilePath& path) override;
diff --git a/net/disk_cache/simple/simple_backend_impl.cc b/net/disk_cache/simple/simple_backend_impl.cc
index 172694a..5aa2fa1 100644
--- a/net/disk_cache/simple/simple_backend_impl.cc
+++ b/net/disk_cache/simple/simple_backend_impl.cc
@@ -753,7 +753,7 @@
                << " path: " << path.LossyDisplayName();
     result.net_error = net::ERR_FAILED;
   } else {
-    absl::optional<base::File::Info> file_info =
+    std::optional<base::File::Info> file_info =
         file_operations->GetFileInfo(path);
     if (!file_info.has_value()) {
       // Something deleted the directory between when we set it up and the
diff --git a/net/disk_cache/simple/simple_entry_impl.cc b/net/disk_cache/simple/simple_entry_impl.cc
index 41ce42f..64ea00c 100644
--- a/net/disk_cache/simple/simple_entry_impl.cc
+++ b/net/disk_cache/simple/simple_entry_impl.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <cstring>
 #include <limits>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -35,7 +36,6 @@
 #include "net/disk_cache/simple/simple_util.h"
 #include "net/log/net_log.h"
 #include "net/log/net_log_source_type.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/zlib/zlib.h"
 
 namespace disk_cache {
diff --git a/net/disk_cache/simple/simple_entry_impl.h b/net/disk_cache/simple/simple_entry_impl.h
index c7816fd..69e2a9a 100644
--- a/net/disk_cache/simple/simple_entry_impl.h
+++ b/net/disk_cache/simple/simple_entry_impl.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "base/containers/queue.h"
@@ -26,7 +27,6 @@
 #include "net/disk_cache/simple/simple_synchronous_entry.h"
 #include "net/log/net_log_event_type.h"
 #include "net/log/net_log_with_source.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class TaskRunner;
@@ -96,7 +96,7 @@
   // CompletionOnceCallback.
   net::Error DoomEntry(CompletionOnceCallback callback);
 
-  const absl::optional<std::string>& key() const { return key_; }
+  const std::optional<std::string>& key() const { return key_; }
   uint64_t entry_hash() const { return entry_hash_; }
 
   // The key is not a constructor parameter to the SimpleEntryImpl, because
@@ -376,7 +376,7 @@
   const base::FilePath path_;
   const uint64_t entry_hash_;
   const bool use_optimistic_operations_;
-  absl::optional<std::string> key_;
+  std::optional<std::string> key_;
 
   // |last_used_|, |last_modified_| and |data_size_| are copied from the
   // synchronous entry at the completion of each item of asynchronous IO.
diff --git a/net/disk_cache/simple/simple_file_enumerator.cc b/net/disk_cache/simple/simple_file_enumerator.cc
index 5ad2ad1..05cd912 100644
--- a/net/disk_cache/simple/simple_file_enumerator.cc
+++ b/net/disk_cache/simple/simple_file_enumerator.cc
@@ -27,9 +27,9 @@
   return has_error_;
 }
 
-absl::optional<SimpleFileEnumerator::Entry> SimpleFileEnumerator::Next() {
+std::optional<SimpleFileEnumerator::Entry> SimpleFileEnumerator::Next() {
   if (!dir_) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   while (true) {
     // errno must be set to 0 before every readdir() call to detect errors.
@@ -43,7 +43,7 @@
         PLOG(ERROR) << "readdir " << path_;
         has_error_ = true;
         dir_ = nullptr;
-        return absl::nullopt;
+        return std::nullopt;
       }
       break;
     }
@@ -61,12 +61,12 @@
     if (file_info.is_directory) {
       continue;
     }
-    return absl::make_optional<Entry>(std::move(path), file_info.size,
-                                      file_info.last_accessed,
-                                      file_info.last_modified);
+    return std::make_optional<Entry>(std::move(path), file_info.size,
+                                     file_info.last_accessed,
+                                     file_info.last_modified);
   }
   dir_ = nullptr;
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 #else
@@ -80,15 +80,15 @@
   return enumerator_.GetError() != base::File::FILE_OK;
 }
 
-absl::optional<SimpleFileEnumerator::Entry> SimpleFileEnumerator::Next() {
+std::optional<SimpleFileEnumerator::Entry> SimpleFileEnumerator::Next() {
   base::FilePath path = enumerator_.Next();
   if (path.empty()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   base::FileEnumerator::FileInfo info = enumerator_.GetInfo();
-  return absl::make_optional<Entry>(std::move(path), info.GetSize(),
-                                    /*last_accessed=*/base::Time(),
-                                    info.GetLastModifiedTime());
+  return std::make_optional<Entry>(std::move(path), info.GetSize(),
+                                   /*last_accessed=*/base::Time(),
+                                   info.GetLastModifiedTime());
 }
 #endif  // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
 
diff --git a/net/disk_cache/simple/simple_file_enumerator.h b/net/disk_cache/simple/simple_file_enumerator.h
index 89d37607..41dcf19 100644
--- a/net/disk_cache/simple/simple_file_enumerator.h
+++ b/net/disk_cache/simple/simple_file_enumerator.h
@@ -6,13 +6,13 @@
 #define NET_DISK_CACHE_SIMPLE_SIMPLE_FILE_ENUMERATOR_H_
 
 #include <memory>
+#include <optional>
 
 #include "base/files/file_path.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "net/base/net_export.h"
 #include "net/disk_cache/disk_cache.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
 #include <dirent.h>
@@ -38,7 +38,7 @@
 
   // Returns the next item, or nullopt if there are no more results (including
   // the error case).
-  absl::optional<Entry> Next();
+  std::optional<Entry> Next();
 
  private:
 #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
diff --git a/net/disk_cache/simple/simple_file_enumerator_unittest.cc b/net/disk_cache/simple/simple_file_enumerator_unittest.cc
index 85a35341..4e9c8f0 100644
--- a/net/disk_cache/simple/simple_file_enumerator_unittest.cc
+++ b/net/disk_cache/simple/simple_file_enumerator_unittest.cc
@@ -32,11 +32,11 @@
   EXPECT_FALSE(enumerator.HasError());
 
   // No directories should be listed, no indirect descendants should be listed.
-  EXPECT_EQ(absl::nullopt, enumerator.Next());
+  EXPECT_EQ(std::nullopt, enumerator.Next());
   EXPECT_FALSE(enumerator.HasError());
 
   // We can call enumerator.Next() after the iteration is done.
-  EXPECT_EQ(absl::nullopt, enumerator.Next());
+  EXPECT_EQ(std::nullopt, enumerator.Next());
   EXPECT_FALSE(enumerator.HasError());
 }
 
@@ -45,7 +45,7 @@
   SimpleFileEnumerator enumerator(kRoot);
 
   auto entry = enumerator.Next();
-  EXPECT_EQ(absl::nullopt, enumerator.Next());
+  EXPECT_EQ(std::nullopt, enumerator.Next());
 #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
   EXPECT_TRUE(enumerator.HasError());
 #endif
diff --git a/net/disk_cache/simple/simple_index_file.cc b/net/disk_cache/simple/simple_index_file.cc
index 4e6c698..7c646432 100644
--- a/net/disk_cache/simple/simple_index_file.cc
+++ b/net/disk_cache/simple/simple_index_file.cc
@@ -309,7 +309,7 @@
   // flush delay. This simple approach will be reconsidered if it does not allow
   // for maintaining freshness.
   base::Time cache_dir_mtime;
-  absl::optional<base::File::Info> file_info =
+  std::optional<base::File::Info> file_info =
       file_operations->GetFileInfo(cache_directory);
   if (!file_info) {
     LOG(ERROR) << "Could not obtain information about cache age";
@@ -605,7 +605,7 @@
   SimpleIndex::EntrySet* entries = &out_result->entries;
 
   auto enumerator = file_operations->EnumerateFiles(cache_directory);
-  while (absl::optional<SimpleFileEnumerator::Entry> entry =
+  while (std::optional<SimpleFileEnumerator::Entry> entry =
              enumerator->Next()) {
     ProcessEntryFile(file_operations, cache_type, entries, entry->path,
                      entry->last_accessed, entry->last_modified, entry->size);
diff --git a/net/disk_cache/simple/simple_synchronous_entry.cc b/net/disk_cache/simple/simple_synchronous_entry.cc
index 338a349..e40ef7e 100644
--- a/net/disk_cache/simple/simple_synchronous_entry.cc
+++ b/net/disk_cache/simple/simple_synchronous_entry.cc
@@ -7,6 +7,7 @@
 #include <cstring>
 #include <functional>
 #include <limits>
+#include <optional>
 
 #include "base/compiler_specific.h"
 #include "base/files/file_util.h"
@@ -33,7 +34,6 @@
 #include "net/disk_cache/simple/simple_histogram_macros.h"
 #include "net/disk_cache/simple/simple_util.h"
 #include "third_party/abseil-cpp/absl/container/inlined_vector.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/zlib/zlib.h"
 
 using base::FilePath;
@@ -342,7 +342,7 @@
 void SimpleSynchronousEntry::OpenEntry(
     net::CacheType cache_type,
     const FilePath& path,
-    const absl::optional<std::string>& key,
+    const std::optional<std::string>& key,
     const uint64_t entry_hash,
     SimpleFileTracker* file_tracker,
     std::unique_ptr<UnboundBackendFileOperations> file_operations,
@@ -1172,7 +1172,7 @@
 SimpleSynchronousEntry::SimpleSynchronousEntry(
     net::CacheType cache_type,
     const FilePath& path,
-    const absl::optional<std::string>& key,
+    const std::optional<std::string>& key,
     const uint64_t entry_hash,
     SimpleFileTracker* file_tracker,
     std::unique_ptr<UnboundBackendFileOperations> unbound_file_operations,
diff --git a/net/disk_cache/simple/simple_synchronous_entry.h b/net/disk_cache/simple/simple_synchronous_entry.h
index 0d24aa03..e17377b2 100644
--- a/net/disk_cache/simple/simple_synchronous_entry.h
+++ b/net/disk_cache/simple/simple_synchronous_entry.h
@@ -10,6 +10,7 @@
 #include <algorithm>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -28,7 +29,6 @@
 #include "net/disk_cache/simple/simple_entry_format.h"
 #include "net/disk_cache/simple/simple_file_tracker.h"
 #include "net/disk_cache/simple/simple_histogram_enums.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 class GrowableIOBuffer;
@@ -191,7 +191,7 @@
   NET_EXPORT_PRIVATE SimpleSynchronousEntry(
       net::CacheType cache_type,
       const base::FilePath& path,
-      const absl::optional<std::string>& key,
+      const std::optional<std::string>& key,
       uint64_t entry_hash,
       SimpleFileTracker* simple_file_tracker,
       std::unique_ptr<UnboundBackendFileOperations> file_operations,
@@ -206,7 +206,7 @@
   static void OpenEntry(
       net::CacheType cache_type,
       const base::FilePath& path,
-      const absl::optional<std::string>& key,
+      const std::optional<std::string>& key,
       uint64_t entry_hash,
       SimpleFileTracker* file_tracker,
       std::unique_ptr<UnboundBackendFileOperations> file_operations,
@@ -305,7 +305,7 @@
              SimpleEntryCloseResults* out_results);
 
   const base::FilePath& path() const { return path_; }
-  absl::optional<std::string> key() const { return key_; }
+  std::optional<std::string> key() const { return key_; }
   const SimpleFileTracker::EntryFileKey& entry_file_key() const {
     return entry_file_key_;
   }
@@ -497,7 +497,7 @@
   const net::CacheType cache_type_;
   const base::FilePath path_;
   SimpleFileTracker::EntryFileKey entry_file_key_;
-  absl::optional<std::string> key_;
+  std::optional<std::string> key_;
 
   bool have_open_files_ = false;
   bool initialized_ = false;
diff --git a/net/dns/host_resolver_manager_unittest.cc b/net/dns/host_resolver_manager_unittest.cc
index fa7601f9..9c8a0e0 100644
--- a/net/dns/host_resolver_manager_unittest.cc
+++ b/net/dns/host_resolver_manager_unittest.cc
@@ -13506,7 +13506,7 @@
 
   ResolveHostResponseHelper response(resolver_->CreateRequest(
       HostPortPair("host.test", 80), NetworkAnonymizationKey(),
-      NetLogWithSource(), absl::nullopt, resolve_context_.get()));
+      NetLogWithSource(), std::nullopt, resolve_context_.get()));
 
   EXPECT_THAT(response.result_error(), IsOk());
 
@@ -13553,7 +13553,7 @@
 
   ResolveHostResponseHelper response(resolver_->CreateRequest(
       HostPortPair("host.test", 80), NetworkAnonymizationKey(),
-      NetLogWithSource(), absl::nullopt, resolve_context_.get()));
+      NetLogWithSource(), std::nullopt, resolve_context_.get()));
 
   EXPECT_THAT(response.result_error(), IsOk());
 
@@ -13592,7 +13592,7 @@
 
   ResolveHostResponseHelper response(resolver_->CreateRequest(
       HostPortPair("host.test", 80), NetworkAnonymizationKey(),
-      NetLogWithSource(), absl::nullopt, resolve_context_.get()));
+      NetLogWithSource(), std::nullopt, resolve_context_.get()));
 
   EXPECT_THAT(response.result_error(), IsOk());
 
@@ -13627,7 +13627,7 @@
 
   ResolveHostResponseHelper response(resolver_->CreateRequest(
       HostPortPair("host.test", 80), NetworkAnonymizationKey(),
-      NetLogWithSource(), absl::nullopt, resolve_context_.get()));
+      NetLogWithSource(), std::nullopt, resolve_context_.get()));
 
   EXPECT_THAT(response.result_error(), IsOk());
 
@@ -13658,7 +13658,7 @@
 
   ResolveHostResponseHelper response(resolver_->CreateRequest(
       HostPortPair("host.test", 80), NetworkAnonymizationKey(),
-      NetLogWithSource(), absl::nullopt, resolve_context_.get()));
+      NetLogWithSource(), std::nullopt, resolve_context_.get()));
 
   EXPECT_THAT(response.result_error(), IsError(ERR_NAME_NOT_RESOLVED));
 }
@@ -13684,7 +13684,7 @@
 
   ResolveHostResponseHelper response(resolver_->CreateRequest(
       HostPortPair("host.test", 80), NetworkAnonymizationKey(),
-      NetLogWithSource(), absl::nullopt, resolve_context_.get()));
+      NetLogWithSource(), std::nullopt, resolve_context_.get()));
 
   EXPECT_THAT(response.result_error(), IsError(ERR_NAME_NOT_RESOLVED));
 }
@@ -13725,7 +13725,7 @@
 
   ResolveHostResponseHelper response(resolver_->CreateRequest(
       HostPortPair("host.test", 80), NetworkAnonymizationKey(),
-      NetLogWithSource(), absl::nullopt, resolve_context_.get()));
+      NetLogWithSource(), std::nullopt, resolve_context_.get()));
 
   EXPECT_THAT(response.result_error(), IsError(ERR_NAME_NOT_RESOLVED));
 
@@ -13772,7 +13772,7 @@
 
   ResolveHostResponseHelper response(resolver_->CreateRequest(
       HostPortPair("host.test", 80), NetworkAnonymizationKey(),
-      NetLogWithSource(), absl::nullopt, resolve_context_.get()));
+      NetLogWithSource(), std::nullopt, resolve_context_.get()));
 
   EXPECT_THAT(response.result_error(), IsError(ERR_NAME_NOT_RESOLVED));
 
@@ -13811,7 +13811,7 @@
 
   ResolveHostResponseHelper response(resolver_->CreateRequest(
       HostPortPair("host.test", 80), NetworkAnonymizationKey(),
-      NetLogWithSource(), absl::nullopt, resolve_context_.get()));
+      NetLogWithSource(), std::nullopt, resolve_context_.get()));
 
   EXPECT_THAT(response.result_error(), IsError(ERR_DNS_SORT_ERROR));
 
@@ -13856,7 +13856,7 @@
 
   ResolveHostResponseHelper response(resolver_->CreateRequest(
       HostPortPair("host.test", 80), NetworkAnonymizationKey(),
-      NetLogWithSource(), absl::nullopt, resolve_context_.get()));
+      NetLogWithSource(), std::nullopt, resolve_context_.get()));
 
   EXPECT_THAT(response.result_error(), IsError(ERR_DNS_SORT_ERROR));
 
@@ -13881,7 +13881,7 @@
 
   ResolveHostResponseHelper response(resolver_->CreateRequest(
       HostPortPair("ok", 80), kNetworkAnonymizationKey, NetLogWithSource(),
-      absl::nullopt, resolve_context_.get()));
+      std::nullopt, resolve_context_.get()));
   ASSERT_THAT(response.result_error(), IsOk());
 
   // Expect separate transactions to be separately cached.
@@ -13930,7 +13930,7 @@
 
   ResolveHostResponseHelper response(resolver_->CreateRequest(
       HostPortPair(kHost, 80), kNetworkAnonymizationKey, NetLogWithSource(),
-      absl::nullopt, resolve_context_.get()));
+      std::nullopt, resolve_context_.get()));
   ASSERT_THAT(response.result_error(), IsOk());
 
   // Expect each alias link and the result to be separately cached with the
diff --git a/net/extras/shared_dictionary/shared_dictionary_info.cc b/net/extras/shared_dictionary/shared_dictionary_info.cc
index d1ee5b77..fb1e8cb 100644
--- a/net/extras/shared_dictionary/shared_dictionary_info.cc
+++ b/net/extras/shared_dictionary/shared_dictionary_info.cc
@@ -17,7 +17,7 @@
     size_t size,
     const net::SHA256HashValue& hash,
     const base::UnguessableToken& disk_cache_key_token,
-    const absl::optional<int64_t>& primary_key_in_database)
+    const std::optional<int64_t>& primary_key_in_database)
     : url_(url),
       response_time_(response_time),
       expiration_(expiration),
diff --git a/net/extras/shared_dictionary/shared_dictionary_info.h b/net/extras/shared_dictionary/shared_dictionary_info.h
index 91dad3b..e846e6cc 100644
--- a/net/extras/shared_dictionary/shared_dictionary_info.h
+++ b/net/extras/shared_dictionary/shared_dictionary_info.h
@@ -30,7 +30,7 @@
                        size_t size,
                        const net::SHA256HashValue& hash,
                        const base::UnguessableToken& disk_cache_key_token,
-                       const absl::optional<int64_t>& primary_key_in_database);
+                       const std::optional<int64_t>& primary_key_in_database);
 
   SharedDictionaryInfo(const SharedDictionaryInfo&);
   SharedDictionaryInfo& operator=(const SharedDictionaryInfo&);
@@ -55,7 +55,7 @@
     return disk_cache_key_token_;
   }
 
-  const absl::optional<int64_t>& primary_key_in_database() const {
+  const std::optional<int64_t>& primary_key_in_database() const {
     return primary_key_in_database_;
   }
   void set_primary_key_in_database(int64_t primary_key_in_database) {
@@ -97,7 +97,7 @@
   base::UnguessableToken disk_cache_key_token_;
   // The primary key in SQLite database. This is nullopt until it is stored to
   // the database.
-  absl::optional<int64_t> primary_key_in_database_;
+  std::optional<int64_t> primary_key_in_database_;
 };
 
 }  // namespace net
diff --git a/net/extras/shared_dictionary/shared_dictionary_isolation_key.cc b/net/extras/shared_dictionary/shared_dictionary_isolation_key.cc
index b0153d49..a53e04a 100644
--- a/net/extras/shared_dictionary/shared_dictionary_isolation_key.cc
+++ b/net/extras/shared_dictionary/shared_dictionary_isolation_key.cc
@@ -10,7 +10,7 @@
 namespace net {
 
 // static
-absl::optional<SharedDictionaryIsolationKey>
+std::optional<SharedDictionaryIsolationKey>
 SharedDictionaryIsolationKey::MaybeCreate(
     const net::IsolationInfo& isolation_info) {
   if (!isolation_info.frame_origin() ||
@@ -18,7 +18,7 @@
       !isolation_info.top_frame_origin() ||
       isolation_info.top_frame_origin()->opaque() ||
       isolation_info.nonce().has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return SharedDictionaryIsolationKey(
       *isolation_info.frame_origin(),
@@ -26,15 +26,15 @@
 }
 
 // static
-absl::optional<SharedDictionaryIsolationKey>
+std::optional<SharedDictionaryIsolationKey>
 SharedDictionaryIsolationKey::MaybeCreate(
     const NetworkIsolationKey& network_isolation_key,
-    const absl::optional<url::Origin>& frame_origin) {
+    const std::optional<url::Origin>& frame_origin) {
   if (!frame_origin || frame_origin->opaque() ||
       !network_isolation_key.GetTopFrameSite() ||
       network_isolation_key.GetTopFrameSite()->opaque() ||
       network_isolation_key.GetNonce().has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return SharedDictionaryIsolationKey(*frame_origin,
                                       *network_isolation_key.GetTopFrameSite());
diff --git a/net/extras/shared_dictionary/shared_dictionary_isolation_key.h b/net/extras/shared_dictionary/shared_dictionary_isolation_key.h
index c817ab37..52421b6 100644
--- a/net/extras/shared_dictionary/shared_dictionary_isolation_key.h
+++ b/net/extras/shared_dictionary/shared_dictionary_isolation_key.h
@@ -5,9 +5,10 @@
 #ifndef NET_EXTRAS_SHARED_DICTIONARY_SHARED_DICTIONARY_ISOLATION_KEY_H_
 #define NET_EXTRAS_SHARED_DICTIONARY_SHARED_DICTIONARY_ISOLATION_KEY_H_
 
+#include <optional>
+
 #include "base/component_export.h"
 #include "net/base/schemeful_site.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/origin.h"
 
 namespace net {
@@ -20,15 +21,15 @@
   // Creates a SharedDictionaryIsolationKey. Returns nullopt when
   // `frame_origin` or `top_frame_origin` of `isolation_info` is not set or
   // opaque, or `nonce` is set.
-  static absl::optional<SharedDictionaryIsolationKey> MaybeCreate(
+  static std::optional<SharedDictionaryIsolationKey> MaybeCreate(
       const net::IsolationInfo& isolation_info);
 
   // Creates a SharedDictionaryIsolationKey. Returns nullopt when
   // `frame_origin` or `top_frame_origin` of `network_isolation_key` is not set
   // or opaque, or `nonce` of `network_isolation_key` is set.
-  static absl::optional<SharedDictionaryIsolationKey> MaybeCreate(
+  static std::optional<SharedDictionaryIsolationKey> MaybeCreate(
       const NetworkIsolationKey& network_isolation_key,
-      const absl::optional<url::Origin>& frame_origin);
+      const std::optional<url::Origin>& frame_origin);
 
   SharedDictionaryIsolationKey() = default;
   SharedDictionaryIsolationKey(const url::Origin& frame_origin,
diff --git a/net/extras/shared_dictionary/shared_dictionary_isolation_key_unittest.cc b/net/extras/shared_dictionary/shared_dictionary_isolation_key_unittest.cc
index baa927c6..9064c5f 100644
--- a/net/extras/shared_dictionary/shared_dictionary_isolation_key_unittest.cc
+++ b/net/extras/shared_dictionary/shared_dictionary_isolation_key_unittest.cc
@@ -18,7 +18,7 @@
 
 TEST(SharedDictionaryIsolationKeyTest, MaybeCreate) {
   url::Origin origin = url::Origin::Create(kUrl1);
-  const absl::optional<SharedDictionaryIsolationKey> isolation_key =
+  const std::optional<SharedDictionaryIsolationKey> isolation_key =
       SharedDictionaryIsolationKey::MaybeCreate(
           net::IsolationInfo::Create(net::IsolationInfo::RequestType::kOther,
                                      origin, origin, net::SiteForCookies()));
@@ -26,7 +26,7 @@
 }
 
 TEST(SharedDictionaryIsolationKeyTest, MaybeCreateOpaqueTopFrameOrigin) {
-  const absl::optional<SharedDictionaryIsolationKey> isolation_key =
+  const std::optional<SharedDictionaryIsolationKey> isolation_key =
       SharedDictionaryIsolationKey::MaybeCreate(net::IsolationInfo::Create(
           net::IsolationInfo::RequestType::kOther, url::Origin(),
           url::Origin::Create(kUrl1), net::SiteForCookies()));
@@ -35,7 +35,7 @@
 
 TEST(SharedDictionaryIsolationKeyTest, MaybeCreateOpaqueFrameOrigin) {
   url::Origin origin = url::Origin::Create(kUrl1);
-  const absl::optional<SharedDictionaryIsolationKey> isolation_key =
+  const std::optional<SharedDictionaryIsolationKey> isolation_key =
       SharedDictionaryIsolationKey::MaybeCreate(net::IsolationInfo::Create(
           net::IsolationInfo::RequestType::kOther, origin, url::Origin(),
           net::SiteForCookies()));
@@ -43,7 +43,7 @@
 }
 
 TEST(SharedDictionaryIsolationKeyTest, MaybeCreateWithNonce) {
-  const absl::optional<SharedDictionaryIsolationKey> isolation_key =
+  const std::optional<SharedDictionaryIsolationKey> isolation_key =
       SharedDictionaryIsolationKey::MaybeCreate(net::IsolationInfo::Create(
           net::IsolationInfo::RequestType::kOther, url::Origin::Create(kUrl1),
           url::Origin(), net::SiteForCookies(),
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store.cc b/net/extras/sqlite/sqlite_persistent_cookie_store.cc
index 0ef8fd6f..b1ef939 100644
--- a/net/extras/sqlite/sqlite_persistent_cookie_store.cc
+++ b/net/extras/sqlite/sqlite_persistent_cookie_store.cc
@@ -7,6 +7,7 @@
 #include <iterator>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <tuple>
 #include <unordered_set>
@@ -42,7 +43,6 @@
 #include "sql/meta_table.h"
 #include "sql/statement.h"
 #include "sql/transaction.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/third_party/mozilla/url_parse.h"
 
@@ -315,7 +315,7 @@
   }
 
   // Database upgrade statements.
-  absl::optional<int> DoMigrateDatabaseSchema() override;
+  std::optional<int> DoMigrateDatabaseSchema() override;
 
   class PendingOperation {
    public:
@@ -654,7 +654,7 @@
 
 void SQLitePersistentCookieStore::Backend::Load(
     LoadedCallback loaded_callback) {
-  LoadCookiesForKey(absl::nullopt, std::move(loaded_callback));
+  LoadCookiesForKey(std::nullopt, std::move(loaded_callback));
 }
 
 void SQLitePersistentCookieStore::Backend::LoadCookiesForKey(
@@ -891,7 +891,7 @@
       value = statement.ColumnString(4);
     }
 
-    absl::optional<CookiePartitionKey> cookie_partition_key;
+    std::optional<CookiePartitionKey> cookie_partition_key;
     std::string top_frame_site_key = statement.ColumnString(2);
     // If we can't deserialize a top_frame_site_key, we delete any cookie with
     // that key.
@@ -945,7 +945,7 @@
   return ok;
 }
 
-absl::optional<int>
+std::optional<int>
 SQLitePersistentCookieStore::Backend::DoMigrateDatabaseSchema() {
   int cur_version = meta_table()->GetVersionNumber();
 
@@ -954,17 +954,17 @@
 
     sql::Transaction transaction(db());
     if (!transaction.Begin())
-      return absl::nullopt;
+      return std::nullopt;
 
     if (!db()->Execute("DROP TABLE IF EXISTS cookies_old"))
-      return absl::nullopt;
+      return std::nullopt;
     if (!db()->Execute("ALTER TABLE cookies RENAME TO cookies_old"))
-      return absl::nullopt;
+      return std::nullopt;
     if (!db()->Execute("DROP INDEX IF EXISTS cookies_unique_index"))
-      return absl::nullopt;
+      return std::nullopt;
 
     if (!CreateV18Schema(db()))
-      return absl::nullopt;
+      return std::nullopt;
     static constexpr char insert_cookies_sql[] =
         "INSERT OR REPLACE INTO cookies "
         "(creation_utc, host_key, top_frame_site_key, name, value, "
@@ -977,16 +977,16 @@
         "       samesite, source_scheme, source_port, is_same_party, 0 "
         "FROM cookies_old ORDER BY creation_utc ASC";
     if (!db()->Execute(insert_cookies_sql))
-      return absl::nullopt;
+      return std::nullopt;
     if (!db()->Execute("DROP TABLE cookies_old"))
-      return absl::nullopt;
+      return std::nullopt;
 
     ++cur_version;
     if (!meta_table()->SetVersionNumber(cur_version) ||
         !meta_table()->SetCompatibleVersionNumber(
             std::min(cur_version, kCompatibleVersionNumber)) ||
         !transaction.Commit()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
@@ -998,19 +998,19 @@
                                  "UPDATE cookies SET expires_utc = ? WHERE "
                                  "has_expires = 1 AND expires_utc > ?"));
     if (!update_statement.is_valid()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     sql::Transaction transaction(db());
     if (!transaction.Begin()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     base::Time expires_cap = base::Time::Now() + base::Days(400);
     update_statement.BindTime(0, expires_cap);
     update_statement.BindTime(1, expires_cap);
     if (!update_statement.Run()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     ++cur_version;
@@ -1018,7 +1018,7 @@
         !meta_table()->SetCompatibleVersionNumber(
             std::min(cur_version, kCompatibleVersionNumber)) ||
         !transaction.Commit()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
@@ -1027,21 +1027,21 @@
 
     sql::Transaction transaction(db());
     if (!transaction.Begin()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     if (!db()->Execute("DROP TABLE IF EXISTS cookies_old")) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (!db()->Execute("ALTER TABLE cookies RENAME TO cookies_old")) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (!db()->Execute("DROP INDEX IF EXISTS cookies_unique_index")) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     if (!CreateV20Schema(db())) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     static constexpr char insert_cookies_sql[] =
@@ -1057,10 +1057,10 @@
         "last_update_utc "
         "FROM cookies_old ORDER BY creation_utc ASC";
     if (!db()->Execute(insert_cookies_sql)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (!db()->Execute("DROP TABLE cookies_old")) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     ++cur_version;
@@ -1068,7 +1068,7 @@
         !meta_table()->SetCompatibleVersionNumber(
             std::min(cur_version, kCompatibleVersionNumber)) ||
         !transaction.Commit()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
@@ -1077,21 +1077,21 @@
 
     sql::Transaction transaction(db());
     if (!transaction.Begin()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     if (!db()->Execute("DROP TABLE IF EXISTS cookies_old")) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (!db()->Execute("ALTER TABLE cookies RENAME TO cookies_old")) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (!db()->Execute("DROP INDEX IF EXISTS cookies_unique_index")) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     if (!CreateV21Schema(db())) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     static constexpr char insert_cookies_sql[] =
@@ -1106,10 +1106,10 @@
         "       samesite, source_scheme, source_port, last_update_utc "
         "FROM cookies_old ORDER BY creation_utc ASC";
     if (!db()->Execute(insert_cookies_sql)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (!db()->Execute("DROP TABLE cookies_old")) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     ++cur_version;
@@ -1117,13 +1117,13 @@
         !meta_table()->SetCompatibleVersionNumber(
             std::min(cur_version, kCompatibleVersionNumber)) ||
         !transaction.Commit()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
   // Put future migration cases here.
 
-  return absl::make_optional(cur_version);
+  return std::make_optional(cur_version);
 }
 
 void SQLitePersistentCookieStore::Backend::AddCookie(
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc b/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
index a5d818e..77c186f 100644
--- a/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
+++ b/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
@@ -8,6 +8,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <utility>
 
@@ -52,7 +53,6 @@
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/third_party/mozilla/url_parse.h"
 
@@ -1033,7 +1033,7 @@
         base::Time(), base::Time(),
         /*secure=*/true, false, CookieSameSite::LAX_MODE,
         COOKIE_PRIORITY_DEFAULT,
-        /*partition_key=*/absl::nullopt,
+        /*partition_key=*/std::nullopt,
         CookieSourceScheme::kUnset /* Doesn't matter for this test. */,
         input.port));
   }
@@ -1224,10 +1224,9 @@
   EXPECT_TRUE(cookie_scheme_callback1.result());
   ResultSavingCookieCallback<CookieAccessResult> set_cookie_callback;
   GURL ftp_url("ftp://subdomain.ftperiffic.com/page/");
-  auto cookie =
-      CanonicalCookie::Create(ftp_url, "A=B; max-age=3600", base::Time::Now(),
-                              absl::nullopt /* server_time */,
-                              absl::nullopt /* cookie_partition_key */);
+  auto cookie = CanonicalCookie::Create(
+      ftp_url, "A=B; max-age=3600", base::Time::Now(),
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */);
   cookie_monster->SetCanonicalCookieAsync(std::move(cookie), ftp_url,
                                           CookieOptions::MakeAllInclusive(),
                                           set_cookie_callback.MakeCallback());
@@ -1241,8 +1240,8 @@
     GURL url(base::StringPrintf("http://example%d.com/", i));
     auto canonical_cookie =
         CanonicalCookie::Create(url, "A=B; max-age=3600", base::Time::Now(),
-                                absl::nullopt /* server_time */,
-                                absl::nullopt /* cookie_partition_key */);
+                                std::nullopt /* server_time */,
+                                std::nullopt /* cookie_partition_key */);
     cookie_monster->SetCanonicalCookieAsync(
         std::move(canonical_cookie), url, CookieOptions::MakeAllInclusive(),
         set_cookie_callback2.MakeCallback());
@@ -1297,10 +1296,9 @@
 
   ResultSavingCookieCallback<CookieAccessResult> set_cookie_callback;
   GURL url("http://www.example.com/");
-  auto cookie =
-      CanonicalCookie::Create(url, "A=B; max-age=3600", base::Time::Now(),
-                              absl::nullopt /* server_time */,
-                              absl::nullopt /* cookie_partition_key */);
+  auto cookie = CanonicalCookie::Create(
+      url, "A=B; max-age=3600", base::Time::Now(),
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */);
   cookie_monster->SetCanonicalCookieAsync(std::move(cookie), url,
                                           CookieOptions::MakeAllInclusive(),
                                           set_cookie_callback.MakeCallback());
@@ -1334,8 +1332,7 @@
 
   std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
       GURL("http://www.example.com/path"), "Tasty=Yes", base::Time::Now(),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */);
 
   for (const TestCase& testcase : testcases) {
     Create(false, false, true /* want current thread to invoke the store. */,
@@ -1391,13 +1388,11 @@
 
   std::unique_ptr<CanonicalCookie> cookie1 = CanonicalCookie::Create(
       GURL("http://www.example.com/path"), "Tasty=Yes", base::Time::Now(),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */);
 
   std::unique_ptr<CanonicalCookie> cookie2 = CanonicalCookie::Create(
       GURL("http://not.example.com/path"), "Tasty=No", base::Time::Now(),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */);
 
   // Wedge the background thread to make sure that it doesn't start consuming
   // the queue.
@@ -1435,8 +1430,7 @@
 
   std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
       GURL("http://www.example.com/path"), "Tasty=Yes", base::Time::Now(),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */);
 
   // Wedge the background thread to make sure that it doesn't start consuming
   // the queue.
@@ -2002,7 +1996,7 @@
 
     basic_cookie_ = CanonicalCookie::Create(
         basic_url_, "a=b; max-age=100000", /*creation_time=*/base::Time::Now(),
-        /*server_time=*/absl::nullopt, /*cookie_partition_key=*/absl::nullopt);
+        /*server_time=*/std::nullopt, /*cookie_partition_key=*/std::nullopt);
 
     http_cookie_ = std::make_unique<CanonicalCookie>(*basic_cookie_);
     http_cookie_->SetSourceScheme(CookieSourceScheme::kNonSecure);
@@ -2047,7 +2041,7 @@
   auto basic_cookie2 = CanonicalCookie::Create(
       basic_url_, "a=b2; max-age=100000",
       /*creation_time=*/base::Time::Now(),
-      /*server_time=*/absl::nullopt, /*cookie_partition_key=*/absl::nullopt);
+      /*server_time=*/std::nullopt, /*cookie_partition_key=*/std::nullopt);
 
   store_->AddCookie(*basic_cookie2);
 
diff --git a/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.cc b/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.cc
index 3aafc03..95318ae 100644
--- a/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.cc
+++ b/net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.cc
@@ -79,7 +79,7 @@
 [[nodiscard]] bool NetworkAnonymizationKeyFromString(
     const std::string& string,
     NetworkAnonymizationKey* out_network_anonymization_key) {
-  absl::optional<base::Value> value = base::JSONReader::Read(string);
+  std::optional<base::Value> value = base::JSONReader::Read(string);
   if (!value)
     return false;
 
@@ -188,7 +188,7 @@
 
   // SQLitePersistentStoreBackendBase implementation
   bool CreateDatabaseSchema() override;
-  absl::optional<int> DoMigrateDatabaseSchema() override;
+  std::optional<int> DoMigrateDatabaseSchema() override;
   void DoCommit() override;
 
   // Commit a pending operation pertaining to a NEL policy.
@@ -691,7 +691,7 @@
   return true;
 }
 
-absl::optional<int>
+std::optional<int>
 SQLitePersistentReportingAndNelStore::Backend::DoMigrateDatabaseSchema() {
   int cur_version = meta_table()->GetVersionNumber();
 
@@ -706,15 +706,15 @@
   if (cur_version == 1) {
     sql::Transaction transaction(db());
     if (!transaction.Begin())
-      return absl::nullopt;
+      return std::nullopt;
 
     // Migrate NEL policies table.
     if (!db()->Execute("DROP TABLE IF EXISTS nel_policies_old; "
                        "ALTER TABLE nel_policies RENAME TO nel_policies_old")) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (!CreateV2NelPoliciesSchema(db()))
-      return absl::nullopt;
+      return std::nullopt;
     // clang-format off
     // The "report_to" field is renamed to "group_name" for consistency with
     // the other tables.
@@ -730,18 +730,18 @@
       "FROM nel_policies_old" ;
     // clang-format on
     if (!db()->Execute(nel_policies_migrate_stmt.c_str()))
-      return absl::nullopt;
+      return std::nullopt;
     if (!db()->Execute("DROP TABLE nel_policies_old"))
-      return absl::nullopt;
+      return std::nullopt;
 
     // Migrate Reporting endpoints table.
     if (!db()->Execute("DROP TABLE IF EXISTS reporting_endpoints_old; "
                        "ALTER TABLE reporting_endpoints RENAME TO "
                        "reporting_endpoints_old")) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (!CreateV2ReportingEndpointsSchema(db()))
-      return absl::nullopt;
+      return std::nullopt;
     // clang-format off
     std::string reporting_endpoints_migrate_stmt =
       "INSERT INTO reporting_endpoints (nik,  origin_scheme, origin_host, "
@@ -751,18 +751,18 @@
       "FROM reporting_endpoints_old" ;
     // clang-format on
     if (!db()->Execute(reporting_endpoints_migrate_stmt.c_str()))
-      return absl::nullopt;
+      return std::nullopt;
     if (!db()->Execute("DROP TABLE reporting_endpoints_old"))
-      return absl::nullopt;
+      return std::nullopt;
 
     // Migrate Reporting endpoint groups table.
     if (!db()->Execute("DROP TABLE IF EXISTS reporting_endpoint_groups_old; "
                        "ALTER TABLE reporting_endpoint_groups RENAME TO "
                        "reporting_endpoint_groups_old")) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (!CreateV2ReportingEndpointGroupsSchema(db()))
-      return absl::nullopt;
+      return std::nullopt;
     // clang-format off
     std::string reporting_endpoint_groups_migrate_stmt =
       "INSERT INTO reporting_endpoint_groups (nik,  origin_scheme, "
@@ -774,22 +774,22 @@
       "FROM reporting_endpoint_groups_old" ;
     // clang-format on
     if (!db()->Execute(reporting_endpoint_groups_migrate_stmt.c_str()))
-      return absl::nullopt;
+      return std::nullopt;
     if (!db()->Execute("DROP TABLE reporting_endpoint_groups_old"))
-      return absl::nullopt;
+      return std::nullopt;
 
     ++cur_version;
     if (!meta_table()->SetVersionNumber(cur_version) ||
         !meta_table()->SetCompatibleVersionNumber(
             std::min(cur_version, kCompatibleVersionNumber)) ||
         !transaction.Commit()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
   // Future database upgrade statements go here.
 
-  return absl::make_optional(cur_version);
+  return std::make_optional(cur_version);
 }
 
 void SQLitePersistentReportingAndNelStore::Backend::DoCommit() {
diff --git a/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.cc b/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.cc
index dfff8de..c54b648 100644
--- a/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.cc
+++ b/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.cc
@@ -123,18 +123,18 @@
   return true;
 }
 
-absl::optional<SHA256HashValue> ToSHA256HashValue(
+std::optional<SHA256HashValue> ToSHA256HashValue(
     base::span<const uint8_t> sha256_bytes) {
   SHA256HashValue sha256_hash;
   if (sha256_bytes.size() != sizeof(sha256_hash.data)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   memcpy(sha256_hash.data, sha256_bytes.data(), sha256_bytes.size());
   return sha256_hash;
 }
 
-absl::optional<base::UnguessableToken> ToUnguessableToken(int64_t token_high,
-                                                          int64_t token_low) {
+std::optional<base::UnguessableToken> ToUnguessableToken(int64_t token_high,
+                                                         int64_t token_low) {
   // There is no `sql::Statement::ColumnUint64()` method. So we cast to
   // uint64_t.
   return base::UnguessableToken::Deserialize(static_cast<uint64_t>(token_high),
@@ -178,7 +178,7 @@
 SQLitePersistentSharedDictionaryStore::RegisterDictionaryResult::
     RegisterDictionaryResult(
         int64_t primary_key_in_database,
-        absl::optional<base::UnguessableToken> replaced_disk_cache_key_token,
+        std::optional<base::UnguessableToken> replaced_disk_cache_key_token,
         std::set<base::UnguessableToken> evicted_disk_cache_key_tokens,
         uint64_t total_dictionary_size,
         uint64_t total_dictionary_count)
@@ -305,7 +305,7 @@
       const std::string& match,
       const std::string& match_dest,
       int64_t* size_out,
-      absl::optional<base::UnguessableToken>* disk_cache_key_out);
+      std::optional<base::UnguessableToken>* disk_cache_key_out);
 
   // Updates the total dictionary size in MetaTable by `size_delta` and returns
   // the updated total dictionary size.
@@ -318,7 +318,7 @@
 
   // SQLitePersistentStoreBackendBase implementation
   bool CreateDatabaseSchema() override;
-  absl::optional<int> DoMigrateDatabaseSchema() override;
+  std::optional<int> DoMigrateDatabaseSchema() override;
   void DoCommit() override;
 
   // Commits the last used time update.
@@ -397,7 +397,7 @@
   return true;
 }
 
-absl::optional<int>
+std::optional<int>
 SQLitePersistentSharedDictionaryStore::Backend::DoMigrateDatabaseSchema() {
   int cur_version = meta_table()->GetVersionNumber();
   if (cur_version == 1) {
@@ -405,7 +405,7 @@
     if (!transaction.Begin() ||
         !db()->Execute("DROP TABLE IF EXISTS dictionaries") ||
         !meta_table()->DeleteKey(kTotalDictSizeKey)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     // The version 1 is used during the Origin Trial period (M119-M122).
     // We don't need to migrate the data from version 1.
@@ -414,13 +414,13 @@
         !meta_table()->SetCompatibleVersionNumber(
             std::min(cur_version, kCompatibleVersionNumber)) ||
         !transaction.Commit()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
   // Future database upgrade statements go here.
 
-  return absl::make_optional(cur_version);
+  return std::make_optional(cur_version);
 }
 
 void SQLitePersistentSharedDictionaryStore::Backend::DoCommit() {
@@ -512,7 +512,7 @@
   }
 
   int64_t size_of_removed_dict = 0;
-  absl::optional<base::UnguessableToken> replaced_disk_cache_key_token;
+  std::optional<base::UnguessableToken> replaced_disk_cache_key_token;
   int64_t size_delta = dictionary_info.size();
   if (GetExistingDictionarySizeAndDiskCacheKeyToken(
           isolation_key, url::SchemeHostPort(dictionary_info.url()),
@@ -696,7 +696,7 @@
     const int64_t token_high = statement.ColumnInt64(2);
     const int64_t token_low = statement.ColumnInt64(3);
 
-    absl::optional<base::UnguessableToken> disk_cache_key_token =
+    std::optional<base::UnguessableToken> disk_cache_key_token =
         ToUnguessableToken(token_high, token_low);
     if (!disk_cache_key_token) {
       LOG(WARNING) << "Invalid token";
@@ -820,13 +820,13 @@
     const base::Time last_used_time = statement.ColumnTime(7);
     const size_t size = statement.ColumnInt64(8);
 
-    absl::optional<SHA256HashValue> sha256_hash =
+    std::optional<SHA256HashValue> sha256_hash =
         ToSHA256HashValue(statement.ColumnBlob(9));
     if (!sha256_hash) {
       LOG(WARNING) << "Invalid hash";
       continue;
     }
-    absl::optional<base::UnguessableToken> disk_cache_key_token =
+    std::optional<base::UnguessableToken> disk_cache_key_token =
         ToUnguessableToken(statement.ColumnInt64(10),
                            statement.ColumnInt64(11));
     if (!disk_cache_key_token) {
@@ -889,14 +889,14 @@
     const base::Time last_used_time = statement.ColumnTime(9);
     const size_t size = statement.ColumnInt64(10);
 
-    absl::optional<SHA256HashValue> sha256_hash =
+    std::optional<SHA256HashValue> sha256_hash =
         ToSHA256HashValue(statement.ColumnBlob(11));
     if (!sha256_hash) {
       LOG(WARNING) << "Invalid hash";
       continue;
     }
 
-    absl::optional<base::UnguessableToken> disk_cache_key_token =
+    std::optional<base::UnguessableToken> disk_cache_key_token =
         ToUnguessableToken(statement.ColumnInt64(12),
                            statement.ColumnInt64(13));
     if (!disk_cache_key_token) {
@@ -1020,7 +1020,7 @@
   while (statement.Step()) {
     const int64_t token_high = statement.ColumnInt64(0);
     const int64_t token_low = statement.ColumnInt64(1);
-    absl::optional<base::UnguessableToken> disk_cache_key_token =
+    std::optional<base::UnguessableToken> disk_cache_key_token =
         ToUnguessableToken(token_high, token_low);
     if (!disk_cache_key_token) {
       continue;
@@ -1121,7 +1121,7 @@
     const size_t size = statement.ColumnInt64(1);
     const int64_t token_high = statement.ColumnInt64(2);
     const int64_t token_low = statement.ColumnInt64(3);
-    absl::optional<base::UnguessableToken> disk_cache_key_token =
+    std::optional<base::UnguessableToken> disk_cache_key_token =
         ToUnguessableToken(token_high, token_low);
     if (!disk_cache_key_token) {
       LOG(WARNING) << "Invalid token";
@@ -1182,7 +1182,7 @@
         !url_matcher.Run(GURL(host))) {
       continue;
     }
-    absl::optional<base::UnguessableToken> disk_cache_key_token =
+    std::optional<base::UnguessableToken> disk_cache_key_token =
         ToUnguessableToken(token_high, token_low);
     if (!disk_cache_key_token) {
       LOG(WARNING) << "Invalid token";
@@ -1233,7 +1233,7 @@
 
     checked_total_size += size;
 
-    absl::optional<base::UnguessableToken> disk_cache_key_token =
+    std::optional<base::UnguessableToken> disk_cache_key_token =
         ToUnguessableToken(token_high, token_low);
     if (!disk_cache_key_token) {
       continue;
@@ -1289,7 +1289,7 @@
 
     checked_total_size += size;
 
-    absl::optional<base::UnguessableToken> disk_cache_key_token =
+    std::optional<base::UnguessableToken> disk_cache_key_token =
         ToUnguessableToken(token_high, token_low);
     if (!disk_cache_key_token) {
       LOG(WARNING) << "Invalid token";
@@ -1404,7 +1404,7 @@
     const size_t size = statement.ColumnInt64(1);
     const int64_t token_high = statement.ColumnInt64(2);
     const int64_t token_low = statement.ColumnInt64(3);
-    absl::optional<base::UnguessableToken> disk_cache_key_token =
+    std::optional<base::UnguessableToken> disk_cache_key_token =
         ToUnguessableToken(token_high, token_low);
     if (!disk_cache_key_token) {
       LOG(WARNING) << "Invalid token";
@@ -1545,7 +1545,7 @@
   sql::Statement statement(db()->GetCachedStatement(SQL_FROM_HERE, kQuery));
   std::vector<base::UnguessableToken> tokens;
   while (statement.Step()) {
-    absl::optional<base::UnguessableToken> disk_cache_key_token =
+    std::optional<base::UnguessableToken> disk_cache_key_token =
         ToUnguessableToken(statement.ColumnInt64(1), statement.ColumnInt64(2));
     if (!disk_cache_key_token) {
       LOG(WARNING) << "Invalid token";
@@ -1609,7 +1609,7 @@
         const std::string& match,
         const std::string& match_dest,
         int64_t* size_out,
-        absl::optional<base::UnguessableToken>* disk_cache_key_out) {
+        std::optional<base::UnguessableToken>* disk_cache_key_out) {
   CHECK(background_task_runner()->RunsTasksInCurrentSequence());
 
   static constexpr char kQuery[] =
diff --git a/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.h b/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.h
index 364aa3e..b1bf1f17 100644
--- a/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.h
+++ b/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.h
@@ -53,7 +53,7 @@
    public:
     RegisterDictionaryResult(
         int64_t primary_key_in_database,
-        absl::optional<base::UnguessableToken> replaced_disk_cache_key_token,
+        std::optional<base::UnguessableToken> replaced_disk_cache_key_token,
         std::set<base::UnguessableToken> evicted_disk_cache_key_tokens,
         uint64_t total_dictionary_size,
         uint64_t total_dictionary_count);
@@ -65,8 +65,8 @@
     RegisterDictionaryResult& operator=(RegisterDictionaryResult&& other);
 
     int64_t primary_key_in_database() const { return primary_key_in_database_; }
-    const absl::optional<base::UnguessableToken>&
-    replaced_disk_cache_key_token() const {
+    const std::optional<base::UnguessableToken>& replaced_disk_cache_key_token()
+        const {
       return replaced_disk_cache_key_token_;
     }
     const std::set<base::UnguessableToken>& evicted_disk_cache_key_tokens()
@@ -78,7 +78,7 @@
 
    private:
     int64_t primary_key_in_database_;
-    absl::optional<base::UnguessableToken> replaced_disk_cache_key_token_;
+    std::optional<base::UnguessableToken> replaced_disk_cache_key_token_;
     std::set<base::UnguessableToken> evicted_disk_cache_key_tokens_;
     uint64_t total_dictionary_size_;
     uint64_t total_dictionary_count_;
diff --git a/net/extras/sqlite/sqlite_persistent_shared_dictionary_store_unittest.cc b/net/extras/sqlite/sqlite_persistent_shared_dictionary_store_unittest.cc
index 869db928..5a7f1dd2 100644
--- a/net/extras/sqlite/sqlite_persistent_shared_dictionary_store_unittest.cc
+++ b/net/extras/sqlite/sqlite_persistent_shared_dictionary_store_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "net/extras/sqlite/sqlite_persistent_shared_dictionary_store.h"
 
+#include <optional>
 #include <tuple>
 
 #include "base/files/file_util.h"
@@ -26,7 +27,6 @@
 #include "sql/test/test_helpers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using ::testing::ElementsAre;
 using ::testing::ElementsAreArray;
@@ -139,8 +139,7 @@
                        SharedDictionaryInfo dictionary_info,
                        uint64_t max_size_per_site = 1000000,
                        uint64_t max_count_per_site = 1000) {
-  absl::optional<
-      SQLitePersistentSharedDictionaryStore::RegisterDictionaryResult>
+  std::optional<SQLitePersistentSharedDictionaryStore::RegisterDictionaryResult>
       result_out;
   base::RunLoop run_loop;
   store->RegisterDictionary(
@@ -180,7 +179,7 @@
                            /*last_used_time*/ now,
                            /*size=*/1000, SHA256HashValue({{0x00, 0x01}}),
                            /*disk_cache_key_token=*/token1,
-                           /*primary_key_in_database=*/absl::nullopt);
+                           /*primary_key_in_database=*/std::nullopt);
   auto result1 = RegisterDictionaryImpl(store, isolation_key, dict1);
   dict1.set_primary_key_in_database(result1.primary_key_in_database());
 
@@ -193,7 +192,7 @@
                            /*last_used_time*/ now + base::Seconds(1),
                            /*size=*/3000, SHA256HashValue({{0x00, 0x02}}),
                            /*disk_cache_key_token=*/token2,
-                           /*primary_key_in_database=*/absl::nullopt);
+                           /*primary_key_in_database=*/std::nullopt);
   auto result2 = RegisterDictionaryImpl(store, isolation_key, dict2);
   dict2.set_primary_key_in_database(result2.primary_key_in_database());
 
@@ -206,7 +205,7 @@
                            /*last_used_time*/ now + base::Seconds(2),
                            /*size=*/5000, SHA256HashValue({{0x00, 0x03}}),
                            /*disk_cache_key_token=*/token3,
-                           /*primary_key_in_database=*/absl::nullopt);
+                           /*primary_key_in_database=*/std::nullopt);
   auto result3 = RegisterDictionaryImpl(store, isolation_key, dict3);
   dict3.set_primary_key_in_database(result3.primary_key_in_database());
 
@@ -219,7 +218,7 @@
                            /*last_used_time*/ now + base::Seconds(3),
                            /*size=*/7000, SHA256HashValue({{0x00, 0x04}}),
                            /*disk_cache_key_token=*/token4,
-                           /*primary_key_in_database=*/absl::nullopt);
+                           /*primary_key_in_database=*/std::nullopt);
   auto result4 = RegisterDictionaryImpl(store, isolation_key, dict4);
   dict4.set_primary_key_in_database(result4.primary_key_in_database());
 
@@ -240,7 +239,7 @@
 
 SharedDictionaryIsolationKey CreateIsolationKey(
     const std::string& frame_origin_str,
-    const absl::optional<std::string>& top_frame_site_str = absl::nullopt) {
+    const std::optional<std::string>& top_frame_site_str = std::nullopt) {
   return SharedDictionaryIsolationKey(
       url::Origin::Create(GURL(frame_origin_str)),
       top_frame_site_str ? SchemefulSite(GURL(*top_frame_site_str))
@@ -264,7 +263,7 @@
             /*size=*/1000,
             SHA256HashValue({{0x00, 0x01}}),
             /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-            /*primary_key_in_database=*/absl::nullopt) {}
+            /*primary_key_in_database=*/std::nullopt) {}
 
   SQLitePersistentSharedDictionaryStoreTest(
       const SQLitePersistentSharedDictionaryStoreTest&) = delete;
@@ -773,7 +772,7 @@
           /*last_used_time*/ base::Time::Now(),
           /*size=*/1000, SHA256HashValue({{0x00, 0x01}}),
           /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-          /*primary_key_in_database=*/absl::nullopt),
+          /*primary_key_in_database=*/std::nullopt),
       isolation_key_,
       SharedDictionaryInfo(
           GURL("https://origin2.test/dict"),
@@ -783,7 +782,7 @@
           /*last_used_time*/ base::Time::Now(),
           /*size=*/2000, SHA256HashValue({{0x00, 0x02}}),
           /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-          /*primary_key_in_database=*/absl::nullopt),
+          /*primary_key_in_database=*/std::nullopt),
       /*expect_merged=*/false);
 }
 
@@ -799,7 +798,7 @@
           /*last_used_time*/ base::Time::Now(),
           /*size=*/1000, SHA256HashValue({{0x00, 0x01}}),
           /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-          /*primary_key_in_database=*/absl::nullopt),
+          /*primary_key_in_database=*/std::nullopt),
       isolation_key_,
       SharedDictionaryInfo(
           GURL("https://origin.test/dict"),
@@ -809,7 +808,7 @@
           /*last_used_time*/ base::Time::Now(),
           /*size=*/2000, SHA256HashValue({{0x00, 0x02}}),
           /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-          /*primary_key_in_database=*/absl::nullopt),
+          /*primary_key_in_database=*/std::nullopt),
       /*expect_merged=*/false);
 }
 
@@ -825,7 +824,7 @@
           /*last_used_time*/ base::Time::Now(),
           /*size=*/1000, SHA256HashValue({{0x00, 0x01}}),
           /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-          /*primary_key_in_database=*/absl::nullopt),
+          /*primary_key_in_database=*/std::nullopt),
       isolation_key_,
       SharedDictionaryInfo(
           GURL("https://origin.test/dict"),
@@ -835,7 +834,7 @@
           /*last_used_time*/ base::Time::Now(),
           /*size=*/2000, SHA256HashValue({{0x00, 0x02}}),
           /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-          /*primary_key_in_database=*/absl::nullopt),
+          /*primary_key_in_database=*/std::nullopt),
       /*expect_merged=*/true);
 }
 
@@ -851,7 +850,7 @@
           /*last_used_time*/ base::Time::Now(),
           /*size=*/1000, SHA256HashValue({{0x00, 0x01}}),
           /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-          /*primary_key_in_database=*/absl::nullopt),
+          /*primary_key_in_database=*/std::nullopt),
       isolation_key_,
       SharedDictionaryInfo(
           GURL("https://origin.test/dict"),
@@ -861,7 +860,7 @@
           /*last_used_time*/ base::Time::Now(),
           /*size=*/2000, SHA256HashValue({{0x00, 0x02}}),
           /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-          /*primary_key_in_database=*/absl::nullopt),
+          /*primary_key_in_database=*/std::nullopt),
       /*expect_merged=*/false);
 }
 
@@ -983,7 +982,7 @@
       /*last_used_time*/ base::Time::Now(), dictionary_info_.size() + 1,
       SHA256HashValue({{0x00, 0x02}}),
       /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
 
   // Register the dictionary which size is dictionary_info_.size() + 1.
   base::RunLoop run_loop;
@@ -1025,7 +1024,7 @@
           /*last_used_time*/ base::Time::Now(),
           /*size=*/max_size_per_site + 1, SHA256HashValue({{0x00, 0x01}}),
           /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-          /*primary_key_in_database=*/absl::nullopt),
+          /*primary_key_in_database=*/std::nullopt),
       max_size_per_site,
       /*max_count_per_site=*/1000,
       base::BindLambdaForTesting(
@@ -1058,7 +1057,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/max_size_per_site, SHA256HashValue({{0x00, 0x01}}),
       /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result1 = RegisterDictionaryImpl(store_.get(), isolation_key1, dict1,
                                         max_size_per_site, max_count_per_site);
   dict1.set_primary_key_in_database(result1.primary_key_in_database());
@@ -1078,7 +1077,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/max_size_per_site / 2, SHA256HashValue({{0x00, 0x02}}),
       /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result2 = RegisterDictionaryImpl(store_.get(), isolation_key2, dict2,
                                         max_size_per_site, max_count_per_site);
   dict2.set_primary_key_in_database(result2.primary_key_in_database());
@@ -1097,7 +1096,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/max_size_per_site / 2, SHA256HashValue({{0x00, 0x03}}),
       /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result3 = RegisterDictionaryImpl(store_.get(), isolation_key2, dict3,
                                         max_size_per_site, max_count_per_site);
   dict3.set_primary_key_in_database(result3.primary_key_in_database());
@@ -1121,7 +1120,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/1, SHA256HashValue({{0x00, 0x04}}),
       /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result4 = RegisterDictionaryImpl(store_.get(), isolation_key3, dict4,
                                         max_size_per_site, max_count_per_site);
   dict4.set_primary_key_in_database(result4.primary_key_in_database());
@@ -1154,7 +1153,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/100, SHA256HashValue({{0x00, 0x01}}),
       /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result1 = RegisterDictionaryImpl(store_.get(), isolation_key1, dict1,
                                         max_size_per_site, max_count_per_site);
   dict1.set_primary_key_in_database(result1.primary_key_in_database());
@@ -1174,7 +1173,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/200, SHA256HashValue({{0x00, 0x02}}),
       /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result2 = RegisterDictionaryImpl(store_.get(), isolation_key2, dict2,
                                         max_size_per_site, max_count_per_site);
   dict2.set_primary_key_in_database(result2.primary_key_in_database());
@@ -1193,7 +1192,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/400, SHA256HashValue({{0x00, 0x03}}),
       /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result3 = RegisterDictionaryImpl(store_.get(), isolation_key2, dict3,
                                         max_size_per_site, max_count_per_site);
   dict3.set_primary_key_in_database(result3.primary_key_in_database());
@@ -1217,7 +1216,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/800, SHA256HashValue({{0x00, 0x04}}),
       /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result4 = RegisterDictionaryImpl(store_.get(), isolation_key3, dict4,
                                         max_size_per_site, max_count_per_site);
   dict4.set_primary_key_in_database(result4.primary_key_in_database());
@@ -1251,7 +1250,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/100, SHA256HashValue({{0x00, 0x01}}),
       /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result1 = RegisterDictionaryImpl(store_.get(), isolation_key1, dict1,
                                         max_size_per_site, max_count_per_site);
   dict1.set_primary_key_in_database(result1.primary_key_in_database());
@@ -1271,7 +1270,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/200, SHA256HashValue({{0x00, 0x02}}),
       /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result2 = RegisterDictionaryImpl(store_.get(), isolation_key2, dict2,
                                         max_size_per_site, max_count_per_site);
   dict2.set_primary_key_in_database(result2.primary_key_in_database());
@@ -1290,7 +1289,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/400, SHA256HashValue({{0x00, 0x03}}),
       /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result3 = RegisterDictionaryImpl(store_.get(), isolation_key2, dict3,
                                         max_size_per_site, max_count_per_site);
   dict3.set_primary_key_in_database(result3.primary_key_in_database());
@@ -1314,7 +1313,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/800, SHA256HashValue({{0x00, 0x04}}),
       /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result4 = RegisterDictionaryImpl(store_.get(), isolation_key3, dict4,
                                         max_size_per_site, max_count_per_site);
   dict4.set_primary_key_in_database(result4.primary_key_in_database());
@@ -1347,7 +1346,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/100, SHA256HashValue({{0x00, 0x01}}),
       /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result1 = RegisterDictionaryImpl(store_.get(), isolation_key1, dict1,
                                         max_size_per_site, max_count_per_site);
   dict1.set_primary_key_in_database(result1.primary_key_in_database());
@@ -1367,7 +1366,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/200, SHA256HashValue({{0x00, 0x02}}),
       /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result2 = RegisterDictionaryImpl(store_.get(), isolation_key2, dict2,
                                         max_size_per_site, max_count_per_site);
   dict2.set_primary_key_in_database(result2.primary_key_in_database());
@@ -1386,7 +1385,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/400, SHA256HashValue({{0x00, 0x03}}),
       /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result3 = RegisterDictionaryImpl(store_.get(), isolation_key2, dict3,
                                         max_size_per_site, max_count_per_site);
   dict3.set_primary_key_in_database(result3.primary_key_in_database());
@@ -1410,7 +1409,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/800, SHA256HashValue({{0x00, 0x04}}),
       /*disk_cache_key_token=*/base::UnguessableToken::Create(),
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result4 = RegisterDictionaryImpl(store_.get(), isolation_key3, dict4,
                                         max_size_per_site, max_count_per_site);
   dict4.set_primary_key_in_database(result4.primary_key_in_database());
@@ -2077,7 +2076,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/1000, SHA256HashValue({{0x00, 0x01}}),
       /*disk_cache_key_token=*/token1,
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result1 = RegisterDictionary(isolation_key_, dict1);
   dict1.set_primary_key_in_database(result1.primary_key_in_database());
 
@@ -2090,7 +2089,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/3000, SHA256HashValue({{0x00, 0x02}}),
       /*disk_cache_key_token=*/token2,
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result2 = RegisterDictionary(isolation_key_, dict2);
   dict2.set_primary_key_in_database(result2.primary_key_in_database());
 
@@ -2103,7 +2102,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/5000, SHA256HashValue({{0x00, 0x03}}),
       /*disk_cache_key_token=*/token3,
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result3 = RegisterDictionary(isolation_key_, dict3);
   dict3.set_primary_key_in_database(result3.primary_key_in_database());
 
@@ -2116,7 +2115,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/7000, SHA256HashValue({{0x00, 0x04}}),
       /*disk_cache_key_token=*/token4,
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result4 = RegisterDictionary(isolation_key_, dict4);
   dict4.set_primary_key_in_database(result4.primary_key_in_database());
 
@@ -2157,7 +2156,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/1000, SHA256HashValue({{0x00, 0x01}}),
       /*disk_cache_key_token=*/token1,
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result1 = RegisterDictionary(isolation_key1, dict1);
   dict1.set_primary_key_in_database(result1.primary_key_in_database());
 
@@ -2172,7 +2171,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/3000, SHA256HashValue({{0x00, 0x02}}),
       /*disk_cache_key_token=*/token2,
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result2 = RegisterDictionary(isolation_key2, dict2);
   dict2.set_primary_key_in_database(result2.primary_key_in_database());
 
@@ -2187,7 +2186,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/5000, SHA256HashValue({{0x00, 0x03}}),
       /*disk_cache_key_token=*/token3,
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result3 = RegisterDictionary(isolation_key3, dict3);
   dict3.set_primary_key_in_database(result3.primary_key_in_database());
 
@@ -2202,7 +2201,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/7000, SHA256HashValue({{0x00, 0x04}}),
       /*disk_cache_key_token=*/token4,
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result4 = RegisterDictionary(isolation_key4, dict4);
   dict4.set_primary_key_in_database(result4.primary_key_in_database());
 
@@ -2273,7 +2272,7 @@
                            /*last_used_time*/ base::Time::Now(),
                            /*size=*/1000, SHA256HashValue({{0x00, 0x01}}),
                            /*disk_cache_key_token=*/token1,
-                           /*primary_key_in_database=*/absl::nullopt);
+                           /*primary_key_in_database=*/std::nullopt);
   auto result1 = RegisterDictionary(isolation_key1, dict1);
   dict1.set_primary_key_in_database(result1.primary_key_in_database());
 
@@ -2289,7 +2288,7 @@
                            /*last_used_time*/ base::Time::Now(),
                            /*size=*/2000, SHA256HashValue({{0x00, 0x02}}),
                            /*disk_cache_key_token=*/token2,
-                           /*primary_key_in_database=*/absl::nullopt);
+                           /*primary_key_in_database=*/std::nullopt);
   auto result2 = RegisterDictionary(isolation_key2, dict2);
   dict2.set_primary_key_in_database(result2.primary_key_in_database());
 
@@ -2305,7 +2304,7 @@
                            /*last_used_time*/ base::Time::Now(),
                            /*size=*/4000, SHA256HashValue({{0x00, 0x03}}),
                            /*disk_cache_key_token=*/token3,
-                           /*primary_key_in_database=*/absl::nullopt);
+                           /*primary_key_in_database=*/std::nullopt);
   auto result3 = RegisterDictionary(isolation_key3, dict3);
   dict3.set_primary_key_in_database(result3.primary_key_in_database());
 
@@ -2321,7 +2320,7 @@
                            /*last_used_time*/ base::Time::Now(),
                            /*size=*/8000, SHA256HashValue({{0x00, 0x04}}),
                            /*disk_cache_key_token=*/token4,
-                           /*primary_key_in_database=*/absl::nullopt);
+                           /*primary_key_in_database=*/std::nullopt);
   auto result4 = RegisterDictionary(isolation_key4, dict4);
   dict4.set_primary_key_in_database(result4.primary_key_in_database());
 
@@ -2356,7 +2355,7 @@
                            /*last_used_time*/ base::Time::Now(),
                            /*size=*/1000, SHA256HashValue({{0x00, 0x01}}),
                            /*disk_cache_key_token=*/token1_1,
-                           /*primary_key_in_database=*/absl::nullopt);
+                           /*primary_key_in_database=*/std::nullopt);
   auto result1_1 = RegisterDictionary(isolation_key1, dict1_1);
   dict1_1.set_primary_key_in_database(result1_1.primary_key_in_database());
 
@@ -2369,7 +2368,7 @@
                            /*last_used_time*/ base::Time::Now(),
                            /*size=*/2000, SHA256HashValue({{0x00, 0x02}}),
                            /*disk_cache_key_token=*/token1_2,
-                           /*primary_key_in_database=*/absl::nullopt);
+                           /*primary_key_in_database=*/std::nullopt);
   auto result1_2 = RegisterDictionary(isolation_key1, dict1_2);
   dict1_2.set_primary_key_in_database(result1_2.primary_key_in_database());
 
@@ -2383,7 +2382,7 @@
                            /*last_used_time*/ base::Time::Now(),
                            /*size=*/4000, SHA256HashValue({{0x00, 0x03}}),
                            /*disk_cache_key_token=*/token2,
-                           /*primary_key_in_database=*/absl::nullopt);
+                           /*primary_key_in_database=*/std::nullopt);
   auto result2 = RegisterDictionary(isolation_key2, dict2);
   dict2.set_primary_key_in_database(result2.primary_key_in_database());
 
@@ -2411,7 +2410,7 @@
                            /*last_used_time*/ now,
                            /*size=*/1000, SHA256HashValue({{0x00, 0x01}}),
                            /*disk_cache_key_token=*/token1,
-                           /*primary_key_in_database=*/absl::nullopt);
+                           /*primary_key_in_database=*/std::nullopt);
   auto result1 = RegisterDictionary(isolation_key_, dict1);
   dict1.set_primary_key_in_database(result1.primary_key_in_database());
 
@@ -2424,7 +2423,7 @@
                            /*last_used_time*/ now,
                            /*size=*/3000, SHA256HashValue({{0x00, 0x02}}),
                            /*disk_cache_key_token=*/token2,
-                           /*primary_key_in_database=*/absl::nullopt);
+                           /*primary_key_in_database=*/std::nullopt);
   auto result2 = RegisterDictionary(isolation_key_, dict2);
   dict2.set_primary_key_in_database(result2.primary_key_in_database());
 
@@ -2437,7 +2436,7 @@
                            /*last_used_time*/ now,
                            /*size=*/5000, SHA256HashValue({{0x00, 0x03}}),
                            /*disk_cache_key_token=*/token3,
-                           /*primary_key_in_database=*/absl::nullopt);
+                           /*primary_key_in_database=*/std::nullopt);
   auto result3 = RegisterDictionary(isolation_key_, dict3);
   dict3.set_primary_key_in_database(result3.primary_key_in_database());
 
@@ -2450,7 +2449,7 @@
                            /*last_used_time*/ now,
                            /*size=*/7000, SHA256HashValue({{0x00, 0x04}}),
                            /*disk_cache_key_token=*/token4,
-                           /*primary_key_in_database=*/absl::nullopt);
+                           /*primary_key_in_database=*/std::nullopt);
   auto result4 = RegisterDictionary(isolation_key_, dict4);
   dict4.set_primary_key_in_database(result4.primary_key_in_database());
 
@@ -2638,7 +2637,7 @@
                            /*last_used_time*/ now,
                            /*size=*/1000, SHA256HashValue({{0x00, 0x01}}),
                            /*disk_cache_key_token=*/token1,
-                           /*primary_key_in_database=*/absl::nullopt);
+                           /*primary_key_in_database=*/std::nullopt);
   auto result1 = RegisterDictionary(isolation_key_, dict1);
   dict1.set_primary_key_in_database(result1.primary_key_in_database());
 
@@ -2651,7 +2650,7 @@
                            /*last_used_time*/ now + base::Seconds(1),
                            /*size=*/3000, SHA256HashValue({{0x00, 0x02}}),
                            /*disk_cache_key_token=*/token2,
-                           /*primary_key_in_database=*/absl::nullopt);
+                           /*primary_key_in_database=*/std::nullopt);
   auto result2 = RegisterDictionary(isolation_key_, dict2);
   dict2.set_primary_key_in_database(result2.primary_key_in_database());
 
@@ -2682,7 +2681,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/1000, SHA256HashValue({{0x00, 0x01}}),
       /*disk_cache_key_token=*/token1,
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   RegisterDictionary(isolation_key_, dict1);
 
   EXPECT_THAT(GetAllDiskCacheKeyTokens(), ElementsAreArray({token1}));
@@ -2696,7 +2695,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/3000, SHA256HashValue({{0x00, 0x02}}),
       /*disk_cache_key_token=*/token2,
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   RegisterDictionary(isolation_key_, dict2);
 
   EXPECT_THAT(GetAllDiskCacheKeyTokens(),
@@ -2717,7 +2716,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/1000, SHA256HashValue({{0x00, 0x01}}),
       /*disk_cache_key_token=*/token1,
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result1 = RegisterDictionary(isolation_key_, dict1);
   dict1.set_primary_key_in_database(result1.primary_key_in_database());
 
@@ -2732,7 +2731,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/3000, SHA256HashValue({{0x00, 0x02}}),
       /*disk_cache_key_token=*/token2,
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   RegisterDictionary(isolation_key_, dict2);
   auto result2 = RegisterDictionary(isolation_key_, dict2);
   dict2.set_primary_key_in_database(result2.primary_key_in_database());
@@ -2746,7 +2745,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/5000, SHA256HashValue({{0x00, 0x03}}),
       /*disk_cache_key_token=*/token3,
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result3 = RegisterDictionary(isolation_key_, dict3);
   dict3.set_primary_key_in_database(result3.primary_key_in_database());
 
@@ -2759,7 +2758,7 @@
       /*last_used_time*/ base::Time::Now(),
       /*size=*/7000, SHA256HashValue({{0x00, 0x04}}),
       /*disk_cache_key_token=*/token4,
-      /*primary_key_in_database=*/absl::nullopt);
+      /*primary_key_in_database=*/std::nullopt);
   auto result4 = RegisterDictionary(isolation_key_, dict4);
   dict4.set_primary_key_in_database(result4.primary_key_in_database());
 
diff --git a/net/extras/sqlite/sqlite_persistent_store_backend_base.cc b/net/extras/sqlite/sqlite_persistent_store_backend_base.cc
index 1bd6bbb3..74213fb 100644
--- a/net/extras/sqlite/sqlite_persistent_store_backend_base.cc
+++ b/net/extras/sqlite/sqlite_persistent_store_backend_base.cc
@@ -213,7 +213,7 @@
 
   // |cur_version| is the version that the database ends up at, after all the
   // database upgrade statements.
-  absl::optional<int> cur_version = DoMigrateDatabaseSchema();
+  std::optional<int> cur_version = DoMigrateDatabaseSchema();
   if (!cur_version.has_value())
     return false;
 
diff --git a/net/extras/sqlite/sqlite_persistent_store_backend_base.h b/net/extras/sqlite/sqlite_persistent_store_backend_base.h
index d8eb543..0ace27e 100644
--- a/net/extras/sqlite/sqlite_persistent_store_backend_base.h
+++ b/net/extras/sqlite/sqlite_persistent_store_backend_base.h
@@ -6,6 +6,7 @@
 #define NET_EXTRAS_SQLITE_SQLITE_PERSISTENT_STORE_BACKEND_BASE_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "base/files/file_path.h"
@@ -14,7 +15,6 @@
 #include "base/memory/ref_counted.h"
 #include "base/thread_annotations.h"
 #include "sql/meta_table.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class Location;
@@ -96,9 +96,9 @@
   // Embedder-specific database upgrade statements. Returns the version number
   // that the database ends up at, or returns nullopt on error. This is called
   // during MigrateDatabaseSchema() which is called during InitializeDatabase(),
-  // and returning |absl::nullopt| will cause the initialization process to fail
+  // and returning |std::nullopt| will cause the initialization process to fail
   // and stop.
-  virtual absl::optional<int> DoMigrateDatabaseSchema() = 0;
+  virtual std::optional<int> DoMigrateDatabaseSchema() = 0;
 
   // Initializes the desired table(s) of the database, e.g. by creating them or
   // checking that they already exist. Returns whether the tables exist.
diff --git a/net/first_party_sets/first_party_set_entry.cc b/net/first_party_sets/first_party_set_entry.cc
index 8feda59a..142c4e7 100644
--- a/net/first_party_sets/first_party_set_entry.cc
+++ b/net/first_party_sets/first_party_set_entry.cc
@@ -39,7 +39,7 @@
 FirstPartySetEntry::FirstPartySetEntry(
     SchemefulSite primary,
     SiteType site_type,
-    absl::optional<FirstPartySetEntry::SiteIndex> site_index)
+    std::optional<FirstPartySetEntry::SiteIndex> site_index)
     : primary_(primary), site_type_(site_type), site_index_(site_index) {
   switch (site_type_) {
     case SiteType::kPrimary:
@@ -57,7 +57,7 @@
     : FirstPartySetEntry(
           primary,
           site_type,
-          absl::make_optional(FirstPartySetEntry::SiteIndex(site_index))) {}
+          std::make_optional(FirstPartySetEntry::SiteIndex(site_index))) {}
 
 FirstPartySetEntry::FirstPartySetEntry(const FirstPartySetEntry&) = default;
 FirstPartySetEntry& FirstPartySetEntry::operator=(const FirstPartySetEntry&) =
@@ -75,7 +75,7 @@
     default;
 
 // static
-absl::optional<net::SiteType> FirstPartySetEntry::DeserializeSiteType(
+std::optional<net::SiteType> FirstPartySetEntry::DeserializeSiteType(
     int value) {
   switch (value) {
     case static_cast<int>(net::SiteType::kPrimary):
@@ -87,7 +87,7 @@
     default:
       NOTREACHED() << "Unknown SiteType: " << value;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 std::string FirstPartySetEntry::GetDebugString() const {
diff --git a/net/first_party_sets/first_party_set_entry.h b/net/first_party_sets/first_party_set_entry.h
index a01955ea..c626a40 100644
--- a/net/first_party_sets/first_party_set_entry.h
+++ b/net/first_party_sets/first_party_set_entry.h
@@ -48,7 +48,7 @@
   // entry.
   FirstPartySetEntry(SchemefulSite primary,
                      SiteType site_type,
-                     absl::optional<SiteIndex> site_index);
+                     std::optional<SiteIndex> site_index);
   FirstPartySetEntry(SchemefulSite primary,
                      SiteType site_type,
                      uint32_t site_index);
@@ -63,7 +63,7 @@
   bool operator==(const FirstPartySetEntry& other) const;
   bool operator!=(const FirstPartySetEntry& other) const;
 
-  static absl::optional<net::SiteType> DeserializeSiteType(int value);
+  static std::optional<net::SiteType> DeserializeSiteType(int value);
 
   std::string GetDebugString() const;
 
@@ -71,7 +71,7 @@
 
   SiteType site_type() const { return site_type_; }
 
-  const absl::optional<SiteIndex>& site_index() const { return site_index_; }
+  const std::optional<SiteIndex>& site_index() const { return site_index_; }
 
  private:
   // The primary site associated with this site's set.
@@ -81,7 +81,7 @@
   // The index of this site in the set declaration, if a meaningful index
   // exists. Primary sites do not have indices, nor do sites that were defined
   // or affected by an enterprise policy set.
-  absl::optional<SiteIndex> site_index_;
+  std::optional<SiteIndex> site_index_;
 };
 
 NET_EXPORT std::ostream& operator<<(
diff --git a/net/first_party_sets/first_party_set_entry_override.h b/net/first_party_sets/first_party_set_entry_override.h
index 80c3ada..1c9d9c9 100644
--- a/net/first_party_sets/first_party_set_entry_override.h
+++ b/net/first_party_sets/first_party_set_entry_override.h
@@ -5,9 +5,10 @@
 #ifndef NET_FIRST_PARTY_SETS_FIRST_PARTY_SET_ENTRY_OVERRIDE_H_
 #define NET_FIRST_PARTY_SETS_FIRST_PARTY_SET_ENTRY_OVERRIDE_H_
 
+#include <optional>
+
 #include "net/base/net_export.h"
 #include "net/first_party_sets/first_party_set_entry.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 template <typename DataViewType, typename T>
@@ -55,7 +56,7 @@
       network::mojom::FirstPartySetEntryOverrideDataView,
       FirstPartySetEntryOverride>;
 
-  absl::optional<FirstPartySetEntry> entry_;
+  std::optional<FirstPartySetEntry> entry_;
 };
 
 NET_EXPORT std::ostream& operator<<(std::ostream& os,
diff --git a/net/first_party_sets/first_party_set_entry_override_unittest.cc b/net/first_party_sets/first_party_set_entry_override_unittest.cc
index e1384df4..0b5b1cd 100644
--- a/net/first_party_sets/first_party_set_entry_override_unittest.cc
+++ b/net/first_party_sets/first_party_set_entry_override_unittest.cc
@@ -19,13 +19,13 @@
   EXPECT_FALSE(
       FirstPartySetEntryOverride(
           FirstPartySetEntry(SchemefulSite(GURL("https://example.test")),
-                             SiteType::kPrimary, absl::nullopt))
+                             SiteType::kPrimary, std::nullopt))
           .IsDeletion());
 }
 
 TEST(FirstPartySetEntryOverrideTest, GetEntry) {
   FirstPartySetEntry entry(SchemefulSite(GURL("https://example.test")),
-                           SiteType::kPrimary, absl::nullopt);
+                           SiteType::kPrimary, std::nullopt);
   EXPECT_EQ(FirstPartySetEntryOverride(entry).GetEntry(), entry);
 }
 
diff --git a/net/first_party_sets/first_party_set_metadata.h b/net/first_party_sets/first_party_set_metadata.h
index b23e5257..5c2286f 100644
--- a/net/first_party_sets/first_party_set_metadata.h
+++ b/net/first_party_sets/first_party_set_metadata.h
@@ -5,9 +5,10 @@
 #ifndef NET_FIRST_PARTY_SETS_FIRST_PARTY_SET_METADATA_H_
 #define NET_FIRST_PARTY_SETS_FIRST_PARTY_SET_METADATA_H_
 
+#include <optional>
+
 #include "net/base/net_export.h"
 #include "net/first_party_sets/first_party_set_entry.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -31,10 +32,10 @@
   bool operator==(const FirstPartySetMetadata& other) const;
   bool operator!=(const FirstPartySetMetadata& other) const;
 
-  const absl::optional<FirstPartySetEntry>& frame_entry() const {
+  const std::optional<FirstPartySetEntry>& frame_entry() const {
     return frame_entry_;
   }
-  const absl::optional<FirstPartySetEntry>& top_frame_entry() const {
+  const std::optional<FirstPartySetEntry>& top_frame_entry() const {
     return top_frame_entry_;
   }
 
@@ -43,8 +44,8 @@
   bool AreSitesInSameFirstPartySet() const;
 
  private:
-  absl::optional<FirstPartySetEntry> frame_entry_ = absl::nullopt;
-  absl::optional<FirstPartySetEntry> top_frame_entry_ = absl::nullopt;
+  std::optional<FirstPartySetEntry> frame_entry_ = std::nullopt;
+  std::optional<FirstPartySetEntry> top_frame_entry_ = std::nullopt;
 };
 
 NET_EXPORT std::ostream& operator<<(std::ostream& os,
diff --git a/net/first_party_sets/first_party_sets_cache_filter.h b/net/first_party_sets/first_party_sets_cache_filter.h
index 93a61e8..f9c6737 100644
--- a/net/first_party_sets/first_party_sets_cache_filter.h
+++ b/net/first_party_sets/first_party_sets_cache_filter.h
@@ -5,10 +5,11 @@
 #ifndef NET_FIRST_PARTY_SETS_FIRST_PARTY_SETS_CACHE_FILTER_H_
 #define NET_FIRST_PARTY_SETS_FIRST_PARTY_SETS_CACHE_FILTER_H_
 
+#include <optional>
+
 #include "base/containers/flat_map.h"
 #include "net/base/net_export.h"
 #include "net/base/schemeful_site.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 template <typename DataViewType, typename T>
@@ -33,10 +34,10 @@
 
     // Stores the ID used to check whether cache should be bypassed. Only not
     // null if the request site matches the filter; nullopt if don't match.
-    absl::optional<int64_t> clear_at_run_id;
+    std::optional<int64_t> clear_at_run_id;
     // The ID used to mark the new cache. It should be either a positive number
     // or nullopt.
-    absl::optional<int64_t> browser_run_id;
+    std::optional<int64_t> browser_run_id;
   };
 
   // The default cache filter is no-op.
diff --git a/net/first_party_sets/first_party_sets_context_config.cc b/net/first_party_sets/first_party_sets_context_config.cc
index 62038e8b..f79c7e39 100644
--- a/net/first_party_sets/first_party_sets_context_config.cc
+++ b/net/first_party_sets/first_party_sets_context_config.cc
@@ -27,12 +27,12 @@
 bool FirstPartySetsContextConfig::operator==(
     const FirstPartySetsContextConfig& other) const = default;
 
-absl::optional<FirstPartySetEntryOverride>
+std::optional<FirstPartySetEntryOverride>
 FirstPartySetsContextConfig::FindOverride(const SchemefulSite& site) const {
   if (const auto it = customizations_.find(site); it != customizations_.end()) {
     return it->second;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool FirstPartySetsContextConfig::Contains(const SchemefulSite& site) const {
diff --git a/net/first_party_sets/first_party_sets_context_config.h b/net/first_party_sets/first_party_sets_context_config.h
index 57e9d5a..c49eb165 100644
--- a/net/first_party_sets/first_party_sets_context_config.h
+++ b/net/first_party_sets/first_party_sets_context_config.h
@@ -5,11 +5,12 @@
 #ifndef NET_FIRST_PARTY_SETS_FIRST_PARTY_SETS_CONTEXT_CONFIG_H_
 #define NET_FIRST_PARTY_SETS_FIRST_PARTY_SETS_CONTEXT_CONFIG_H_
 
+#include <optional>
+
 #include "base/containers/flat_map.h"
 #include "base/functional/function_ref.h"
 #include "net/base/schemeful_site.h"
 #include "net/first_party_sets/first_party_set_entry_override.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 template <typename DataViewType, typename T>
@@ -44,7 +45,7 @@
   // - nullopt if no override was found.
   // - optional(override) if an override was found. The override may be a
   //     deletion or a modification/addition.
-  absl::optional<FirstPartySetEntryOverride> FindOverride(
+  std::optional<FirstPartySetEntryOverride> FindOverride(
       const SchemefulSite& site) const;
 
   // Returns whether an override can be found for the given site in this
diff --git a/net/first_party_sets/first_party_sets_context_config_unittest.cc b/net/first_party_sets/first_party_sets_context_config_unittest.cc
index 8c93393..17f1b3b 100644
--- a/net/first_party_sets/first_party_sets_context_config_unittest.cc
+++ b/net/first_party_sets/first_party_sets_context_config_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "net/first_party_sets/first_party_sets_context_config.h"
 
+#include <optional>
+
 #include "net/base/schemeful_site.h"
 #include "net/first_party_sets/first_party_set_entry.h"
 #include "net/first_party_sets/first_party_set_entry_override.h"
@@ -11,7 +13,6 @@
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 using ::testing::Optional;
@@ -26,18 +27,18 @@
 TEST(FirstPartySetsContextConfigTest, FindOverride_empty) {
   EXPECT_EQ(FirstPartySetsContextConfig().FindOverride(
                 SchemefulSite(GURL("https://example.test"))),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(FirstPartySetsContextConfigTest, FindOverride_irrelevant) {
   SchemefulSite example(GURL("https://example.test"));
-  FirstPartySetEntry entry(example, SiteType::kPrimary, absl::nullopt);
+  FirstPartySetEntry entry(example, SiteType::kPrimary, std::nullopt);
   SchemefulSite foo(GURL("https://foo.test"));
 
   EXPECT_EQ(FirstPartySetsContextConfig(
                 {{example, FirstPartySetEntryOverride(entry)}})
                 .FindOverride(foo),
-            absl::nullopt);
+            std::nullopt);
 }
 
 TEST(FirstPartySetsContextConfigTest, FindOverride_deletion) {
@@ -51,7 +52,7 @@
 
 TEST(FirstPartySetsContextConfigTest, FindOverride_modification) {
   SchemefulSite example(GURL("https://example.test"));
-  FirstPartySetEntry entry(example, SiteType::kPrimary, absl::nullopt);
+  FirstPartySetEntry entry(example, SiteType::kPrimary, std::nullopt);
 
   EXPECT_THAT(FirstPartySetsContextConfig(
                   {{example, FirstPartySetEntryOverride(entry)}})
diff --git a/net/first_party_sets/global_first_party_sets.cc b/net/first_party_sets/global_first_party_sets.cc
index c916b0f4..573ac50 100644
--- a/net/first_party_sets/global_first_party_sets.cc
+++ b/net/first_party_sets/global_first_party_sets.cc
@@ -4,6 +4,7 @@
 
 #include "net/first_party_sets/global_first_party_sets.h"
 
+#include <optional>
 #include <set>
 #include <tuple>
 
@@ -20,7 +21,6 @@
 #include "net/first_party_sets/first_party_set_metadata.h"
 #include "net/first_party_sets/first_party_sets_context_config.h"
 #include "net/first_party_sets/local_set_declaration.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -118,21 +118,21 @@
                               manual_config_.Clone(), manual_aliases_);
 }
 
-absl::optional<FirstPartySetEntry> GlobalFirstPartySets::FindEntry(
+std::optional<FirstPartySetEntry> GlobalFirstPartySets::FindEntry(
     const SchemefulSite& site,
     const FirstPartySetsContextConfig& config) const {
   return FindEntry(site, &config);
 }
 
-absl::optional<FirstPartySetEntry> GlobalFirstPartySets::FindEntry(
+std::optional<FirstPartySetEntry> GlobalFirstPartySets::FindEntry(
     const SchemefulSite& site,
     const FirstPartySetsContextConfig* config) const {
   // Check if `site` can be found in the customizations first.
   if (config) {
     if (const auto override = config->FindOverride(site);
         override.has_value()) {
-      return override->IsDeletion() ? absl::nullopt
-                                    : absl::make_optional(override->GetEntry());
+      return override->IsDeletion() ? std::nullopt
+                                    : std::make_optional(override->GetEntry());
     }
   }
 
@@ -140,8 +140,8 @@
   if (const auto manual_override = manual_config_.FindOverride(site);
       manual_override.has_value()) {
     return manual_override->IsDeletion()
-               ? absl::nullopt
-               : absl::make_optional(manual_override->GetEntry());
+               ? std::nullopt
+               : std::make_optional(manual_override->GetEntry());
   }
 
   // Finally, look up in `entries_`, applying an alias if applicable.
@@ -153,7 +153,7 @@
     return entry_it->second;
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 base::flat_map<SchemefulSite, FirstPartySetEntry>
@@ -162,7 +162,7 @@
     const FirstPartySetsContextConfig& config) const {
   std::vector<std::pair<SchemefulSite, FirstPartySetEntry>> sites_to_entries;
   for (const SchemefulSite& site : sites) {
-    const absl::optional<FirstPartySetEntry> entry = FindEntry(site, config);
+    const std::optional<FirstPartySetEntry> entry = FindEntry(site, config);
     if (entry.has_value()) {
       sites_to_entries.emplace_back(site, entry.value());
     }
@@ -174,9 +174,9 @@
     const SchemefulSite& site,
     const SchemefulSite* top_frame_site,
     const FirstPartySetsContextConfig& fps_context_config) const {
-  absl::optional<FirstPartySetEntry> top_frame_entry =
+  std::optional<FirstPartySetEntry> top_frame_entry =
       top_frame_site ? FindEntry(*top_frame_site, fps_context_config)
-                     : absl::nullopt;
+                     : std::nullopt;
 
   return FirstPartySetMetadata(
       base::OptionalToPtr(FindEntry(site, fps_context_config)),
@@ -305,7 +305,7 @@
                                            member == entry->second.primary()
                                                ? SiteType::kPrimary
                                                : SiteType::kAssociated,
-                                           absl::nullopt));
+                                           std::nullopt));
           }
           if (member == set_entry.primary())
             return true;
@@ -390,7 +390,7 @@
             normalized
                 .emplace(child_site_and_entry.first,
                          FirstPartySetEntry(rep_primary, SiteType::kAssociated,
-                                            absl::nullopt))
+                                            std::nullopt))
                 .second;
         CHECK(inserted);
       }
diff --git a/net/first_party_sets/global_first_party_sets.h b/net/first_party_sets/global_first_party_sets.h
index d87aaec1..0ee3c16 100644
--- a/net/first_party_sets/global_first_party_sets.h
+++ b/net/first_party_sets/global_first_party_sets.h
@@ -5,6 +5,8 @@
 #ifndef NET_FIRST_PARTY_SETS_GLOBAL_FIRST_PARTY_SETS_H_
 #define NET_FIRST_PARTY_SETS_GLOBAL_FIRST_PARTY_SETS_H_
 
+#include <optional>
+
 #include "base/containers/flat_map.h"
 #include "base/containers/flat_set.h"
 #include "base/functional/function_ref.h"
@@ -16,7 +18,6 @@
 #include "net/first_party_sets/first_party_sets_context_config.h"
 #include "net/first_party_sets/local_set_declaration.h"
 #include "net/first_party_sets/sets_mutation.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 template <typename DataViewType, typename T>
@@ -62,7 +63,7 @@
   // Respects any customization/overlay specified by `config`. This is
   // semi-agnostic to scheme: it just cares whether the scheme is secure or
   // insecure.
-  absl::optional<FirstPartySetEntry> FindEntry(
+  std::optional<FirstPartySetEntry> FindEntry(
       const SchemefulSite& site,
       const FirstPartySetsContextConfig& config) const;
 
@@ -146,7 +147,7 @@
 
   // Same as the public version of FindEntry, but is allowed to omit the
   // `config` argument (i.e. pass nullptr instead of a reference).
-  absl::optional<FirstPartySetEntry> FindEntry(
+  std::optional<FirstPartySetEntry> FindEntry(
       const SchemefulSite& site,
       const FirstPartySetsContextConfig* config) const;
 
diff --git a/net/first_party_sets/global_first_party_sets_unittest.cc b/net/first_party_sets/global_first_party_sets_unittest.cc
index 1a3c5ea..ea31279 100644
--- a/net/first_party_sets/global_first_party_sets_unittest.cc
+++ b/net/first_party_sets/global_first_party_sets_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "net/first_party_sets/global_first_party_sets.h"
 
+#include <optional>
+
 #include "base/containers/flat_map.h"
 #include "base/version.h"
 #include "net/base/schemeful_site.h"
@@ -16,7 +18,6 @@
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 using ::testing::IsEmpty;
@@ -72,7 +73,7 @@
       base::Version(), /*entries=*/
       {
           {kPrimary,
-           FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
           {kAssociated1,
            FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
       },
@@ -88,12 +89,12 @@
   const SchemefulSite example(GURL("https://example.test"));
   const SchemefulSite example_cctld(GURL("https://example.cctld"));
   const SchemefulSite member1(GURL("https://member1.test"));
-  const FirstPartySetEntry entry(example, SiteType::kPrimary, absl::nullopt);
+  const FirstPartySetEntry entry(example, SiteType::kPrimary, std::nullopt);
   const FirstPartySetEntry member1_entry(example, SiteType::kAssociated, 1);
 
   const SchemefulSite foo(GURL("https://foo.test"));
   const SchemefulSite member2(GURL("https://member2.test"));
-  const FirstPartySetEntry foo_entry(foo, SiteType::kPrimary, absl::nullopt);
+  const FirstPartySetEntry foo_entry(foo, SiteType::kPrimary, std::nullopt);
   const FirstPartySetEntry member2_entry(foo, SiteType::kAssociated, 1);
 
   GlobalFirstPartySets sets(version,
@@ -112,13 +113,13 @@
 
   EXPECT_THAT(
       GlobalFirstPartySets().FindEntry(example, FirstPartySetsContextConfig()),
-      absl::nullopt);
+      std::nullopt);
 }
 
 TEST_F(GlobalFirstPartySetsTest, FindEntry_Exists) {
   SchemefulSite example(GURL("https://example.test"));
   SchemefulSite decoy_site(GURL("https://decoy.test"));
-  FirstPartySetEntry entry(example, SiteType::kPrimary, absl::nullopt);
+  FirstPartySetEntry entry(example, SiteType::kPrimary, std::nullopt);
   FirstPartySetEntry decoy_entry(example, SiteType::kAssociated, 1);
 
   EXPECT_THAT(GlobalFirstPartySets(kVersion,
@@ -135,7 +136,7 @@
   SchemefulSite https_example(GURL("https://example.test"));
   SchemefulSite associated(GURL("https://associated.test"));
   SchemefulSite wss_example(GURL("wss://example.test"));
-  FirstPartySetEntry entry(https_example, SiteType::kPrimary, absl::nullopt);
+  FirstPartySetEntry entry(https_example, SiteType::kPrimary, std::nullopt);
   FirstPartySetEntry assoc_entry(https_example, SiteType::kAssociated, 0);
 
   EXPECT_THAT(GlobalFirstPartySets(kVersion,
@@ -145,13 +146,13 @@
                                    },
                                    {})
                   .FindEntry(wss_example, FirstPartySetsContextConfig()),
-              absl::nullopt);
+              std::nullopt);
 }
 
 TEST_F(GlobalFirstPartySetsTest, FindEntry_ExistsViaOverride) {
   SchemefulSite example(GURL("https://example.test"));
   SchemefulSite associated(GURL("https://associated.test"));
-  FirstPartySetEntry public_entry(example, SiteType::kPrimary, absl::nullopt);
+  FirstPartySetEntry public_entry(example, SiteType::kPrimary, std::nullopt);
   FirstPartySetEntry assoc_entry(example, SiteType::kAssociated, 0);
   FirstPartySetEntry override_entry(example, SiteType::kAssociated, 1);
 
@@ -171,7 +172,7 @@
 TEST_F(GlobalFirstPartySetsTest, FindEntry_RemovedViaOverride) {
   SchemefulSite example(GURL("https://example.test"));
   SchemefulSite associated(GURL("https://associated.test"));
-  FirstPartySetEntry public_entry(example, SiteType::kPrimary, absl::nullopt);
+  FirstPartySetEntry public_entry(example, SiteType::kPrimary, std::nullopt);
   FirstPartySetEntry assoc_entry(example, SiteType::kAssociated, 0);
 
   FirstPartySetsContextConfig config(
@@ -184,13 +185,13 @@
                                    },
                                    {})
                   .FindEntry(example, config),
-              absl::nullopt);
+              std::nullopt);
 }
 
 TEST_F(GlobalFirstPartySetsTest, FindEntry_ExistsViaAlias) {
   SchemefulSite example(GURL("https://example.test"));
   SchemefulSite example_cctld(GURL("https://example.cctld"));
-  FirstPartySetEntry entry(example, SiteType::kPrimary, absl::nullopt);
+  FirstPartySetEntry entry(example, SiteType::kPrimary, std::nullopt);
 
   EXPECT_THAT(GlobalFirstPartySets(kVersion,
                                    {
@@ -204,7 +205,7 @@
 TEST_F(GlobalFirstPartySetsTest, FindEntry_ExistsViaOverrideWithDecoyAlias) {
   SchemefulSite example(GURL("https://example.test"));
   SchemefulSite example_cctld(GURL("https://example.cctld"));
-  FirstPartySetEntry public_entry(example, SiteType::kPrimary, absl::nullopt);
+  FirstPartySetEntry public_entry(example, SiteType::kPrimary, std::nullopt);
   FirstPartySetEntry override_entry(example, SiteType::kAssociated, 1);
 
   FirstPartySetsContextConfig config(
@@ -222,7 +223,7 @@
 TEST_F(GlobalFirstPartySetsTest, FindEntry_RemovedViaOverrideWithDecoyAlias) {
   SchemefulSite example(GURL("https://example.test"));
   SchemefulSite example_cctld(GURL("https://example.cctld"));
-  FirstPartySetEntry public_entry(example, SiteType::kPrimary, absl::nullopt);
+  FirstPartySetEntry public_entry(example, SiteType::kPrimary, std::nullopt);
 
   FirstPartySetsContextConfig config(
       {{example_cctld, net::FirstPartySetEntryOverride()}});
@@ -233,13 +234,13 @@
                                    },
                                    {{example_cctld, example}})
                   .FindEntry(example_cctld, config),
-              absl::nullopt);
+              std::nullopt);
 }
 
 TEST_F(GlobalFirstPartySetsTest, FindEntry_AliasesIgnoredForConfig) {
   SchemefulSite example(GURL("https://example.test"));
   SchemefulSite example_cctld(GURL("https://example.cctld"));
-  FirstPartySetEntry public_entry(example, SiteType::kPrimary, absl::nullopt);
+  FirstPartySetEntry public_entry(example, SiteType::kPrimary, std::nullopt);
   FirstPartySetEntry override_entry(example, SiteType::kAssociated, 1);
 
   FirstPartySetsContextConfig config(
@@ -266,7 +267,7 @@
           kVersion,
           {
               {kPrimary,
-               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
               {kAssociated4,
                FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
           },
@@ -280,7 +281,7 @@
       /*set_entries=*/
       {
           {kPrimary,
-           FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
           {kAssociated4,
            FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
       },
@@ -293,7 +294,7 @@
       base::Version(), /*entries=*/
       {
           {kPrimary,
-           FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
           {kAssociated1,
            FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
       },
@@ -303,7 +304,7 @@
       /*set_entries=*/
       {
           {kPrimary,
-           FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
           {kAssociated4,
            FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
       },
@@ -317,7 +318,7 @@
                        FirstPartySetsContextConfig()),
       UnorderedElementsAre(
           Pair(kPrimary,
-               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)),
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)),
           Pair(kAssociated4,
                FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0))));
 }
@@ -329,7 +330,7 @@
       /*set_entries=*/
       {
           {kPrimary,
-           FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
           {kAssociated4,
            FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
           {kAssociated5,
@@ -344,16 +345,16 @@
       {
           {
               {kPrimary,
-               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
               {kAssociated1, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)},
+                                                std::nullopt)},
               {kAssociated1Cctld,
                FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                  absl::nullopt)},
+                                  std::nullopt)},
               {kAssociated4, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)},
+                                                std::nullopt)},
               {kService,
-               FirstPartySetEntry(kPrimary, SiteType::kService, absl::nullopt)},
+               FirstPartySetEntry(kPrimary, SiteType::kService, std::nullopt)},
           },
       },
       /*addition_sets=*/{}));
@@ -365,15 +366,15 @@
       UnorderedElementsAre(
           Pair(kAssociated1Cctld,
                FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(kAssociated1, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)),
+                                                std::nullopt)),
           Pair(kAssociated4, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)),
+                                                std::nullopt)),
           Pair(kPrimary,
-               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)),
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)),
           Pair(kService, FirstPartySetEntry(kPrimary, SiteType::kService,
-                                            absl::nullopt))));
+                                            std::nullopt))));
 }
 
 class PopulatedGlobalFirstPartySetsTest : public GlobalFirstPartySetsTest {
@@ -384,17 +385,17 @@
             {
                 {kPrimary, FirstPartySetEntry(kPrimary,
                                               SiteType::kPrimary,
-                                              absl::nullopt)},
+                                              std::nullopt)},
                 {kAssociated1,
                  FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
                 {kAssociated2,
                  FirstPartySetEntry(kPrimary, SiteType::kAssociated, 1)},
                 {kService, FirstPartySetEntry(kPrimary,
                                               SiteType::kService,
-                                              absl::nullopt)},
+                                              std::nullopt)},
                 {kPrimary2, FirstPartySetEntry(kPrimary2,
                                                SiteType::kPrimary,
-                                               absl::nullopt)},
+                                               std::nullopt)},
                 {kAssociated3,
                  FirstPartySetEntry(kPrimary2, SiteType::kAssociated, 0)},
             },
@@ -416,7 +417,7 @@
       /*set_entries=*/
       {
           {kPrimary,
-           FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
           {kAssociated4,
            FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
       },
@@ -435,7 +436,7 @@
           FirstPartySetsContextConfig()),
       UnorderedElementsAre(
           Pair(kPrimary,
-               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)),
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)),
           Pair(kAssociated4,
                FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0))));
 }
@@ -448,7 +449,7 @@
       /*set_entries=*/
       {
           {kPrimary3,
-           FirstPartySetEntry(kPrimary3, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary3, SiteType::kPrimary, std::nullopt)},
           {kPrimary, FirstPartySetEntry(kPrimary3, SiteType::kAssociated, 0)},
       },
       /*aliases=*/{}));
@@ -466,8 +467,8 @@
           },
           FirstPartySetsContextConfig()),
       UnorderedElementsAre(
-          Pair(kPrimary3, FirstPartySetEntry(kPrimary3, SiteType::kPrimary,
-                                             absl::nullopt)),
+          Pair(kPrimary3,
+               FirstPartySetEntry(kPrimary3, SiteType::kPrimary, std::nullopt)),
           Pair(kPrimary,
                FirstPartySetEntry(kPrimary3, SiteType::kAssociated, 0))));
 }
@@ -481,7 +482,7 @@
       /*set_entries=*/
       {
           {kAssociated1,
-           FirstPartySetEntry(kAssociated1, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kAssociated1, SiteType::kPrimary, std::nullopt)},
           {kAssociated4,
            FirstPartySetEntry(kAssociated1, SiteType::kAssociated, 0)},
       },
@@ -501,14 +502,14 @@
           FirstPartySetsContextConfig()),
       UnorderedElementsAre(
           Pair(kPrimary,
-               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)),
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)),
           Pair(kAssociated2,
                FirstPartySetEntry(kPrimary, SiteType::kAssociated, 1)),
           Pair(kService,
-               FirstPartySetEntry(kPrimary, SiteType::kService, absl::nullopt)),
+               FirstPartySetEntry(kPrimary, SiteType::kService, std::nullopt)),
           Pair(kAssociated1,
                FirstPartySetEntry(kAssociated1, SiteType::kPrimary,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(kAssociated4,
                FirstPartySetEntry(kAssociated1, SiteType::kAssociated, 0))));
 }
@@ -521,7 +522,7 @@
       /*set_entries=*/
       {
           {kPrimary3,
-           FirstPartySetEntry(kPrimary3, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary3, SiteType::kPrimary, std::nullopt)},
           {kAssociated1,
            FirstPartySetEntry(kPrimary3, SiteType::kAssociated, 0)},
       },
@@ -541,13 +542,13 @@
           FirstPartySetsContextConfig()),
       UnorderedElementsAre(
           Pair(kPrimary,
-               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)),
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)),
           Pair(kAssociated2,
                FirstPartySetEntry(kPrimary, SiteType::kAssociated, 1)),
           Pair(kService,
-               FirstPartySetEntry(kPrimary, SiteType::kService, absl::nullopt)),
-          Pair(kPrimary3, FirstPartySetEntry(kPrimary3, SiteType::kPrimary,
-                                             absl::nullopt)),
+               FirstPartySetEntry(kPrimary, SiteType::kService, std::nullopt)),
+          Pair(kPrimary3,
+               FirstPartySetEntry(kPrimary3, SiteType::kPrimary, std::nullopt)),
           Pair(kAssociated1,
                FirstPartySetEntry(kPrimary3, SiteType::kAssociated, 0))));
 }
@@ -560,7 +561,7 @@
       /*set_entries=*/
       {
           {kPrimary3,
-           FirstPartySetEntry(kPrimary3, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary3, SiteType::kPrimary, std::nullopt)},
           {kAssociated3,
            FirstPartySetEntry(kPrimary3, SiteType::kAssociated, 0)},
       },
@@ -580,7 +581,7 @@
       /*set_entries=*/
       {
           {kPrimary3,
-           FirstPartySetEntry(kPrimary3, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary3, SiteType::kPrimary, std::nullopt)},
           {kAssociated1,
            FirstPartySetEntry(kPrimary3, SiteType::kAssociated, 0)},
       },
@@ -637,11 +638,11 @@
           Pair(kAssociated3,
                FirstPartySetEntry(kPrimary2, SiteType::kAssociated, 0)),
           Pair(kPrimary,
-               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)),
-          Pair(kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
-                                             absl::nullopt)),
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)),
+          Pair(kPrimary2,
+               FirstPartySetEntry(kPrimary2, SiteType::kPrimary, std::nullopt)),
           Pair(kService, FirstPartySetEntry(kPrimary, SiteType::kService,
-                                            absl::nullopt))));
+                                            std::nullopt))));
 }
 
 TEST_F(PopulatedGlobalFirstPartySetsTest,
@@ -652,7 +653,7 @@
       /*set_entries=*/
       {
           {kPrimary,
-           FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
           {kAssociated4,
            FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
       },
@@ -666,9 +667,9 @@
           Pair(kAssociated4,
                FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)),
           Pair(kPrimary,
-               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)),
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)),
           Pair(kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
-                                             absl::nullopt))));
+                                             std::nullopt))));
 }
 
 TEST_F(PopulatedGlobalFirstPartySetsTest,
@@ -680,16 +681,16 @@
       {
           {
               {kPrimary,
-               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
               {kAssociated1, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)},
+                                                std::nullopt)},
               {kAssociated1Cctld,
                FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                  absl::nullopt)},
+                                  std::nullopt)},
               {kAssociated4, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)},
+                                                std::nullopt)},
               {kService,
-               FirstPartySetEntry(kPrimary, SiteType::kService, absl::nullopt)},
+               FirstPartySetEntry(kPrimary, SiteType::kService, std::nullopt)},
           },
       },
       /*addition_sets=*/{}));
@@ -699,19 +700,19 @@
       UnorderedElementsAre(
           Pair(kAssociated1Cctld,
                FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(kAssociated1, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)),
+                                                std::nullopt)),
           Pair(kAssociated3,
                FirstPartySetEntry(kPrimary2, SiteType::kAssociated, 0)),
           Pair(kAssociated4, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)),
+                                                std::nullopt)),
           Pair(kPrimary,
-               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)),
-          Pair(kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
-                                             absl::nullopt)),
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)),
+          Pair(kPrimary2,
+               FirstPartySetEntry(kPrimary2, SiteType::kPrimary, std::nullopt)),
           Pair(kService, FirstPartySetEntry(kPrimary, SiteType::kService,
-                                            absl::nullopt))));
+                                            std::nullopt))));
 }
 
 TEST_F(
@@ -723,7 +724,7 @@
       /*set_entries=*/
       {
           {kPrimary,
-           FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
           {kAssociated4,
            FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
           {kAssociated5,
@@ -738,16 +739,16 @@
       {
           {
               {kPrimary,
-               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
               {kAssociated1, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)},
+                                                std::nullopt)},
               {kAssociated1Cctld,
                FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                  absl::nullopt)},
+                                  std::nullopt)},
               {kAssociated4, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)},
+                                                std::nullopt)},
               {kService,
-               FirstPartySetEntry(kPrimary, SiteType::kService, absl::nullopt)},
+               FirstPartySetEntry(kPrimary, SiteType::kService, std::nullopt)},
           },
       },
       /*addition_sets=*/{}));
@@ -759,19 +760,19 @@
       UnorderedElementsAre(
           Pair(kAssociated1Cctld,
                FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(kAssociated1, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)),
+                                                std::nullopt)),
           Pair(kAssociated3,
                FirstPartySetEntry(kPrimary2, SiteType::kAssociated, 0)),
           Pair(kAssociated4, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)),
+                                                std::nullopt)),
           Pair(kPrimary,
-               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)),
-          Pair(kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
-                                             absl::nullopt)),
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)),
+          Pair(kPrimary2,
+               FirstPartySetEntry(kPrimary2, SiteType::kPrimary, std::nullopt)),
           Pair(kService, FirstPartySetEntry(kPrimary, SiteType::kService,
-                                            absl::nullopt))));
+                                            std::nullopt))));
 }
 
 TEST_F(
@@ -781,7 +782,7 @@
       /*set_entries=*/
       {
           {kPrimary,
-           FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
           {kAssociated1,
            FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
       },
@@ -793,11 +794,11 @@
       /*replacement_sets=*/
       {
           {
-              {kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
-                                             absl::nullopt)},
+              {kPrimary2,
+               FirstPartySetEntry(kPrimary2, SiteType::kPrimary, std::nullopt)},
               {kAssociated1,
                FirstPartySetEntry(kPrimary2, SiteType::kAssociated,
-                                  absl::nullopt)},
+                                  std::nullopt)},
           },
       },
       /*addition_sets=*/{}));
@@ -807,17 +808,17 @@
       UnorderedElementsAre(
           Pair(kAssociated1,
                FirstPartySetEntry(kPrimary2, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(kPrimary,
-               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)),
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)),
           Pair(kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
-                                             absl::nullopt))));
+                                             std::nullopt))));
 }
 
 TEST_F(PopulatedGlobalFirstPartySetsTest, ComputeMetadata) {
   SchemefulSite nonmember(GURL("https://nonmember.test"));
   SchemefulSite nonmember1(GURL("https://nonmember1.test"));
-  FirstPartySetEntry primary_entry(kPrimary, SiteType::kPrimary, absl::nullopt);
+  FirstPartySetEntry primary_entry(kPrimary, SiteType::kPrimary, std::nullopt);
   FirstPartySetEntry associated_entry(kPrimary, SiteType::kAssociated, 0);
 
   // Works as usual for sites that are in First-Party sets.
@@ -849,7 +850,7 @@
                 /*entries=*/
                 {
                     {kPrimary, FirstPartySetEntry(kPrimary, SiteType::kPrimary,
-                                                  absl::nullopt)},
+                                                  std::nullopt)},
                     {kAssociated1,
                      FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
                 },
@@ -865,7 +866,7 @@
       /*entries=*/
       {
           {kPrimary,
-           FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
           {kAssociated1,
            FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
       },
@@ -874,11 +875,11 @@
       /*replacement_sets=*/
       {
           {
-              {kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
-                                             absl::nullopt)},
+              {kPrimary2,
+               FirstPartySetEntry(kPrimary2, SiteType::kPrimary, std::nullopt)},
               {kAssociated2,
                FirstPartySetEntry(kPrimary2, SiteType::kAssociated,
-                                  absl::nullopt)},
+                                  std::nullopt)},
           },
       },
       /*addition_sets=*/{}));
@@ -887,9 +888,9 @@
       UnorderedElementsAre(
           Pair(kAssociated2,
                FirstPartySetEntry(kPrimary2, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
-                                             absl::nullopt))));
+                                             std::nullopt))));
 }
 
 // The common associated site between the policy and existing set is removed
@@ -902,7 +903,7 @@
       /*entries=*/
       {
           {kPrimary,
-           FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
           {kAssociated1,
            FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
           {kAssociated2,
@@ -913,11 +914,11 @@
       /*replacement_sets=*/
       {
           {
-              {kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
-                                             absl::nullopt)},
+              {kPrimary2,
+               FirstPartySetEntry(kPrimary2, SiteType::kPrimary, std::nullopt)},
               {kAssociated2,
                FirstPartySetEntry(kPrimary2, SiteType::kAssociated,
-                                  absl::nullopt)},
+                                  std::nullopt)},
           },
       },
       /*addition_sets=*/{}));
@@ -926,9 +927,9 @@
       UnorderedElementsAre(
           Pair(kAssociated2,
                FirstPartySetEntry(kPrimary2, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
-                                             absl::nullopt))));
+                                             std::nullopt))));
 }
 
 // The common primary between the policy and existing set is removed and its
@@ -941,7 +942,7 @@
       /*entries=*/
       {
           {kPrimary,
-           FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
           {kAssociated1,
            FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
           {kAssociated2,
@@ -953,9 +954,9 @@
       {
           {
               {kPrimary,
-               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
               {kAssociated3, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)},
+                                                std::nullopt)},
           },
       },
       /*addition_sets=*/{}));
@@ -964,9 +965,9 @@
                        config),
       UnorderedElementsAre(
           Pair(kAssociated3, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)),
+                                                std::nullopt)),
           Pair(kPrimary, FirstPartySetEntry(kPrimary, SiteType::kPrimary,
-                                            absl::nullopt))));
+                                            std::nullopt))));
 }
 
 // The common associated site between the policy and existing set is removed and
@@ -979,7 +980,7 @@
       /*entries=*/
       {
           {kPrimary,
-           FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
           {kAssociated1,
            FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
       },
@@ -988,11 +989,11 @@
       /*replacement_sets=*/
       {
           {
-              {kPrimary3, FirstPartySetEntry(kPrimary3, SiteType::kPrimary,
-                                             absl::nullopt)},
+              {kPrimary3,
+               FirstPartySetEntry(kPrimary3, SiteType::kPrimary, std::nullopt)},
               {kAssociated1,
                FirstPartySetEntry(kPrimary3, SiteType::kAssociated,
-                                  absl::nullopt)},
+                                  std::nullopt)},
           },
       },
       /*addition_sets=*/{}));
@@ -1001,9 +1002,9 @@
       UnorderedElementsAre(
           Pair(kAssociated1,
                FirstPartySetEntry(kPrimary3, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(kPrimary3, FirstPartySetEntry(kPrimary3, SiteType::kPrimary,
-                                             absl::nullopt))));
+                                             std::nullopt))));
 }
 
 // The policy set and the existing set have nothing in common so the policy set
@@ -1015,7 +1016,7 @@
       /*entries=*/
       {
           {kPrimary,
-           FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
           {kAssociated1,
            FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
       },
@@ -1024,11 +1025,11 @@
       /*replacement_sets=*/{},
       /*addition_sets=*/{
           {
-              {kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
-                                             absl::nullopt)},
+              {kPrimary2,
+               FirstPartySetEntry(kPrimary2, SiteType::kPrimary, std::nullopt)},
               {kAssociated2,
                FirstPartySetEntry(kPrimary2, SiteType::kAssociated,
-                                  absl::nullopt)},
+                                  std::nullopt)},
           },
       }));
   EXPECT_THAT(
@@ -1036,9 +1037,9 @@
       UnorderedElementsAre(
           Pair(kAssociated2,
                FirstPartySetEntry(kPrimary2, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
-                                             absl::nullopt))));
+                                             std::nullopt))));
 }
 
 // The primary of a policy set is also an associated site in an existing set.
@@ -1052,7 +1053,7 @@
       /*entries=*/
       {
           {kPrimary,
-           FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
           {kAssociated1,
            FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
       },
@@ -1063,13 +1064,13 @@
           {
               {kAssociated1,
                FirstPartySetEntry(kAssociated1, SiteType::kPrimary,
-                                  absl::nullopt)},
+                                  std::nullopt)},
               {kAssociated2,
                FirstPartySetEntry(kAssociated1, SiteType::kAssociated,
-                                  absl::nullopt)},
+                                  std::nullopt)},
               {kAssociated3,
                FirstPartySetEntry(kAssociated1, SiteType::kAssociated,
-                                  absl::nullopt)},
+                                  std::nullopt)},
           },
       }));
   EXPECT_THAT(
@@ -1077,16 +1078,16 @@
                        config),
       UnorderedElementsAre(
           Pair(kPrimary, FirstPartySetEntry(kAssociated1, SiteType::kAssociated,
-                                            absl::nullopt)),
+                                            std::nullopt)),
           Pair(kAssociated2,
                FirstPartySetEntry(kAssociated1, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(kAssociated3,
                FirstPartySetEntry(kAssociated1, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(kAssociated1,
                FirstPartySetEntry(kAssociated1, SiteType::kPrimary,
-                                  absl::nullopt))));
+                                  std::nullopt))));
 }
 
 // The primary of a policy set is also a primary of an existing set.
@@ -1100,7 +1101,7 @@
       /*entries=*/
       {
           {kPrimary,
-           FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
           {kAssociated1,
            FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
           {kAssociated3,
@@ -1111,22 +1112,22 @@
       /*replacement_sets=*/{},
       /*addition_sets=*/{{
           {kPrimary,
-           FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
           {kAssociated2,
-           FirstPartySetEntry(kPrimary, SiteType::kAssociated, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kAssociated, std::nullopt)},
       }}));
   EXPECT_THAT(
       sets.FindEntries({kAssociated1, kAssociated2, kAssociated3, kPrimary},
                        config),
       UnorderedElementsAre(
           Pair(kAssociated1, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)),
+                                                std::nullopt)),
           Pair(kAssociated2, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)),
+                                                std::nullopt)),
           Pair(kAssociated3, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)),
+                                                std::nullopt)),
           Pair(kPrimary, FirstPartySetEntry(kPrimary, SiteType::kPrimary,
-                                            absl::nullopt))));
+                                            std::nullopt))));
 }
 
 // Existing set overlaps with both replacement and addition set.
@@ -1138,7 +1139,7 @@
       /*entries=*/
       {
           {kPrimary,
-           FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
           {kAssociated1,
            FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
           {kAssociated2,
@@ -1149,19 +1150,19 @@
       /*replacement_sets=*/
       {
           {
-              {kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
-                                             absl::nullopt)},
+              {kPrimary2,
+               FirstPartySetEntry(kPrimary2, SiteType::kPrimary, std::nullopt)},
               {kAssociated1,
                FirstPartySetEntry(kPrimary2, SiteType::kAssociated,
-                                  absl::nullopt)},
+                                  std::nullopt)},
           },
       },
       /*addition_sets=*/{
           {
               {kPrimary,
-               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
               {kAssociated3, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)},
+                                                std::nullopt)},
           },
       }));
   EXPECT_THAT(
@@ -1171,15 +1172,15 @@
       UnorderedElementsAre(
           Pair(kAssociated1,
                FirstPartySetEntry(kPrimary2, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(kAssociated2, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)),
+                                                std::nullopt)),
           Pair(kAssociated3, FirstPartySetEntry(kPrimary, SiteType::kAssociated,
-                                                absl::nullopt)),
+                                                std::nullopt)),
           Pair(kPrimary,
-               FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)),
+               FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)),
           Pair(kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
-                                             absl::nullopt))));
+                                             std::nullopt))));
 }
 
 TEST_F(GlobalFirstPartySetsTest, TransitiveOverlap_TwoCommonPrimaries) {
@@ -1200,7 +1201,7 @@
       /*entries=*/
       {
           {primary1,
-           FirstPartySetEntry(primary1, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(primary1, SiteType::kPrimary, std::nullopt)},
           {primary2, FirstPartySetEntry(primary1, SiteType::kAssociated, 0)},
       },
       /*aliases=*/{});
@@ -1208,25 +1209,22 @@
       /*replacement_sets=*/{},
       /*addition_sets=*/{
           {{primary0,
-            FirstPartySetEntry(primary0, SiteType::kPrimary, absl::nullopt)},
+            FirstPartySetEntry(primary0, SiteType::kPrimary, std::nullopt)},
            {associated_site0,
-            FirstPartySetEntry(primary0, SiteType::kAssociated,
-                               absl::nullopt)}},
+            FirstPartySetEntry(primary0, SiteType::kAssociated, std::nullopt)}},
           {{primary1,
-            FirstPartySetEntry(primary1, SiteType::kPrimary, absl::nullopt)},
+            FirstPartySetEntry(primary1, SiteType::kPrimary, std::nullopt)},
            {associated_site1,
-            FirstPartySetEntry(primary1, SiteType::kAssociated,
-                               absl::nullopt)}},
+            FirstPartySetEntry(primary1, SiteType::kAssociated, std::nullopt)}},
           {{primary2,
-            FirstPartySetEntry(primary2, SiteType::kPrimary, absl::nullopt)},
+            FirstPartySetEntry(primary2, SiteType::kPrimary, std::nullopt)},
            {associated_site2,
-            FirstPartySetEntry(primary2, SiteType::kAssociated,
-                               absl::nullopt)}},
+            FirstPartySetEntry(primary2, SiteType::kAssociated, std::nullopt)}},
           {{primary42,
-            FirstPartySetEntry(primary42, SiteType::kPrimary, absl::nullopt)},
+            FirstPartySetEntry(primary42, SiteType::kPrimary, std::nullopt)},
            {associated_site42,
             FirstPartySetEntry(primary42, SiteType::kAssociated,
-                               absl::nullopt)}},
+                               std::nullopt)}},
       }));
   EXPECT_THAT(
       sets.FindEntries(
@@ -1244,24 +1242,24 @@
       UnorderedElementsAre(
           Pair(associated_site0,
                FirstPartySetEntry(primary0, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(associated_site1,
                FirstPartySetEntry(primary1, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(associated_site2,
                FirstPartySetEntry(primary1, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(associated_site42,
                FirstPartySetEntry(primary42, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(primary0,
-               FirstPartySetEntry(primary0, SiteType::kPrimary, absl::nullopt)),
+               FirstPartySetEntry(primary0, SiteType::kPrimary, std::nullopt)),
           Pair(primary1,
-               FirstPartySetEntry(primary1, SiteType::kPrimary, absl::nullopt)),
+               FirstPartySetEntry(primary1, SiteType::kPrimary, std::nullopt)),
           Pair(primary2, FirstPartySetEntry(primary1, SiteType::kAssociated,
-                                            absl::nullopt)),
+                                            std::nullopt)),
           Pair(primary42, FirstPartySetEntry(primary42, SiteType::kPrimary,
-                                             absl::nullopt))));
+                                             std::nullopt))));
 }
 
 TEST_F(GlobalFirstPartySetsTest, TransitiveOverlap_TwoCommonAssociatedSites) {
@@ -1282,7 +1280,7 @@
       /*entries=*/
       {
           {primary2,
-           FirstPartySetEntry(primary2, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(primary2, SiteType::kPrimary, std::nullopt)},
           {primary1, FirstPartySetEntry(primary2, SiteType::kAssociated, 0)},
       },
       /*aliases=*/{});
@@ -1290,25 +1288,22 @@
       /*replacement_sets=*/{},
       /*addition_sets=*/{
           {{primary0,
-            FirstPartySetEntry(primary0, SiteType::kPrimary, absl::nullopt)},
+            FirstPartySetEntry(primary0, SiteType::kPrimary, std::nullopt)},
            {associated_site0,
-            FirstPartySetEntry(primary0, SiteType::kAssociated,
-                               absl::nullopt)}},
+            FirstPartySetEntry(primary0, SiteType::kAssociated, std::nullopt)}},
           {{primary2,
-            FirstPartySetEntry(primary2, SiteType::kPrimary, absl::nullopt)},
+            FirstPartySetEntry(primary2, SiteType::kPrimary, std::nullopt)},
            {associated_site2,
-            FirstPartySetEntry(primary2, SiteType::kAssociated,
-                               absl::nullopt)}},
+            FirstPartySetEntry(primary2, SiteType::kAssociated, std::nullopt)}},
           {{primary1,
-            FirstPartySetEntry(primary1, SiteType::kPrimary, absl::nullopt)},
+            FirstPartySetEntry(primary1, SiteType::kPrimary, std::nullopt)},
            {associated_site1,
-            FirstPartySetEntry(primary1, SiteType::kAssociated,
-                               absl::nullopt)}},
+            FirstPartySetEntry(primary1, SiteType::kAssociated, std::nullopt)}},
           {{primary42,
-            FirstPartySetEntry(primary42, SiteType::kPrimary, absl::nullopt)},
+            FirstPartySetEntry(primary42, SiteType::kPrimary, std::nullopt)},
            {associated_site42,
             FirstPartySetEntry(primary42, SiteType::kAssociated,
-                               absl::nullopt)}},
+                               std::nullopt)}},
       }));
   EXPECT_THAT(
       sets.FindEntries(
@@ -1326,24 +1321,24 @@
       UnorderedElementsAre(
           Pair(associated_site0,
                FirstPartySetEntry(primary0, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(associated_site1,
                FirstPartySetEntry(primary2, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(associated_site2,
                FirstPartySetEntry(primary2, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(associated_site42,
                FirstPartySetEntry(primary42, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(primary0,
-               FirstPartySetEntry(primary0, SiteType::kPrimary, absl::nullopt)),
+               FirstPartySetEntry(primary0, SiteType::kPrimary, std::nullopt)),
           Pair(primary1, FirstPartySetEntry(primary2, SiteType::kAssociated,
-                                            absl::nullopt)),
+                                            std::nullopt)),
           Pair(primary2,
-               FirstPartySetEntry(primary2, SiteType::kPrimary, absl::nullopt)),
+               FirstPartySetEntry(primary2, SiteType::kPrimary, std::nullopt)),
           Pair(primary42, FirstPartySetEntry(primary42, SiteType::kPrimary,
-                                             absl::nullopt))));
+                                             std::nullopt))));
 }
 
 TEST_F(GlobalFirstPartySetsTest, InvalidPublicSetsVersion_ComputeConfig) {
@@ -1351,7 +1346,7 @@
       base::Version(), /*entries=*/
       {
           {kPrimary,
-           FirstPartySetEntry(kPrimary, SiteType::kPrimary, absl::nullopt)},
+           FirstPartySetEntry(kPrimary, SiteType::kPrimary, std::nullopt)},
           {kAssociated1,
            FirstPartySetEntry(kPrimary, SiteType::kAssociated, 0)},
       },
@@ -1362,11 +1357,11 @@
       /*replacement_sets=*/
       {
           {
-              {kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
-                                             absl::nullopt)},
+              {kPrimary2,
+               FirstPartySetEntry(kPrimary2, SiteType::kPrimary, std::nullopt)},
               {kAssociated2,
                FirstPartySetEntry(kPrimary2, SiteType::kAssociated,
-                                  absl::nullopt)},
+                                  std::nullopt)},
           },
       },
       /*addition_sets=*/{}));
@@ -1386,9 +1381,9 @@
       UnorderedElementsAre(
           Pair(kAssociated2,
                FirstPartySetEntry(kPrimary2, SiteType::kAssociated,
-                                  absl::nullopt)),
+                                  std::nullopt)),
           Pair(kPrimary2, FirstPartySetEntry(kPrimary2, SiteType::kPrimary,
-                                             absl::nullopt))));
+                                             std::nullopt))));
 }
 
 class GlobalFirstPartySetsWithConfigTest
@@ -1400,7 +1395,7 @@
             {kPrimary3, net::FirstPartySetEntryOverride(
                             FirstPartySetEntry(kPrimary3,
                                                SiteType::kPrimary,
-                                               absl::nullopt))},
+                                               std::nullopt))},
             // Removed entry:
             {kAssociated1, net::FirstPartySetEntryOverride()},
             // Remapped entry:
@@ -1419,9 +1414,9 @@
 
 TEST_F(GlobalFirstPartySetsWithConfigTest, ComputeMetadata) {
   FirstPartySetEntry example_primary_entry(kPrimary, SiteType::kPrimary,
-                                           absl::nullopt);
+                                           std::nullopt);
   FirstPartySetEntry foo_primary_entry(kPrimary3, SiteType::kPrimary,
-                                       absl::nullopt);
+                                       std::nullopt);
   FirstPartySetEntry foo_associated_entry(kPrimary3, SiteType::kAssociated, 0);
 
   // kAssociated1 has been removed from its set.
diff --git a/net/first_party_sets/local_set_declaration_unittest.cc b/net/first_party_sets/local_set_declaration_unittest.cc
index 09f7513d..65c1de12 100644
--- a/net/first_party_sets/local_set_declaration_unittest.cc
+++ b/net/first_party_sets/local_set_declaration_unittest.cc
@@ -4,12 +4,13 @@
 
 #include "net/first_party_sets/local_set_declaration.h"
 
+#include <optional>
+
 #include "net/base/schemeful_site.h"
 #include "net/first_party_sets/first_party_set_entry.h"
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 using ::testing::IsEmpty;
@@ -27,14 +28,14 @@
   SchemefulSite associated(GURL("https://associated.test"));
 
   base::flat_map<SchemefulSite, FirstPartySetEntry> entries({
-      {primary, FirstPartySetEntry(primary, SiteType::kPrimary, absl::nullopt)},
+      {primary, FirstPartySetEntry(primary, SiteType::kPrimary, std::nullopt)},
       {associated, FirstPartySetEntry(primary, SiteType::kAssociated, 0)},
   });
 
   EXPECT_THAT(LocalSetDeclaration(entries, /*aliases=*/{}).entries(),
               UnorderedElementsAre(
                   Pair(primary, FirstPartySetEntry(primary, SiteType::kPrimary,
-                                                   absl::nullopt)),
+                                                   std::nullopt)),
                   Pair(associated,
                        FirstPartySetEntry(primary, SiteType::kAssociated, 0))));
 }
@@ -46,7 +47,7 @@
   SchemefulSite associated_cctld(GURL("https://associated.cctld"));
 
   base::flat_map<SchemefulSite, FirstPartySetEntry> entries({
-      {primary, FirstPartySetEntry(primary, SiteType::kPrimary, absl::nullopt)},
+      {primary, FirstPartySetEntry(primary, SiteType::kPrimary, std::nullopt)},
       {associated, FirstPartySetEntry(primary, SiteType::kAssociated, 0)},
   });
 
@@ -60,7 +61,7 @@
   EXPECT_THAT(local_set.entries(),
               UnorderedElementsAre(
                   Pair(primary, FirstPartySetEntry(primary, SiteType::kPrimary,
-                                                   absl::nullopt)),
+                                                   std::nullopt)),
                   Pair(associated,
                        FirstPartySetEntry(primary, SiteType::kAssociated, 0))));
 
diff --git a/net/first_party_sets/sets_mutation_unittest.cc b/net/first_party_sets/sets_mutation_unittest.cc
index b2806f5..56791fb 100644
--- a/net/first_party_sets/sets_mutation_unittest.cc
+++ b/net/first_party_sets/sets_mutation_unittest.cc
@@ -4,12 +4,13 @@
 
 #include "net/first_party_sets/sets_mutation.h"
 
+#include <optional>
+
 #include "net/base/schemeful_site.h"
 #include "net/first_party_sets/first_party_set_entry.h"
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 using ::testing::Pair;
@@ -28,13 +29,13 @@
       {
           {
               {primary1,
-               FirstPartySetEntry(primary1, SiteType::kPrimary, absl::nullopt)},
+               FirstPartySetEntry(primary1, SiteType::kPrimary, std::nullopt)},
               {associated1,
                FirstPartySetEntry(primary1, SiteType::kAssociated, 0)},
           },
           {
               {primary2,
-               FirstPartySetEntry(primary2, SiteType::kPrimary, absl::nullopt)},
+               FirstPartySetEntry(primary2, SiteType::kPrimary, std::nullopt)},
               {associated2,
                FirstPartySetEntry(primary2, SiteType::kAssociated, 0)},
           },
@@ -46,13 +47,13 @@
       /*addition_sets=*/{
           {
               {primary1,
-               FirstPartySetEntry(primary1, SiteType::kPrimary, absl::nullopt)},
+               FirstPartySetEntry(primary1, SiteType::kPrimary, std::nullopt)},
               {associated1,
                FirstPartySetEntry(primary1, SiteType::kAssociated, 0)},
           },
           {
               {primary2,
-               FirstPartySetEntry(primary2, SiteType::kPrimary, absl::nullopt)},
+               FirstPartySetEntry(primary2, SiteType::kPrimary, std::nullopt)},
               {associated2,
                FirstPartySetEntry(primary2, SiteType::kAssociated, 0)},
           },
@@ -63,7 +64,7 @@
       {
           {
               {primary1,
-               FirstPartySetEntry(primary1, SiteType::kPrimary, absl::nullopt)},
+               FirstPartySetEntry(primary1, SiteType::kPrimary, std::nullopt)},
               {associated1,
                FirstPartySetEntry(primary1, SiteType::kAssociated, 0)},
           },
@@ -71,7 +72,7 @@
       /*addition_sets=*/{
           {
               {primary2,
-               FirstPartySetEntry(primary2, SiteType::kPrimary, absl::nullopt)},
+               FirstPartySetEntry(primary2, SiteType::kPrimary, std::nullopt)},
               {associated2,
                FirstPartySetEntry(primary2, SiteType::kAssociated, 0)},
           },
@@ -92,13 +93,13 @@
             {
                 {
                     {primary1, FirstPartySetEntry(primary1, SiteType::kPrimary,
-                                                  absl::nullopt)},
+                                                  std::nullopt)},
                     {associated1,
                      FirstPartySetEntry(primary1, SiteType::kAssociated, 0)},
                 },
                 {
                     {primary2, FirstPartySetEntry(primary2, SiteType::kPrimary,
-                                                  absl::nullopt)},
+                                                  std::nullopt)},
                     {associated1,
                      FirstPartySetEntry(primary2, SiteType::kAssociated, 0)},
                     {associated2,
diff --git a/net/http/broken_alternative_services.cc b/net/http/broken_alternative_services.cc
index 3c963e9..7d5c7fc 100644
--- a/net/http/broken_alternative_services.cc
+++ b/net/http/broken_alternative_services.cc
@@ -315,8 +315,8 @@
 }
 
 void BrokenAlternativeServices::SetDelayParams(
-    absl::optional<base::TimeDelta> initial_delay,
-    absl::optional<bool> exponential_backoff_on_initial_delay) {
+    std::optional<base::TimeDelta> initial_delay,
+    std::optional<bool> exponential_backoff_on_initial_delay) {
   if (initial_delay.has_value()) {
     initial_delay_ = initial_delay.value();
   }
diff --git a/net/http/broken_alternative_services.h b/net/http/broken_alternative_services.h
index a706067..81338dc 100644
--- a/net/http/broken_alternative_services.h
+++ b/net/http/broken_alternative_services.h
@@ -159,9 +159,8 @@
   // If values are present, sets initial_delay_ and
   // exponential_backoff_on_initial_delay_ which are used to calculate delay of
   // broken alternative services.
-  void SetDelayParams(
-      absl::optional<base::TimeDelta> initial_delay,
-      absl::optional<bool> exponential_backoff_on_initial_delay);
+  void SetDelayParams(std::optional<base::TimeDelta> initial_delay,
+                      std::optional<bool> exponential_backoff_on_initial_delay);
 
   const BrokenAlternativeServiceList& broken_alternative_service_list() const;
 
diff --git a/net/http/http_auth_controller.cc b/net/http/http_auth_controller.cc
index a3bfb754..dac5171 100644
--- a/net/http/http_auth_controller.cc
+++ b/net/http/http_auth_controller.cc
@@ -401,7 +401,7 @@
     identity_.credentials = credentials;
 
     // auth_info_ is no longer necessary.
-    auth_info_ = absl::nullopt;
+    auth_info_ = std::nullopt;
   }
 
   DCHECK(identity_.source != HttpAuth::IDENT_SRC_PATH_LOOKUP);
@@ -636,8 +636,7 @@
   }
 }
 
-void HttpAuthController::TakeAuthInfo(
-    absl::optional<AuthChallengeInfo>* other) {
+void HttpAuthController::TakeAuthInfo(std::optional<AuthChallengeInfo>* other) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   auth_info_.swap(*other);
 }
diff --git a/net/http/http_auth_controller.h b/net/http/http_auth_controller.h
index 19082cb2..5c506d4c 100644
--- a/net/http/http_auth_controller.h
+++ b/net/http/http_auth_controller.h
@@ -6,6 +6,7 @@
 #define NET_HTTP_HTTP_AUTH_CONTROLLER_H_
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 
@@ -18,7 +19,6 @@
 #include "net/http/http_auth.h"
 #include "net/http/http_auth_preferences.h"
 #include "net/log/net_log_with_source.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/scheme_host_port.h"
 
@@ -125,7 +125,7 @@
   bool NeedsHTTP11() const;
 
   // Swaps the authentication challenge info into |other|.
-  void TakeAuthInfo(absl::optional<AuthChallengeInfo>* other);
+  void TakeAuthInfo(std::optional<AuthChallengeInfo>* other);
 
   bool IsAuthSchemeDisabled(HttpAuth::Scheme scheme) const;
   void DisableAuthScheme(HttpAuth::Scheme scheme);
@@ -221,7 +221,7 @@
   std::string auth_token_;
 
   // Contains information about the auth challenge.
-  absl::optional<AuthChallengeInfo> auth_info_;
+  std::optional<AuthChallengeInfo> auth_info_;
 
   // True if we've used the username:password embedded in the URL.  This
   // makes sure we use the embedded identity only once for the transaction,
diff --git a/net/http/http_auth_handler_factory.cc b/net/http/http_auth_handler_factory.cc
index b334186..ca2e684a 100644
--- a/net/http/http_auth_handler_factory.cc
+++ b/net/http/http_auth_handler_factory.cc
@@ -4,6 +4,7 @@
 
 #include "net/http/http_auth_handler_factory.h"
 
+#include <optional>
 #include <set>
 
 #include "base/containers/contains.h"
@@ -22,7 +23,6 @@
 #include "net/log/net_log_values.h"
 #include "net/net_buildflags.h"
 #include "net/ssl/ssl_info.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/scheme_host_port.h"
 
 #if BUILDFLAG(USE_KERBEROS)
@@ -36,7 +36,7 @@
     const std::string& challenge,
     const int net_error,
     const url::SchemeHostPort& scheme_host_port,
-    const absl::optional<bool>& allows_default_credentials,
+    const std::optional<bool>& allows_default_credentials,
     net::NetLogCaptureMode capture_mode) {
   base::Value::Dict dict;
   dict.Set("scheme", net::NetLogStringValue(scheme));
@@ -233,8 +233,8 @@
         return NetLogParamsForCreateAuth(
             scheme, challenge->challenge_text(), net_error, scheme_host_port,
             *handler
-                ? absl::make_optional((*handler)->AllowsDefaultCredentials())
-                : absl::nullopt,
+                ? std::make_optional((*handler)->AllowsDefaultCredentials())
+                : std::nullopt,
             capture_mode);
       });
   return net_error;
@@ -255,10 +255,10 @@
 }
 
 #if BUILDFLAG(USE_KERBEROS) && !BUILDFLAG(IS_ANDROID) && BUILDFLAG(IS_POSIX)
-absl::optional<std::string>
+std::optional<std::string>
 HttpAuthHandlerRegistryFactory::GetNegotiateLibraryNameForTesting() const {
   if (!IsSchemeAllowed(kNegotiateAuthScheme))
-    return absl::nullopt;
+    return std::nullopt;
 
   return reinterpret_cast<net::HttpAuthHandlerNegotiate::Factory*>(
              GetSchemeFactory(net::kNegotiateAuthScheme))
diff --git a/net/http/http_auth_handler_factory.h b/net/http/http_auth_handler_factory.h
index 8c9f268..a35b1cb 100644
--- a/net/http/http_auth_handler_factory.h
+++ b/net/http/http_auth_handler_factory.h
@@ -7,6 +7,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
@@ -19,7 +20,6 @@
 #include "net/http/http_auth_scheme.h"
 #include "net/http/url_security_manager.h"
 #include "net/net_buildflags.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace url {
 class SchemeHostPort;
@@ -238,7 +238,7 @@
       std::unique_ptr<HttpAuthHandler>* handler) override;
 
 #if BUILDFLAG(USE_KERBEROS) && !BUILDFLAG(IS_ANDROID) && BUILDFLAG(IS_POSIX)
-  absl::optional<std::string> GetNegotiateLibraryNameForTesting() const;
+  std::optional<std::string> GetNegotiateLibraryNameForTesting() const;
 #endif
 
   // Returns true if the scheme is allowed to be used for all origins. An auth
diff --git a/net/http/http_auth_handler_factory_unittest.cc b/net/http/http_auth_handler_factory_unittest.cc
index 60545ad..76ec684 100644
--- a/net/http/http_auth_handler_factory_unittest.cc
+++ b/net/http/http_auth_handler_factory_unittest.cc
@@ -385,7 +385,7 @@
       const std::string* scheme = entries[0].params.FindString("scheme");
       ASSERT_NE(nullptr, scheme);
       EXPECT_STRCASEEQ(test_case.expected_scheme, scheme->data());
-      absl::optional<int> net_error = entries[0].params.FindInt("net_error");
+      std::optional<int> net_error = entries[0].params.FindInt("net_error");
       if (test_case.expected_net_error) {
         ASSERT_TRUE(net_error.has_value());
         EXPECT_EQ(test_case.expected_net_error, net_error.value());
diff --git a/net/http/http_auth_preferences.h b/net/http/http_auth_preferences.h
index f14d55e..127e47c 100644
--- a/net/http/http_auth_preferences.h
+++ b/net/http/http_auth_preferences.h
@@ -6,6 +6,7 @@
 #define NET_HTTP_HTTP_AUTH_PREFERENCES_H_
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 
@@ -14,7 +15,6 @@
 #include "build/chromeos_buildflags.h"
 #include "net/base/net_export.h"
 #include "net/http/http_auth.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace url {
 class SchemeHostPort;
@@ -92,12 +92,12 @@
   }
 #endif  // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
 
-  const absl::optional<std::set<std::string>>& allowed_schemes() const {
+  const std::optional<std::set<std::string>>& allowed_schemes() const {
     return allowed_schemes_;
   }
 
   void set_allowed_schemes(
-      const absl::optional<std::set<std::string>>& allowed_schemes) {
+      const std::optional<std::set<std::string>>& allowed_schemes) {
     allowed_schemes_ = allowed_schemes;
   }
 
@@ -141,7 +141,7 @@
   bool allow_gssapi_library_load_ = true;
 #endif  // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
 
-  absl::optional<std::set<std::string>> allowed_schemes_;
+  std::optional<std::set<std::string>> allowed_schemes_;
   std::unique_ptr<URLSecurityManager> security_manager_;
   base::RepeatingCallback<bool(const url::SchemeHostPort&)>
       http_auth_scheme_filter_ =
diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc
index 6cf84824..997cdff 100644
--- a/net/http/http_cache.cc
+++ b/net/http/http_cache.cc
@@ -4,6 +4,7 @@
 
 #include "net/http/http_cache.h"
 
+#include <optional>
 #include <utility>
 
 #include "base/compiler_specific.h"
@@ -49,7 +50,6 @@
 #include "net/http/http_util.h"
 #include "net/log/net_log_with_source.h"
 #include "net/quic/quic_server_info.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_POSIX)
 #include <unistd.h>
@@ -604,7 +604,7 @@
 
 // static
 // Generate a key that can be used inside the cache.
-absl::optional<std::string> HttpCache::GenerateCacheKey(
+std::optional<std::string> HttpCache::GenerateCacheKey(
     const GURL& url,
     int load_flags,
     const NetworkIsolationKey& network_isolation_key,
@@ -626,7 +626,7 @@
     // confused with a single-keyed entry). Separate the origin and url
     // with invalid whitespace character |kDoubleKeySeparator|.
     if (network_isolation_key.IsTransient()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     std::string subframe_document_resource_prefix =
         is_subframe_document_resource ? kSubframeDocumentResourcePrefix : "";
@@ -647,7 +647,7 @@
 }
 
 // static
-absl::optional<std::string> HttpCache::GenerateCacheKeyForRequest(
+std::optional<std::string> HttpCache::GenerateCacheKeyForRequest(
     const HttpRequestInfo* request) {
   CHECK(request);
   const int64_t upload_data_identifier =
diff --git a/net/http/http_cache.h b/net/http/http_cache.h
index 6bafcc99..96404d049 100644
--- a/net/http/http_cache.h
+++ b/net/http/http_cache.h
@@ -17,6 +17,7 @@
 #include <list>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <unordered_map>
@@ -39,7 +40,6 @@
 #include "net/base/request_priority.h"
 #include "net/disk_cache/disk_cache.h"
 #include "net/http/http_transaction_factory.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class GURL;
 
@@ -259,13 +259,13 @@
   // configured to be split by the NetworkIsolationKey, and the
   // NetworkIsolationKey is transient, in which case nothing should generally be
   // stored to disk.
-  static absl::optional<std::string> GenerateCacheKey(
+  static std::optional<std::string> GenerateCacheKey(
       const GURL& url,
       int load_flags,
       const NetworkIsolationKey& network_isolation_key,
       int64_t upload_data_identifier,
       bool is_subframe_document_resource);
-  static absl::optional<std::string> GenerateCacheKeyForRequest(
+  static std::optional<std::string> GenerateCacheKeyForRequest(
       const HttpRequestInfo* request);
 
   // Enable split cache feature if not already overridden in the feature list.
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index ead08e8..800fb77 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -97,8 +97,8 @@
 };
 
 bool ShouldByPassCacheForFirstPartySets(
-    const absl::optional<int64_t>& clear_at_run_id,
-    const absl::optional<int64_t>& written_at_run_id) {
+    const std::optional<int64_t>& clear_at_run_id,
+    const std::optional<int64_t>& written_at_run_id) {
   return clear_at_run_id.has_value() &&
          (!written_at_run_id.has_value() ||
           written_at_run_id.value() < clear_at_run_id.value());
@@ -3981,7 +3981,7 @@
     // transaction was being processed that now needs to be processed.
     if (pending_io_result_) {
       int stored_result = pending_io_result_.value();
-      pending_io_result_ = absl::nullopt;
+      pending_io_result_ = std::nullopt;
       OnIOComplete(stored_result);
     }
   } else {
diff --git a/net/http/http_cache_transaction.h b/net/http/http_cache_transaction.h
index 764ef7c..21bf29f 100644
--- a/net/http/http_cache_transaction.h
+++ b/net/http/http_cache_transaction.h
@@ -609,7 +609,7 @@
   // If a pending async HTTPCache transaction takes longer than the parallel
   // Network IO, this will store the result of the Network IO operation until
   // the cache transaction completes (or times out).
-  absl::optional<int> pending_io_result_ = absl::nullopt;
+  std::optional<int> pending_io_result_ = std::nullopt;
 
   // Used for tracing.
   const uint64_t trace_id_;
@@ -647,7 +647,7 @@
   // and modifies the members for future transactions. Then,
   // WriteResponseInfoToEntry() writes |updated_prefetch_response_| to the cache
   // entry if it is populated, or |response_| otherwise. Finally,
-  // WriteResponseInfoToEntry() resets this to absl::nullopt.
+  // WriteResponseInfoToEntry() resets this to std::nullopt.
   std::unique_ptr<HttpResponseInfo> updated_prefetch_response_;
 
   raw_ptr<const HttpResponseInfo, AcrossTasksDanglingUntriaged> new_response_ =
diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc
index 264b7578..2b2ec5c 100644
--- a/net/http/http_cache_unittest.cc
+++ b/net/http/http_cache_unittest.cc
@@ -8,6 +8,7 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 #include <set>
 #include <utility>
 #include <vector>
@@ -75,7 +76,6 @@
 #include "net/websockets/websocket_handshake_stream_base.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/origin.h"
 
 using net::test::IsError;
@@ -371,8 +371,8 @@
     base::Time(),
     "<html><body>Google Blah Blah</body></html>",
     {},
-    absl::nullopt,
-    absl::nullopt,
+    std::nullopt,
+    std::nullopt,
     TEST_MODE_SYNC_NET_START,
     base::BindRepeating(&FastTransactionServer::FastNoStoreHandler),
     MockTransactionReadHandler(),
@@ -576,8 +576,8 @@
     base::Time(),
     "rg: 40-49 ",
     {},
-    absl::nullopt,
-    absl::nullopt,
+    std::nullopt,
+    std::nullopt,
     TEST_MODE_NORMAL,
     base::BindRepeating(&RangeTransactionServer::RangeHandler),
     MockTransactionReadHandler(),
@@ -11424,7 +11424,7 @@
       net::NetworkAnonymizationKey::CreateCrossSite(site_b);
   switch (GetParam()) {
     case SplitCacheTestCase::kSplitCacheNikFrameSiteEnabled:
-      EXPECT_EQ(absl::nullopt,
+      EXPECT_EQ(std::nullopt,
                 trans_info.network_isolation_key.ToCacheKeyString());
       break;
     case SplitCacheTestCase::kSplitCacheNikCrossSiteFlagEnabled:
@@ -11682,7 +11682,7 @@
   trans_info.network_isolation_key = NetworkIsolationKey(site_data, site_data);
   trans_info.network_anonymization_key =
       NetworkAnonymizationKey::CreateSameSite(site_data);
-  EXPECT_EQ(absl::nullopt, trans_info.network_isolation_key.ToCacheKeyString());
+  EXPECT_EQ(std::nullopt, trans_info.network_isolation_key.ToCacheKeyString());
   RunTransactionTestWithRequest(cache.http_cache(), kSimpleGET_Transaction,
                                 trans_info, &response);
   EXPECT_FALSE(response.was_cached);
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h
index 5fa5161..917708b0 100644
--- a/net/http/http_network_session.h
+++ b/net/http/http_network_session.h
@@ -10,6 +10,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <unordered_set>
@@ -37,7 +38,6 @@
 #include "net/spdy/spdy_session_pool.h"
 #include "net/ssl/ssl_client_session_cache.h"
 #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class Value;
@@ -127,7 +127,7 @@
   // https://tools.ietf.org/html/draft-bishop-httpbis-grease-00.
   // The same frame will be sent out on all connections to prevent the retry
   // logic from hiding broken servers.
-  absl::optional<SpdySessionPool::GreasedHttp2Frame> greased_http2_frame;
+  std::optional<SpdySessionPool::GreasedHttp2Frame> greased_http2_frame;
   // If set, the HEADERS frame carrying a request without body will not have
   // the END_STREAM flag set.  The stream will be closed by a subsequent empty
   // DATA frame with END_STREAM.  Does not affect bidirectional or proxy
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 3b372bc..e0f3805 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -1695,7 +1695,7 @@
 }
 
 // static
-absl::optional<HttpNetworkTransaction::RetryReason>
+std::optional<HttpNetworkTransaction::RetryReason>
 HttpNetworkTransaction::GetRetryReasonForIOError(int error) {
   switch (error) {
     case ERR_CONNECTION_RESET:
@@ -1723,7 +1723,7 @@
     case ERR_QUIC_PROTOCOL_ERROR:
       return RetryReason::kQuicProtocolError;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 // This method determines whether it is safe to resend the request after an
@@ -1740,7 +1740,7 @@
   GenerateNetworkErrorLoggingReportIfError(error);
 #endif  // BUILDFLAG(ENABLE_REPORTING)
 
-  absl::optional<HttpNetworkTransaction::RetryReason> retry_reason =
+  std::optional<HttpNetworkTransaction::RetryReason> retry_reason =
       GetRetryReasonForIOError(error);
   if (!retry_reason) {
     return error;
@@ -2092,9 +2092,9 @@
   if (!stream_) {
     return;
   }
-  absl::optional<quic::QuicErrorCode> connection_error =
+  std::optional<quic::QuicErrorCode> connection_error =
       stream_->GetQuicErrorCode();
-  absl::optional<quic::QuicRstStreamErrorCode> stream_error =
+  std::optional<quic::QuicRstStreamErrorCode> stream_error =
       stream_->GetQuicRstStreamErrorCode();
   if (!connection_error || !stream_error) {
     return;
diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h
index 6558e7d..4eb4f743 100644
--- a/net/http/http_network_transaction.h
+++ b/net/http/http_network_transaction.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -35,7 +36,6 @@
 #include "net/socket/connection_attempts.h"
 #include "net/ssl/ssl_config.h"
 #include "net/websockets/websocket_handshake_stream_base.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -291,7 +291,7 @@
     kQuicProtocolError = 18,
     kMaxValue = kQuicProtocolError,
   };
-  static absl::optional<RetryReason> GetRetryReasonForIOError(int error);
+  static std::optional<RetryReason> GetRetryReasonForIOError(int error);
 
   // Resets the connection and the request headers for resend.  Called when
   // ShouldResendRequest() is true.
@@ -505,7 +505,7 @@
   // Set to true when the server required HTTP/1.1 fallback.
   bool http_1_1_was_required_ = false;
 
-  absl::optional<base::TimeDelta> quic_protocol_error_retry_delay_;
+  std::optional<base::TimeDelta> quic_protocol_error_retry_delay_;
 };
 
 }  // namespace net
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 91f77c4..52177c1 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -10,6 +10,7 @@
 
 #include <limits>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
@@ -127,7 +128,6 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/scheme_host_port.h"
 #include "url/url_constants.h"
@@ -704,7 +704,7 @@
   int RequestSocket(
       const ClientSocketPool::GroupId& group_id,
       scoped_refptr<ClientSocketPool::SocketParams> socket_params,
-      const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+      const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
       RequestPriority priority,
       const SocketTag& socket_tag,
       ClientSocketPool::RespectLimits respect_limits,
@@ -745,7 +745,7 @@
 // Helper functions for validating that AuthChallengeInfo's are correctly
 // configured for common cases.
 bool CheckBasicServerAuth(
-    const absl::optional<AuthChallengeInfo>& auth_challenge) {
+    const std::optional<AuthChallengeInfo>& auth_challenge) {
   if (!auth_challenge) {
     return false;
   }
@@ -757,7 +757,7 @@
 }
 
 bool CheckBasicSecureServerAuth(
-    const absl::optional<AuthChallengeInfo>& auth_challenge) {
+    const std::optional<AuthChallengeInfo>& auth_challenge) {
   if (!auth_challenge) {
     return false;
   }
@@ -769,7 +769,7 @@
 }
 
 bool CheckBasicProxyAuth(
-    const absl::optional<AuthChallengeInfo>& auth_challenge) {
+    const std::optional<AuthChallengeInfo>& auth_challenge) {
   if (!auth_challenge) {
     return false;
   }
@@ -781,7 +781,7 @@
 }
 
 bool CheckBasicSecureProxyAuth(
-    const absl::optional<AuthChallengeInfo>& auth_challenge) {
+    const std::optional<AuthChallengeInfo>& auth_challenge) {
   if (!auth_challenge) {
     return false;
   }
@@ -793,7 +793,7 @@
 }
 
 bool CheckDigestServerAuth(
-    const absl::optional<AuthChallengeInfo>& auth_challenge) {
+    const std::optional<AuthChallengeInfo>& auth_challenge) {
   if (!auth_challenge) {
     return false;
   }
@@ -806,7 +806,7 @@
 
 #if defined(NTLM_PORTABLE)
 bool CheckNTLMServerAuth(
-    const absl::optional<AuthChallengeInfo>& auth_challenge) {
+    const std::optional<AuthChallengeInfo>& auth_challenge) {
   if (!auth_challenge) {
     return false;
   }
@@ -818,7 +818,7 @@
 }
 
 bool CheckNTLMProxyAuth(
-    const absl::optional<AuthChallengeInfo>& auth_challenge) {
+    const std::optional<AuthChallengeInfo>& auth_challenge) {
   if (!auth_challenge) {
     return false;
   }
@@ -13650,7 +13650,7 @@
 
   // Setup state in response_
   HttpResponseInfo* response = &trans.response_;
-  response->auth_challenge = absl::nullopt;
+  response->auth_challenge = std::nullopt;
   response->ssl_info.cert_status = static_cast<CertStatus>(-1);  // Nonsensical.
   response->response_time = base::Time::Now();
   response->was_cached = true;  // (Wouldn't ever actually be true...)
@@ -15906,7 +15906,7 @@
   EXPECT_THAT(rv, IsOk());
   const HttpResponseInfo* response = trans.GetResponseInfo();
   ASSERT_TRUE(response);
-  absl::optional<AuthChallengeInfo> challenge = response->auth_challenge;
+  std::optional<AuthChallengeInfo> challenge = response->auth_challenge;
   ASSERT_TRUE(challenge);
   EXPECT_FALSE(challenge->is_proxy);
   EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
@@ -19556,8 +19556,8 @@
         StaticSocketDataProvider data1;
         session_deps_.socket_factory->AddSocketDataProvider(&data1);
 
-        absl::optional<SSLSocketDataProvider> ssl_data2;
-        absl::optional<StaticSocketDataProvider> data2;
+        std::optional<SSLSocketDataProvider> ssl_data2;
+        std::optional<StaticSocketDataProvider> data2;
         MockRead error_in_read[] = {MockRead(ASYNC, reject_error)};
         if (reject_in_connect) {
           ssl_data2.emplace(ASYNC, reject_error);
@@ -19579,8 +19579,8 @@
 
         // If the handshake returns ERR_SSL_PROTOCOL_ERROR, we attempt to
         // connect twice.
-        absl::optional<SSLSocketDataProvider> ssl_data3;
-        absl::optional<StaticSocketDataProvider> data3;
+        std::optional<SSLSocketDataProvider> ssl_data3;
+        std::optional<StaticSocketDataProvider> data3;
         if (reject_in_connect && reject_error == ERR_SSL_PROTOCOL_ERROR) {
           ssl_data3.emplace(ASYNC, reject_error);
           data3.emplace();  // There are no reads or writes.
@@ -19789,7 +19789,7 @@
   // Preload mail.example.com into HostCache.
   rv = session_deps_.host_resolver->LoadIntoCache(
       HostPortPair("mail.example.com", 443), NetworkAnonymizationKey(),
-      absl::nullopt);
+      std::nullopt);
   EXPECT_THAT(rv, IsOk());
 
   HttpRequestInfo request2;
@@ -20569,7 +20569,7 @@
   // Preload mail.example.org into HostCache.
   int rv = session_deps_.host_resolver->LoadIntoCache(
       HostPortPair("mail.example.org", 443), NetworkAnonymizationKey(),
-      absl::nullopt);
+      std::nullopt);
   EXPECT_THAT(rv, IsOk());
 
   HttpRequestInfo request1;
@@ -20697,7 +20697,7 @@
   // Preload mail.example.org into HostCache.
   int rv = session_deps_.host_resolver->LoadIntoCache(
       HostPortPair("mail.example.org", 443), NetworkAnonymizationKey(),
-      absl::nullopt);
+      std::nullopt);
   EXPECT_THAT(rv, IsOk());
 
   HttpRequestInfo request1;
@@ -20973,7 +20973,7 @@
   // Preload cache entries into HostCache.
   rv = session_deps_.host_resolver->LoadIntoCache(
       HostPortPair("mail.example.com", 443), NetworkAnonymizationKey(),
-      absl::nullopt);
+      std::nullopt);
   EXPECT_THAT(rv, IsOk());
 
   HttpRequestInfo request2;
@@ -24244,7 +24244,7 @@
   // Preload mail.example.org into HostCache.
   int rv = session_deps_.host_resolver->LoadIntoCache(
       HostPortPair("mail.example.org", 443), NetworkAnonymizationKey(),
-      absl::nullopt);
+      std::nullopt);
   EXPECT_THAT(rv, IsOk());
 
   HttpRequestInfo request1;
diff --git a/net/http/http_no_vary_search_data.cc b/net/http/http_no_vary_search_data.cc
index 294ad4f..56c0f107 100644
--- a/net/http/http_no_vary_search_data.cc
+++ b/net/http/http_no_vary_search_data.cc
@@ -17,14 +17,14 @@
 
 namespace {
 // Tries to parse a list of ParameterizedItem as a list of strings.
-// Returns absl::nullopt if unsuccessful.
-absl::optional<std::vector<std::string>> ParseStringList(
+// Returns std::nullopt if unsuccessful.
+std::optional<std::vector<std::string>> ParseStringList(
     const std::vector<structured_headers::ParameterizedItem>& items) {
   std::vector<std::string> keys;
   keys.reserve(items.size());
   for (const auto& item : items) {
     if (!item.item.is_string()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     keys.push_back(UnescapePercentEncodedUrl(item.item.GetString()));
   }
diff --git a/net/http/http_proxy_connect_job.cc b/net/http/http_proxy_connect_job.cc
index e0d3b4c..d2fdacaf 100644
--- a/net/http/http_proxy_connect_job.cc
+++ b/net/http/http_proxy_connect_job.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "base/functional/bind.h"
@@ -44,7 +45,6 @@
 #include "net/spdy/spdy_session_pool.h"
 #include "net/spdy/spdy_stream.h"
 #include "net/ssl/ssl_cert_request_info.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
 #include "url/gurl.h"
 #include "url/scheme_host_port.h"
@@ -308,7 +308,7 @@
     return default_alternate_timeout;
   }
 
-  absl::optional<base::TimeDelta> http_rtt_estimate =
+  std::optional<base::TimeDelta> http_rtt_estimate =
       network_quality_estimator->GetHttpRTT();
   if (!http_rtt_estimate) {
     return default_alternate_timeout;
@@ -600,7 +600,7 @@
   }
 
   if (result == OK) {
-    SetSocket(std::move(transport_socket_), /*dns_aliases=*/absl::nullopt);
+    SetSocket(std::move(transport_socket_), /*dns_aliases=*/std::nullopt);
   }
 
   return result;
diff --git a/net/http/http_request_headers.cc b/net/http/http_request_headers.cc
index 981c1e3..86a7f92 100644
--- a/net/http/http_request_headers.cc
+++ b/net/http/http_request_headers.cc
@@ -26,7 +26,7 @@
 namespace {
 
 bool SupportsStreamType(
-    const absl::optional<base::flat_set<SourceStream::SourceType>>&
+    const std::optional<base::flat_set<SourceStream::SourceType>>&
         accepted_stream_types,
     SourceStream::SourceType type) {
   if (!accepted_stream_types)
@@ -243,7 +243,7 @@
 
 void HttpRequestHeaders::SetAcceptEncodingIfMissing(
     const GURL& url,
-    const absl::optional<base::flat_set<SourceStream::SourceType>>&
+    const std::optional<base::flat_set<SourceStream::SourceType>>&
         accepted_stream_types,
     bool enable_brotli,
     bool enable_zstd) {
diff --git a/net/http/http_request_headers.h b/net/http/http_request_headers.h
index fe6e754..9cfe1466 100644
--- a/net/http/http_request_headers.h
+++ b/net/http/http_request_headers.h
@@ -11,6 +11,7 @@
 #define NET_HTTP_HTTP_REQUEST_HEADERS_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -20,7 +21,6 @@
 #include "net/base/net_export.h"
 #include "net/filter/source_stream.h"
 #include "net/log/net_log_capture_mode.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace net {
@@ -196,7 +196,7 @@
   // it does not exist. "br" is appended only when `enable_brotli` is true.
   void SetAcceptEncodingIfMissing(
       const GURL& url,
-      const absl::optional<base::flat_set<SourceStream::SourceType>>&
+      const std::optional<base::flat_set<SourceStream::SourceType>>&
           accepted_stream_types,
       bool enable_brotli,
       bool enable_zstd);
diff --git a/net/http/http_request_info.h b/net/http/http_request_info.h
index e318ba4..3d445e45 100644
--- a/net/http/http_request_info.h
+++ b/net/http/http_request_info.h
@@ -5,6 +5,7 @@
 #ifndef NET_HTTP_HTTP_REQUEST_INFO_H__
 #define NET_HTTP_HTTP_REQUEST_INFO_H__
 
+#include <optional>
 #include <string>
 
 #include "base/memory/raw_ptr.h"
@@ -18,7 +19,6 @@
 #include "net/http/http_request_headers.h"
 #include "net/socket/socket_tag.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -97,11 +97,11 @@
   // TODO(https://crbug.com/1136054): Investigate migrating the one consumer of
   // this to NetworkIsolationKey::TopFrameSite().  That gives more consistent
   /// behavior, and may still provide useful metrics.
-  absl::optional<url::Origin> possibly_top_frame_origin;
+  std::optional<url::Origin> possibly_top_frame_origin;
 
   // The frame origin associated with a request. This is used to isolate shared
   // dictionaries between different frame origins.
-  absl::optional<url::Origin> frame_origin;
+  std::optional<url::Origin> frame_origin;
 
   // Idempotency of the request, which determines that if it is safe to enable
   // 0-RTT for the request. By default, 0-RTT is only enabled for safe
@@ -115,11 +115,11 @@
   // If not null, the value is used to evaluate whether the cache entry should
   // be bypassed; if is null, that means the request site does not match the
   // filter.
-  absl::optional<int64_t> fps_cache_filter;
+  std::optional<int64_t> fps_cache_filter;
 
   // Use as ID to mark the cache entry when persisting. Should be a positive
   // number once set.
-  absl::optional<int64_t> browser_run_id;
+  std::optional<int64_t> browser_run_id;
 };
 
 }  // namespace net
diff --git a/net/http/http_response_headers_unittest.cc b/net/http/http_response_headers_unittest.cc
index 62597185..efebb2da 100644
--- a/net/http/http_response_headers_unittest.cc
+++ b/net/http/http_response_headers_unittest.cc
@@ -2342,7 +2342,7 @@
 
 struct MaxAgeTestData {
   const char* max_age_string;
-  const absl::optional<int64_t> expected_seconds;
+  const std::optional<int64_t> expected_seconds;
 };
 
 class MaxAgeEdgeCasesTest
@@ -2366,15 +2366,15 @@
 
 const MaxAgeTestData max_age_tests[] = {
     {" 1 ", 1},  // Spaces are ignored.
-    {"-1", absl::nullopt},
-    {"--1", absl::nullopt},
-    {"2s", absl::nullopt},
-    {"3 days", absl::nullopt},
-    {"'4'", absl::nullopt},
-    {"\"5\"", absl::nullopt},
-    {"0x6", absl::nullopt},  // Hex not parsed as hex.
-    {"7F", absl::nullopt},   // Hex without 0x still not parsed as hex.
-    {"010", 10},             // Octal not parsed as octal.
+    {"-1", std::nullopt},
+    {"--1", std::nullopt},
+    {"2s", std::nullopt},
+    {"3 days", std::nullopt},
+    {"'4'", std::nullopt},
+    {"\"5\"", std::nullopt},
+    {"0x6", std::nullopt},  // Hex not parsed as hex.
+    {"7F", std::nullopt},   // Hex without 0x still not parsed as hex.
+    {"010", 10},            // Octal not parsed as octal.
     {"9223372036853", 9223372036853},
     {"9223372036854", 9223372036854},
     {"9223372036855", 9223372036854},
diff --git a/net/http/http_response_info.cc b/net/http/http_response_info.cc
index adaa2e4..fdbf5f0c 100644
--- a/net/http/http_response_info.cc
+++ b/net/http/http_response_info.cc
@@ -4,6 +4,8 @@
 
 #include "net/http/http_response_info.h"
 
+#include <optional>
+
 #include "base/logging.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/pickle.h"
@@ -16,7 +18,6 @@
 #include "net/ssl/ssl_cert_request_info.h"
 #include "net/ssl/ssl_connection_status_flags.h"
 #include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/include/openssl/ssl.h"
 
 using base::Time;
@@ -348,7 +349,7 @@
     int64_t id;
     if (!iter.ReadInt64(&id))
       return false;
-    browser_run_id = absl::make_optional(id);
+    browser_run_id = std::make_optional(id);
   }
 
   did_use_shared_dictionary =
diff --git a/net/http/http_response_info.h b/net/http/http_response_info.h
index 43330b3..d4c56c2 100644
--- a/net/http/http_response_info.h
+++ b/net/http/http_response_info.h
@@ -5,6 +5,7 @@
 #ifndef NET_HTTP_HTTP_RESPONSE_INFO_H_
 #define NET_HTTP_HTTP_RESPONSE_INFO_H_
 
+#include <optional>
 #include <set>
 #include <string>
 
@@ -18,7 +19,6 @@
 #include "net/http/http_connection_info.h"
 #include "net/http/http_vary_data.h"
 #include "net/ssl/ssl_info.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class Pickle;
@@ -181,7 +181,7 @@
 
   // If the response headers indicate a 401 or 407 failure, then this structure
   // will contain additional information about the authentication challenge.
-  absl::optional<AuthChallengeInfo> auth_challenge;
+  std::optional<AuthChallengeInfo> auth_challenge;
 
   // The SSL client certificate request info.
   // TODO(wtc): does this really belong in HttpResponseInfo?  I put it here
@@ -209,7 +209,7 @@
 
   // If not null, this indicates the response is stored during a certain browser
   // session. Used for filtering cache access.
-  absl::optional<int64_t> browser_run_id;
+  std::optional<int64_t> browser_run_id;
 
   // True if the response used a shared dictionary for decoding its body.
   bool did_use_shared_dictionary = false;
diff --git a/net/http/http_response_info_unittest.cc b/net/http/http_response_info_unittest.cc
index 2258d1b..f27f91e 100644
--- a/net/http/http_response_info_unittest.cc
+++ b/net/http/http_response_info_unittest.cc
@@ -271,7 +271,7 @@
 
 // Test that an empty `browser_run_id` is preserved and doesn't throw an error.
 TEST_F(HttpResponseInfoTest, EmptyBrowserRunId) {
-  response_info_.browser_run_id = absl::nullopt;
+  response_info_.browser_run_id = std::nullopt;
   net::HttpResponseInfo restored_response_info;
   PickleAndRestore(response_info_, &restored_response_info);
   EXPECT_FALSE(restored_response_info.browser_run_id.has_value());
diff --git a/net/http/http_server_properties.cc b/net/http/http_server_properties.cc
index 455d55f..827ea33 100644
--- a/net/http/http_server_properties.cc
+++ b/net/http/http_server_properties.cc
@@ -573,8 +573,8 @@
 }
 
 void HttpServerProperties::SetBrokenAlternativeServicesDelayParams(
-    absl::optional<base::TimeDelta> initial_delay,
-    absl::optional<bool> exponential_backoff_on_initial_delay) {
+    std::optional<base::TimeDelta> initial_delay,
+    std::optional<bool> exponential_backoff_on_initial_delay) {
   broken_alternative_services_.SetDelayParams(
       initial_delay, exponential_backoff_on_initial_delay);
 }
diff --git a/net/http/http_server_properties.h b/net/http/http_server_properties.h
index 71b7fe96..0f58324 100644
--- a/net/http/http_server_properties.h
+++ b/net/http/http_server_properties.h
@@ -10,6 +10,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <tuple>
@@ -34,7 +35,6 @@
 #include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
 #include "net/third_party/quiche/src/quiche/spdy/core/spdy_framer.h"  // TODO(willchan): Reconsider this.
 #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/scheme_host_port.h"
 
 namespace base {
@@ -150,14 +150,14 @@
     // indicates unknown. The difference between false and not set only matters
     // when loading from disk, when an initialized false value will take
     // priority over a not set value.
-    absl::optional<bool> supports_spdy;
+    std::optional<bool> supports_spdy;
 
     // True if the server has previously indicated it required HTTP/1.1. Unlike
     // other fields, not persisted to disk.
-    absl::optional<bool> requires_http11;
+    std::optional<bool> requires_http11;
 
-    absl::optional<AlternativeServiceInfoVector> alternative_services;
-    absl::optional<ServerNetworkStats> server_network_stats;
+    std::optional<AlternativeServiceInfoVector> alternative_services;
+    std::optional<ServerNetworkStats> server_network_stats;
   };
 
   struct NET_EXPORT ServerInfoMapKey {
@@ -427,8 +427,8 @@
   // exponential_backoff_on_initial_delay which are used to calculate delay of
   // broken alternative services.
   void SetBrokenAlternativeServicesDelayParams(
-      absl::optional<base::TimeDelta> initial_delay,
-      absl::optional<bool> exponential_backoff_on_initial_delay);
+      std::optional<base::TimeDelta> initial_delay,
+      std::optional<bool> exponential_backoff_on_initial_delay);
 
   // Returns whether HttpServerProperties is initialized.
   bool IsInitialized() const;
diff --git a/net/http/http_server_properties_manager.cc b/net/http/http_server_properties_manager.cc
index 3457831..9833d9c62 100644
--- a/net/http/http_server_properties_manager.cc
+++ b/net/http/http_server_properties_manager.cc
@@ -5,6 +5,7 @@
 #include "net/http/http_server_properties_manager.h"
 
 #include <algorithm>
+#include <optional>
 #include <utility>
 
 #include "base/containers/adapters.h"
@@ -23,7 +24,6 @@
 #include "net/base/privacy_mode.h"
 #include "net/http/http_server_properties.h"
 #include "net/third_party/quiche/src/quiche/quic/platform/api/quic_hostname_utils.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/scheme_host_port.h"
 
@@ -69,7 +69,7 @@
 // services. Also checks if an alternative service for the same canonical suffix
 // has already been saved, and if so, returns an empty list.
 AlternativeServiceInfoVector GetAlternativeServiceToPersist(
-    const absl::optional<AlternativeServiceInfoVector>& alternative_services,
+    const std::optional<AlternativeServiceInfoVector>& alternative_services,
     const HttpServerProperties::ServerInfoMapKey& server_info_key,
     base::Time now,
     const HttpServerPropertiesManager::GetCannonicalSuffix&
@@ -233,7 +233,7 @@
 
   net_log_.AddEvent(NetLogEventType::HTTP_SERVER_PROPERTIES_UPDATE_CACHE,
                     [&] { return http_server_properties_dict.Clone(); });
-  absl::optional<int> maybe_version_number =
+  std::optional<int> maybe_version_number =
       http_server_properties_dict.FindInt(kVersionKey);
   if (!maybe_version_number.has_value() ||
       *maybe_version_number != kVersionNumber) {
@@ -354,7 +354,7 @@
   // Read broken-count and add an entry for |alt_service| into
   // |recently_broken_alternative_services|.
   if (broken_alt_svc_entry_dict.Find(kBrokenCountKey)) {
-    absl::optional<int> broken_count =
+    std::optional<int> broken_count =
         broken_alt_svc_entry_dict.FindInt(kBrokenCountKey);
     if (!broken_count.has_value()) {
       DVLOG(1) << "Recently broken alternative service has malformed "
@@ -478,7 +478,7 @@
   alternative_service->host = host;
 
   // Port is mandatory.
-  absl::optional<int> maybe_port = dict.FindInt(kPortKey);
+  std::optional<int> maybe_port = dict.FindInt(kPortKey);
   if (!maybe_port.has_value() || !IsPortValid(maybe_port.value())) {
     DVLOG(1) << "Malformed alternative service port under: " << parsing_under;
     return false;
@@ -618,7 +618,7 @@
   if (!server_network_stats_dict) {
     return;
   }
-  absl::optional<int> maybe_srtt = server_network_stats_dict->FindInt(kSrttKey);
+  std::optional<int> maybe_srtt = server_network_stats_dict->FindInt(kSrttKey);
   if (!maybe_srtt.has_value()) {
     DVLOG(1) << "Malformed ServerNetworkStats for server: "
              << server.Serialize();
diff --git a/net/http/http_stream.cc b/net/http/http_stream.cc
index d1e6ace..9089df0 100644
--- a/net/http/http_stream.cc
+++ b/net/http/http_stream.cc
@@ -6,13 +6,13 @@
 
 namespace net {
 
-absl::optional<quic::QuicErrorCode> HttpStream::GetQuicErrorCode() const {
-  return absl::nullopt;
+std::optional<quic::QuicErrorCode> HttpStream::GetQuicErrorCode() const {
+  return std::nullopt;
 }
 
-absl::optional<quic::QuicRstStreamErrorCode>
+std::optional<quic::QuicRstStreamErrorCode>
 HttpStream::GetQuicRstStreamErrorCode() const {
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace net
diff --git a/net/http/http_stream.h b/net/http/http_stream.h
index 7e37392..3b0a1d0 100644
--- a/net/http/http_stream.h
+++ b/net/http/http_stream.h
@@ -14,6 +14,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <set>
 
 #include "base/strings/string_piece.h"
@@ -25,7 +26,6 @@
 #include "net/base/request_priority.h"
 #include "net/http/http_raw_request_headers.h"
 #include "net/third_party/quiche/src/quiche/quic/core/quic_error_codes.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -216,11 +216,11 @@
 
   // If `this` is using a Quic stream, set the `connection_error` of the Quic
   // stream. Otherwise returns nullopt.
-  virtual absl::optional<quic::QuicErrorCode> GetQuicErrorCode() const;
+  virtual std::optional<quic::QuicErrorCode> GetQuicErrorCode() const;
 
   // If `this` is using a Quic stream, set the `stream_error' status of the Quic
   // stream. Otherwise returns nullopt.
-  virtual absl::optional<quic::QuicRstStreamErrorCode>
+  virtual std::optional<quic::QuicRstStreamErrorCode>
   GetQuicRstStreamErrorCode() const;
 };
 
diff --git a/net/http/http_stream_factory_job_controller_unittest.cc b/net/http/http_stream_factory_job_controller_unittest.cc
index bf56fa0..94eb517 100644
--- a/net/http/http_stream_factory_job_controller_unittest.cc
+++ b/net/http/http_stream_factory_job_controller_unittest.cc
@@ -4980,7 +4980,7 @@
     url::SchemeHostPort scheme_host_port(
         url::kHttpsScheme,
         alt_destination ? "alt.example.org" : "www.example.org", 443);
-    absl::optional<int> quic_request_result;
+    std::optional<int> quic_request_result;
 
     CHECK_EQ(ERR_IO_PENDING,
              quic_request.Request(
diff --git a/net/http/http_stream_factory_unittest.cc b/net/http/http_stream_factory_unittest.cc
index 77d5e78..5a867f7 100644
--- a/net/http/http_stream_factory_unittest.cc
+++ b/net/http/http_stream_factory_unittest.cc
@@ -88,10 +88,11 @@
 // This file can be included from net/http even though
 // it is in net/websockets because it doesn't
 // introduce any link dependency to net/websockets.
+#include <optional>
+
 #include "net/websockets/websocket_handshake_stream_base.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/scheme_host_port.h"
 #include "url/url_constants.h"
@@ -446,7 +447,7 @@
   int RequestSocket(
       const ClientSocketPool::GroupId& group_id,
       scoped_refptr<ClientSocketPool::SocketParams> socket_params,
-      const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+      const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
       RequestPriority priority,
       const SocketTag& socket_tag,
       ClientSocketPool::RespectLimits respect_limits,
@@ -461,7 +462,7 @@
   int RequestSockets(
       const ClientSocketPool::GroupId& group_id,
       scoped_refptr<ClientSocketPool::SocketParams> socket_params,
-      const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+      const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
       int num_sockets,
       CompletionOnceCallback callback,
       const NetLogWithSource& net_log) override {
@@ -1783,7 +1784,7 @@
         NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
         /*disable_cert_network_fetches=*/false);
     int rv = connection->Init(
-        group_id, socket_params, absl::nullopt /* proxy_annotation_tag */,
+        group_id, socket_params, std::nullopt /* proxy_annotation_tag */,
         MEDIUM, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
         callback.callback(), ClientSocketPool::ProxyAuthCallback(),
         session->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
diff --git a/net/http/http_transaction_test_util.cc b/net/http/http_transaction_test_util.cc
index a1d296f4..2264be8 100644
--- a/net/http/http_transaction_test_util.cc
+++ b/net/http/http_transaction_test_util.cc
@@ -65,8 +65,8 @@
     base::Time(),
     "<html><body>Google Blah Blah</body></html>",
     {},
-    absl::nullopt,
-    absl::nullopt,
+    std::nullopt,
+    std::nullopt,
     TEST_MODE_NORMAL,
     MockTransactionHandler(),
     MockTransactionReadHandler(),
@@ -89,8 +89,8 @@
     base::Time(),
     "<html><body>Google Blah Blah</body></html>",
     {},
-    absl::nullopt,
-    absl::nullopt,
+    std::nullopt,
+    std::nullopt,
     TEST_MODE_NORMAL,
     MockTransactionHandler(),
     MockTransactionReadHandler(),
@@ -114,8 +114,8 @@
     base::Time(),
     "<html><body>Google Blah Blah</body></html>",
     {},
-    absl::nullopt,
-    absl::nullopt,
+    std::nullopt,
+    std::nullopt,
     TEST_MODE_NORMAL,
     MockTransactionHandler(),
     MockTransactionReadHandler(),
@@ -139,8 +139,8 @@
     base::Time(),
     "<html><body>Google Blah Blah</body></html>",
     {},
-    absl::nullopt,
-    absl::nullopt,
+    std::nullopt,
+    std::nullopt,
     TEST_MODE_NORMAL,
     MockTransactionHandler(),
     MockTransactionReadHandler(),
@@ -163,8 +163,8 @@
     base::Time(),
     "<html><body>Google Blah Blah</body></html>",
     {},
-    absl::nullopt,
-    absl::nullopt,
+    std::nullopt,
+    std::nullopt,
     TEST_MODE_NORMAL,
     MockTransactionHandler(),
     MockTransactionReadHandler(),
diff --git a/net/http/http_transaction_test_util.h b/net/http/http_transaction_test_util.h
index 80e69582..42d99dab 100644
--- a/net/http/http_transaction_test_util.h
+++ b/net/http/http_transaction_test_util.h
@@ -5,17 +5,16 @@
 #ifndef NET_HTTP_HTTP_TRANSACTION_TEST_UTIL_H_
 #define NET_HTTP_HTTP_TRANSACTION_TEST_UTIL_H_
 
-#include "base/memory/raw_ptr.h"
-#include "net/http/http_transaction.h"
-
 #include <stdint.h>
 
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
 
 #include "base/compiler_specific.h"
 #include "base/functional/callback.h"
+#include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
@@ -33,9 +32,9 @@
 #include "net/http/http_request_info.h"
 #include "net/http/http_response_headers.h"
 #include "net/http/http_response_info.h"
+#include "net/http/http_transaction.h"
 #include "net/log/net_log_source.h"
 #include "net/socket/connection_attempts.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -92,8 +91,8 @@
   // known aliases, e.g. from A, AAAA, or HTTPS, not just from the address used
   // for the connection, in no particular order.
   std::set<std::string> dns_aliases;
-  absl::optional<int64_t> fps_cache_filter;
-  absl::optional<int64_t> browser_run_id;
+  std::optional<int64_t> fps_cache_filter;
+  std::optional<int64_t> browser_run_id;
   int test_mode;
   MockTransactionHandler handler;
   MockTransactionReadHandler read_handler;
diff --git a/net/http/http_transaction_test_util_unittest.cc b/net/http/http_transaction_test_util_unittest.cc
index c6b3b8b..6832922 100644
--- a/net/http/http_transaction_test_util_unittest.cc
+++ b/net/http/http_transaction_test_util_unittest.cc
@@ -34,8 +34,8 @@
     .response_time = base::Time(),
     .data = "<html><body>Hello world!</body></html>",
     .dns_aliases = {},
-    .fps_cache_filter = absl::nullopt,
-    .browser_run_id = absl::nullopt,
+    .fps_cache_filter = std::nullopt,
+    .browser_run_id = std::nullopt,
     .test_mode = TEST_MODE_NORMAL,
     .handler = MockTransactionHandler(),
     .read_handler = MockTransactionReadHandler(),
diff --git a/net/http/structured_headers.h b/net/http/structured_headers.h
index 77c7a24c..eee38ae 100644
--- a/net/http/structured_headers.h
+++ b/net/http/structured_headers.h
@@ -5,11 +5,11 @@
 #ifndef NET_HTTP_STRUCTURED_HEADERS_H_
 #define NET_HTTP_STRUCTURED_HEADERS_H_
 
+#include <optional>
 #include <string>
 
 #include "base/strings/string_piece.h"
 #include "net/third_party/quiche/src/quiche/common/structured_headers.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net::structured_headers {
 
@@ -25,38 +25,37 @@
 using List = quiche::structured_headers::List;
 using Parameters = quiche::structured_headers::Parameters;
 
-inline absl::optional<ParameterizedItem> ParseItem(base::StringPiece str) {
+inline std::optional<ParameterizedItem> ParseItem(base::StringPiece str) {
   return quiche::structured_headers::ParseItem(str);
 }
-inline absl::optional<Item> ParseBareItem(base::StringPiece str) {
+inline std::optional<Item> ParseBareItem(base::StringPiece str) {
   return quiche::structured_headers::ParseBareItem(str);
 }
-inline absl::optional<ParameterisedList> ParseParameterisedList(
+inline std::optional<ParameterisedList> ParseParameterisedList(
     base::StringPiece str) {
   return quiche::structured_headers::ParseParameterisedList(str);
 }
-inline absl::optional<ListOfLists> ParseListOfLists(base::StringPiece str) {
+inline std::optional<ListOfLists> ParseListOfLists(base::StringPiece str) {
   return quiche::structured_headers::ParseListOfLists(str);
 }
-inline absl::optional<List> ParseList(base::StringPiece str) {
+inline std::optional<List> ParseList(base::StringPiece str) {
   return quiche::structured_headers::ParseList(str);
 }
-inline absl::optional<Dictionary> ParseDictionary(base::StringPiece str) {
+inline std::optional<Dictionary> ParseDictionary(base::StringPiece str) {
   return quiche::structured_headers::ParseDictionary(str);
 }
 
-inline absl::optional<std::string> SerializeItem(const Item& value) {
+inline std::optional<std::string> SerializeItem(const Item& value) {
   return quiche::structured_headers::SerializeItem(value);
 }
-inline absl::optional<std::string> SerializeItem(
+inline std::optional<std::string> SerializeItem(
     const ParameterizedItem& value) {
   return quiche::structured_headers::SerializeItem(value);
 }
-inline absl::optional<std::string> SerializeList(const List& value) {
+inline std::optional<std::string> SerializeList(const List& value) {
   return quiche::structured_headers::SerializeList(value);
 }
-inline absl::optional<std::string> SerializeDictionary(
-    const Dictionary& value) {
+inline std::optional<std::string> SerializeDictionary(const Dictionary& value) {
   return quiche::structured_headers::SerializeDictionary(value);
 }
 
diff --git a/net/http/transport_security_persister.cc b/net/http/transport_security_persister.cc
index 264e010..c75538d6 100644
--- a/net/http/transport_security_persister.cc
+++ b/net/http/transport_security_persister.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -26,7 +27,6 @@
 #include "net/base/network_anonymization_key.h"
 #include "net/cert/x509_certificate.h"
 #include "net/http/transport_security_state.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -41,12 +41,12 @@
 
 // This inverts |HashedDomainToExternalString|, above. It turns an external
 // string (from a JSON file) into an internal (binary) array.
-absl::optional<TransportSecurityState::HashedHost> ExternalStringToHashedDomain(
+std::optional<TransportSecurityState::HashedHost> ExternalStringToHashedDomain(
     const std::string& external) {
   TransportSecurityState::HashedHost out;
-  absl::optional<std::vector<uint8_t>> hashed = base::Base64Decode(external);
+  std::optional<std::vector<uint8_t>> hashed = base::Base64Decode(external);
   if (!hashed.has_value() || hashed.value().size() != out.size()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::copy_n(hashed.value().begin(), out.size(), out.begin());
@@ -135,10 +135,10 @@
       continue;
 
     const std::string* hostname = sts_dict->FindString(kHostname);
-    absl::optional<bool> sts_include_subdomains =
+    std::optional<bool> sts_include_subdomains =
         sts_dict->FindBool(kStsIncludeSubdomains);
-    absl::optional<double> sts_observed = sts_dict->FindDouble(kStsObserved);
-    absl::optional<double> expiry = sts_dict->FindDouble(kExpiry);
+    std::optional<double> sts_observed = sts_dict->FindDouble(kStsObserved);
+    std::optional<double> expiry = sts_dict->FindDouble(kExpiry);
     const std::string* mode = sts_dict->FindString(kMode);
 
     if (!hostname || !sts_include_subdomains.has_value() ||
@@ -164,7 +164,7 @@
     if (sts_state.expiry < current_time || !sts_state.ShouldUpgradeToSSL())
       continue;
 
-    absl::optional<TransportSecurityState::HashedHost> hashed =
+    std::optional<TransportSecurityState::HashedHost> hashed =
         ExternalStringToHashedDomain(*hostname);
     if (!hashed.has_value())
       continue;
@@ -224,7 +224,7 @@
           &OnWriteFinishedTask, foreground_runner_,
           base::BindOnce(&TransportSecurityPersister::OnWriteFinished,
                          weak_ptr_factory_.GetWeakPtr(), std::move(callback))));
-  absl::optional<std::string> data = SerializeData();
+  std::optional<std::string> data = SerializeData();
   if (data) {
     writer_.WriteNow(std::move(data).value());
   } else {
@@ -237,7 +237,7 @@
   std::move(callback).Run();
 }
 
-absl::optional<std::string> TransportSecurityPersister::SerializeData() {
+std::optional<std::string> TransportSecurityPersister::SerializeData() {
   CHECK(foreground_runner_->RunsTasksInCurrentSequence());
 
   base::Value::Dict toplevel;
@@ -246,7 +246,7 @@
 
   std::string output;
   if (!base::JSONWriter::Write(toplevel, &output)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return output;
 }
@@ -267,12 +267,12 @@
     const std::string& serialized,
     TransportSecurityState* state,
     bool& contains_legacy_expect_ct_data) {
-  absl::optional<base::Value> value = base::JSONReader::Read(serialized);
+  std::optional<base::Value> value = base::JSONReader::Read(serialized);
   if (!value || !value->is_dict())
     return;
 
   base::Value::Dict& dict = value->GetDict();
-  absl::optional<int> version = dict.FindInt(kVersionKey);
+  std::optional<int> version = dict.FindInt(kVersionKey);
 
   // Stop if the data is out of date (or in the previous format that didn't have
   // a version number).
diff --git a/net/http/transport_security_persister.h b/net/http/transport_security_persister.h
index 3a7c345..96033d9 100644
--- a/net/http/transport_security_persister.h
+++ b/net/http/transport_security_persister.h
@@ -33,6 +33,7 @@
 #ifndef NET_HTTP_TRANSPORT_SECURITY_PERSISTER_H_
 #define NET_HTTP_TRANSPORT_SECURITY_PERSISTER_H_
 
+#include <optional>
 #include <string>
 
 #include "base/files/file_path.h"
@@ -42,7 +43,6 @@
 #include "base/memory/weak_ptr.h"
 #include "net/base/net_export.h"
 #include "net/http/transport_security_state.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class SequencedTaskRunner;
@@ -113,7 +113,7 @@
   // The reason for hashing them is so that the stored state does not
   // trivially reveal a user's browsing history to an attacker reading the
   // serialized state on disk.
-  absl::optional<std::string> SerializeData() override;
+  std::optional<std::string> SerializeData() override;
 
   // Clears any existing non-static entries, and then re-populates
   // |transport_security_state_|.
diff --git a/net/http/transport_security_persister_unittest.cc b/net/http/transport_security_persister_unittest.cc
index 061f000e..e3b66d3 100644
--- a/net/http/transport_security_persister_unittest.cc
+++ b/net/http/transport_security_persister_unittest.cc
@@ -92,12 +92,12 @@
 // Tests that serializing -> deserializing -> reserializing results in the same
 // output.
 TEST_F(TransportSecurityPersisterTest, SerializeData1) {
-  absl::optional<std::string> output = persister_->SerializeData();
+  std::optional<std::string> output = persister_->SerializeData();
 
   ASSERT_TRUE(output);
   persister_->LoadEntries(*output);
 
-  absl::optional<std::string> output2 = persister_->SerializeData();
+  std::optional<std::string> output2 = persister_->SerializeData();
   ASSERT_TRUE(output2);
   EXPECT_EQ(output, output2);
 }
@@ -113,7 +113,7 @@
   bool include_subdomains = true;
   state_->AddHSTS(kYahooDomain, expiry, include_subdomains);
 
-  absl::optional<std::string> output = persister_->SerializeData();
+  std::optional<std::string> output = persister_->SerializeData();
   ASSERT_TRUE(output);
   persister_->LoadEntries(*output);
 
@@ -150,7 +150,7 @@
     sts_iter.Advance();
   }
 
-  absl::optional<std::string> serialized = persister_->SerializeData();
+  std::optional<std::string> serialized = persister_->SerializeData();
   ASSERT_TRUE(serialized);
 
   // Persist the data to the file.
diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc
index d460061..3f54000 100644
--- a/net/http/transport_security_state.cc
+++ b/net/http/transport_security_state.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <tuple>
 #include <utility>
 #include <vector>
@@ -40,7 +41,6 @@
 #include "net/http/http_security_headers.h"
 #include "net/net_buildflags.h"
 #include "net/ssl/ssl_info.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -94,7 +94,7 @@
   // invalid characters in the host (via DNSDomainFromDot()).
   std::string lowered_host = base::ToLowerASCII(host);
 
-  absl::optional<std::vector<uint8_t>> new_host =
+  std::optional<std::vector<uint8_t>> new_host =
       dns_names_util::DottedNameToNetwork(
           lowered_host,
           /*require_valid_internet_hostname=*/true);
@@ -772,7 +772,7 @@
     // An entry matches if it is either an exact match, or if it is a prefix
     // match and the includeSubDomains directive was included.
     if (i == 0 || j->second.include_subdomains) {
-      absl::optional<std::string> dotted_name =
+      std::optional<std::string> dotted_name =
           dns_names_util::NetworkToDottedName(host_sub_chunk);
       if (!dotted_name)
         return false;
@@ -818,7 +818,7 @@
     // implement HPKP, so this logic is only used via AddHPKP(), reachable from
     // Cronet.
     if (i == 0 || j->second.include_subdomains) {
-      absl::optional<std::string> dotted_name =
+      std::optional<std::string> dotted_name =
           dns_names_util::NetworkToDottedName(host_sub_chunk);
       if (!dotted_name)
         return false;
diff --git a/net/http/transport_security_state.h b/net/http/transport_security_state.h
index b2d08581..cc4c850 100644
--- a/net/http/transport_security_state.h
+++ b/net/http/transport_security_state.h
@@ -9,6 +9,7 @@
 
 #include <array>
 #include <map>
+#include <optional>
 #include <set>
 #include <string>
 
@@ -28,7 +29,6 @@
 #include "net/cert/signed_certificate_timestamp_and_status.h"
 #include "net/http/transport_security_state_source.h"
 #include "net/log/net_log_with_source.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace net {
@@ -522,7 +522,7 @@
 
   // The values in host_pins_ maps are references to PinSet objects in the
   // pinsets_ vector.
-  absl::optional<
+  std::optional<
       std::map<std::string, std::pair<const PinSet*, bool>, std::less<>>>
       host_pins_;
   base::Time key_pins_list_last_update_time_;
diff --git a/net/log/file_net_log_observer.cc b/net/log/file_net_log_observer.cc
index 45ffa43..95b88bb 100644
--- a/net/log/file_net_log_observer.cc
+++ b/net/log/file_net_log_observer.cc
@@ -201,7 +201,7 @@
   // If max_event_file_size == kNoLimit, then no limit is enforced.
   FileWriter(const base::FilePath& log_path,
              const base::FilePath& inprogress_dir_path,
-             absl::optional<base::File> pre_existing_log_file,
+             std::optional<base::File> pre_existing_log_file,
              uint64_t max_event_file_size,
              size_t total_num_event_files,
              scoped_refptr<base::SequencedTaskRunner> task_runner);
@@ -338,7 +338,7 @@
     NetLogCaptureMode capture_mode,
     std::unique_ptr<base::Value::Dict> constants) {
   return CreateInternal(log_path, SiblingInprogressDirectory(log_path),
-                        absl::nullopt, max_total_size, kDefaultNumFiles,
+                        std::nullopt, max_total_size, kDefaultNumFiles,
                         capture_mode, std::move(constants));
 }
 
@@ -346,7 +346,7 @@
     const base::FilePath& log_path,
     NetLogCaptureMode capture_mode,
     std::unique_ptr<base::Value::Dict> constants) {
-  return CreateInternal(log_path, base::FilePath(), absl::nullopt, kNoLimit,
+  return CreateInternal(log_path, base::FilePath(), std::nullopt, kNoLimit,
                         kDefaultNumFiles, capture_mode, std::move(constants));
 }
 
@@ -358,7 +358,7 @@
     NetLogCaptureMode capture_mode,
     std::unique_ptr<base::Value::Dict> constants) {
   return CreateInternal(base::FilePath(), inprogress_dir_path,
-                        absl::make_optional<base::File>(std::move(output_file)),
+                        std::make_optional<base::File>(std::move(output_file)),
                         max_total_size, kDefaultNumFiles, capture_mode,
                         std::move(constants));
 }
@@ -369,7 +369,7 @@
     NetLogCaptureMode capture_mode,
     std::unique_ptr<base::Value::Dict> constants) {
   return CreateInternal(base::FilePath(), base::FilePath(),
-                        absl::make_optional<base::File>(std::move(output_file)),
+                        std::make_optional<base::File>(std::move(output_file)),
                         kNoLimit, kDefaultNumFiles, capture_mode,
                         std::move(constants));
 }
@@ -435,14 +435,14 @@
     NetLogCaptureMode capture_mode,
     std::unique_ptr<base::Value::Dict> constants) {
   return CreateInternal(log_path, SiblingInprogressDirectory(log_path),
-                        absl::nullopt, max_total_size, total_num_event_files,
+                        std::nullopt, max_total_size, total_num_event_files,
                         capture_mode, std::move(constants));
 }
 
 std::unique_ptr<FileNetLogObserver> FileNetLogObserver::CreateInternal(
     const base::FilePath& log_path,
     const base::FilePath& inprogress_dir_path,
-    absl::optional<base::File> pre_existing_log_file,
+    std::optional<base::File> pre_existing_log_file,
     uint64_t max_total_size,
     size_t total_num_event_files,
     NetLogCaptureMode capture_mode,
@@ -547,7 +547,7 @@
 FileNetLogObserver::FileWriter::FileWriter(
     const base::FilePath& log_path,
     const base::FilePath& inprogress_dir_path,
-    absl::optional<base::File> pre_existing_log_file,
+    std::optional<base::File> pre_existing_log_file,
     uint64_t max_event_file_size,
     size_t total_num_event_files,
     scoped_refptr<base::SequencedTaskRunner> task_runner)
diff --git a/net/log/file_net_log_observer.h b/net/log/file_net_log_observer.h
index cba2390..5ae249a 100644
--- a/net/log/file_net_log_observer.h
+++ b/net/log/file_net_log_observer.h
@@ -7,6 +7,7 @@
 
 #include <limits>
 #include <memory>
+#include <optional>
 
 #include "base/files/file.h"
 #include "base/functional/callback.h"
@@ -14,7 +15,6 @@
 #include "base/values.h"
 #include "net/base/net_export.h"
 #include "net/log/net_log.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class FilePath;
@@ -130,7 +130,7 @@
   static std::unique_ptr<FileNetLogObserver> CreateInternal(
       const base::FilePath& log_path,
       const base::FilePath& inprogress_dir_path,
-      absl::optional<base::File> pre_existing_out_file,
+      std::optional<base::File> pre_existing_out_file,
       uint64_t max_total_size,
       size_t total_num_event_files,
       NetLogCaptureMode capture_mode,
diff --git a/net/log/file_net_log_observer_unittest.cc b/net/log/file_net_log_observer_unittest.cc
index 9c13b8f..5c08c43 100644
--- a/net/log/file_net_log_observer_unittest.cc
+++ b/net/log/file_net_log_observer_unittest.cc
@@ -193,7 +193,7 @@
 
     size_t expected_source_id = num_events_emitted - num_events_saved + i;
 
-    absl::optional<int> id_value = event->FindIntByDottedPath("source.id");
+    std::optional<int> id_value = event->FindIntByDottedPath("source.id");
     ASSERT_EQ(static_cast<int>(expected_source_id), id_value);
   }
 }
diff --git a/net/log/net_log_unittest.cc b/net/log/net_log_unittest.cc
index 0b6f648..c62277e 100644
--- a/net/log/net_log_unittest.cc
+++ b/net/log/net_log_unittest.cc
@@ -416,7 +416,7 @@
 
   // Add event and make sure both observers receive it at their respective log
   // levels.
-  absl::optional<int> param;
+  std::optional<int> param;
   AddEvent(NetLog::Get());
   ASSERT_EQ(1U, observer[0].GetNumValues());
   param = observer[0].GetDict(0)->FindDict("params")->FindInt("capture_mode");
diff --git a/net/log/test_net_log_util.cc b/net/log/test_net_log_util.cc
index 258d4d15..0a58486b 100644
--- a/net/log/test_net_log_util.cc
+++ b/net/log/test_net_log_util.cc
@@ -123,38 +123,37 @@
   return i;
 }
 
-absl::optional<std::string> GetOptionalStringValueFromParams(
+std::optional<std::string> GetOptionalStringValueFromParams(
     const NetLogEntry& entry,
     base::StringPiece path) {
   if (entry.params.empty()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   const std::string* result = entry.params.FindStringByDottedPath(path);
   if (!result)
-    return absl::nullopt;
+    return std::nullopt;
 
   return *result;
 }
 
-absl::optional<bool> GetOptionalBooleanValueFromParams(const NetLogEntry& entry,
-                                                       base::StringPiece path) {
+std::optional<bool> GetOptionalBooleanValueFromParams(const NetLogEntry& entry,
+                                                      base::StringPiece path) {
   if (entry.params.empty()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return entry.params.FindBoolByDottedPath(path);
 }
 
-absl::optional<int> GetOptionalIntegerValueFromParams(const NetLogEntry& entry,
-                                                      base::StringPiece path) {
+std::optional<int> GetOptionalIntegerValueFromParams(const NetLogEntry& entry,
+                                                     base::StringPiece path) {
   if (entry.params.empty()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return entry.params.FindIntByDottedPath(path);
 }
 
-absl::optional<int> GetOptionalNetErrorCodeFromParams(
-    const NetLogEntry& entry) {
+std::optional<int> GetOptionalNetErrorCodeFromParams(const NetLogEntry& entry) {
   return GetOptionalIntegerValueFromParams(entry, "net_error");
 }
 
diff --git a/net/log/test_net_log_util.h b/net/log/test_net_log_util.h
index 2fae1ad..77421ff 100644
--- a/net/log/test_net_log_util.h
+++ b/net/log/test_net_log_util.h
@@ -6,13 +6,14 @@
 #define NET_LOG_TEST_NET_LOG_UTIL_H_
 
 #include <stddef.h>
+
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "base/strings/string_piece.h"
 #include "net/log/net_log_event_type.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -73,14 +74,14 @@
 
 // The following methods return a parameter of the given type at the given path,
 // or nullopt if there is none.
-absl::optional<std::string> GetOptionalStringValueFromParams(
+std::optional<std::string> GetOptionalStringValueFromParams(
     const NetLogEntry& entry,
     base::StringPiece path);
-absl::optional<bool> GetOptionalBooleanValueFromParams(const NetLogEntry& entry,
-                                                       base::StringPiece path);
-absl::optional<int> GetOptionalIntegerValueFromParams(const NetLogEntry& entry,
+std::optional<bool> GetOptionalBooleanValueFromParams(const NetLogEntry& entry,
                                                       base::StringPiece path);
-absl::optional<int> GetOptionalNetErrorCodeFromParams(const NetLogEntry& entry);
+std::optional<int> GetOptionalIntegerValueFromParams(const NetLogEntry& entry,
+                                                     base::StringPiece path);
+std::optional<int> GetOptionalNetErrorCodeFromParams(const NetLogEntry& entry);
 
 // Same as the *Optional* versions above, except will add a Gtest failure if the
 // value was not present, and then return some default.
diff --git a/net/log/trace_net_log_observer_unittest.cc b/net/log/trace_net_log_observer_unittest.cc
index fd2b7dd..02646d99 100644
--- a/net/log/trace_net_log_observer_unittest.cc
+++ b/net/log/trace_net_log_observer_unittest.cc
@@ -127,7 +127,7 @@
     trace_buffer_.AddFragment(events_str->data());
     trace_buffer_.Finish();
 
-    absl::optional<base::Value> trace_value;
+    std::optional<base::Value> trace_value;
     trace_value =
         base::JSONReader::Read(json_output_.json_output, base::JSON_PARSE_RFC);
 
diff --git a/net/network_error_logging/network_error_logging_service.cc b/net/network_error_logging/network_error_logging_service.cc
index d840259..7acac19 100644
--- a/net/network_error_logging/network_error_logging_service.cc
+++ b/net/network_error_logging/network_error_logging_service.cc
@@ -5,6 +5,7 @@
 #include "net/network_error_logging/network_error_logging_service.h"
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -28,7 +29,6 @@
 #include "net/base/url_util.h"
 #include "net/log/net_log.h"
 #include "net/reporting/reporting_service.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -475,7 +475,7 @@
     }
 
     bool success = (type == OK) && !IsHttpError(details);
-    const absl::optional<double> sampling_fraction =
+    const std::optional<double> sampling_fraction =
         SampleAndReturnFraction(*policy, success);
     if (!sampling_fraction.has_value())
       return;
@@ -488,7 +488,7 @@
     // A null reporting source token is used since this report is not associated
     // with any particular document.
     reporting_service_->QueueReport(
-        details.uri, absl::nullopt, details.network_anonymization_key,
+        details.uri, std::nullopt, details.network_anonymization_key,
         details.user_agent, policy->report_to, kReportType,
         CreateReportBody(phase_string, type_string, sampling_fraction.value(),
                          details),
@@ -526,7 +526,7 @@
           RequestOutcome::kDiscardedIPAddressMismatch);
       return;
     }
-    const absl::optional<double> sampling_fraction =
+    const std::optional<double> sampling_fraction =
         SampleAndReturnFraction(*policy, details.success);
     if (!sampling_fraction.has_value()) {
       RecordSignedExchangeRequestOutcome(
@@ -538,7 +538,7 @@
     // A null reporting source token is used since this report is not associated
     // with any particular document.
     reporting_service_->QueueReport(
-        details.outer_url, absl::nullopt, details.network_anonymization_key,
+        details.outer_url, std::nullopt, details.network_anonymization_key,
         details.user_agent, policy->report_to, kReportType,
         CreateSignedExchangeReportBody(details, sampling_fraction.value()),
         0 /* depth */);
@@ -586,7 +586,7 @@
     if (json_value.size() > kMaxJsonSize)
       return false;
 
-    absl::optional<base::Value> value =
+    std::optional<base::Value> value =
         base::JSONReader::Read(json_value, base::JSON_PARSE_RFC, kMaxJsonDepth);
     if (!value)
       return false;
@@ -825,20 +825,20 @@
   }
 
   // Returns a valid value of matching fraction iff the event should be sampled.
-  absl::optional<double> SampleAndReturnFraction(const NelPolicy& policy,
-                                                 bool success) const {
+  std::optional<double> SampleAndReturnFraction(const NelPolicy& policy,
+                                                bool success) const {
     const double sampling_fraction =
         success ? policy.success_fraction : policy.failure_fraction;
 
     // Sampling fractions are often either 0.0 or 1.0, so in those cases we
     // can avoid having to call RandDouble().
     if (sampling_fraction <= 0.0)
-      return absl::nullopt;
+      return std::nullopt;
     if (sampling_fraction >= 1.0)
       return sampling_fraction;
 
     if (base::RandDouble() >= sampling_fraction)
-      return absl::nullopt;
+      return std::nullopt;
     return sampling_fraction;
   }
 
diff --git a/net/network_error_logging/network_error_logging_service_unittest.cc b/net/network_error_logging/network_error_logging_service_unittest.cc
index 1ed715ae..491f9b5b 100644
--- a/net/network_error_logging/network_error_logging_service_unittest.cc
+++ b/net/network_error_logging/network_error_logging_service_unittest.cc
@@ -222,7 +222,7 @@
 void ExpectDictDoubleValue(double expected_value,
                            const base::Value::Dict& value,
                            const std::string& key) {
-  absl::optional<double> double_value = value.FindDouble(key);
+  std::optional<double> double_value = value.FindDouble(key);
   ASSERT_TRUE(double_value) << key;
   EXPECT_DOUBLE_EQ(expected_value, *double_value) << key;
 }
diff --git a/net/nqe/effective_connection_type.cc b/net/nqe/effective_connection_type.cc
index c3bddc8d..e62ddb71 100644
--- a/net/nqe/effective_connection_type.cc
+++ b/net/nqe/effective_connection_type.cc
@@ -43,7 +43,7 @@
   return "";
 }
 
-absl::optional<EffectiveConnectionType> GetEffectiveConnectionTypeForName(
+std::optional<EffectiveConnectionType> GetEffectiveConnectionTypeForName(
     base::StringPiece connection_type_name) {
   if (connection_type_name == kEffectiveConnectionTypeUnknown)
     return EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
@@ -61,7 +61,7 @@
     return EFFECTIVE_CONNECTION_TYPE_3G;
   if (connection_type_name == kEffectiveConnectionType4G)
     return EFFECTIVE_CONNECTION_TYPE_4G;
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 const char* DeprecatedGetNameForEffectiveConnectionType(
diff --git a/net/nqe/effective_connection_type.h b/net/nqe/effective_connection_type.h
index c0b0ab8d..060a953 100644
--- a/net/nqe/effective_connection_type.h
+++ b/net/nqe/effective_connection_type.h
@@ -5,9 +5,10 @@
 #ifndef NET_NQE_EFFECTIVE_CONNECTION_TYPE_H_
 #define NET_NQE_EFFECTIVE_CONNECTION_TYPE_H_
 
+#include <optional>
+
 #include "base/strings/string_piece.h"
 #include "net/base/net_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -69,7 +70,7 @@
 // |connection_type_name|. If the effective connection type is unavailable or if
 // |connection_type_name| does not match to a known effective connection type,
 // an unset value is returned.
-NET_EXPORT absl::optional<EffectiveConnectionType>
+NET_EXPORT std::optional<EffectiveConnectionType>
 GetEffectiveConnectionTypeForName(base::StringPiece connection_type_name);
 
 // Returns the string equivalent of |type|. Deprecated, and replaced by
diff --git a/net/nqe/effective_connection_type_unittest.cc b/net/nqe/effective_connection_type_unittest.cc
index b0ffa8cc..4761150 100644
--- a/net/nqe/effective_connection_type_unittest.cc
+++ b/net/nqe/effective_connection_type_unittest.cc
@@ -4,10 +4,10 @@
 
 #include "net/nqe/effective_connection_type.h"
 
+#include <optional>
 #include <string>
 
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -48,7 +48,7 @@
   // GetEffectiveConnectionTypeForName should return Slow2G as effective
   // connection type for both the deprecated and the current string
   // representation.
-  absl::optional<EffectiveConnectionType> type =
+  std::optional<EffectiveConnectionType> type =
       GetEffectiveConnectionTypeForName("Slow2G");
   EXPECT_EQ(EFFECTIVE_CONNECTION_TYPE_SLOW_2G, type.value());
 
diff --git a/net/nqe/network_id.h b/net/nqe/network_id.h
index 967f9da..2878e44 100644
--- a/net/nqe/network_id.h
+++ b/net/nqe/network_id.h
@@ -58,7 +58,7 @@
   // range is capped between 0 and 4 to ensure that a change in the value
   // indicates a non-negligible change in the signal quality.
   //
-  // TODO(crbug.com/1495477): This should use absl::optional instead of a magic
+  // TODO(crbug.com/1495477): This should use std::optional instead of a magic
   // value.
   int32_t signal_strength;
 };
diff --git a/net/nqe/network_qualities_prefs_manager.cc b/net/nqe/network_qualities_prefs_manager.cc
index bff2264..11f787b3 100644
--- a/net/nqe/network_qualities_prefs_manager.cc
+++ b/net/nqe/network_qualities_prefs_manager.cc
@@ -4,6 +4,7 @@
 
 #include "net/nqe/network_qualities_prefs_manager.h"
 
+#include <optional>
 #include <string>
 #include <utility>
 
@@ -12,7 +13,6 @@
 #include "base/rand_util.h"
 #include "base/task/sequenced_task_runner.h"
 #include "net/nqe/network_quality_estimator.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -40,7 +40,7 @@
 
     if (!it.second.is_string())
       continue;
-    absl::optional<EffectiveConnectionType> effective_connection_type =
+    std::optional<EffectiveConnectionType> effective_connection_type =
         GetEffectiveConnectionTypeForName(it.second.GetString());
     DCHECK(effective_connection_type.has_value());
 
diff --git a/net/nqe/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc
index 717a1a4..8d0b8e5 100644
--- a/net/nqe/network_quality_estimator.cc
+++ b/net/nqe/network_quality_estimator.cc
@@ -467,7 +467,7 @@
 
   current_network_id_.signal_strength = INT32_MIN;
   network_quality_ = nqe::internal::NetworkQuality();
-  end_to_end_rtt_ = absl::nullopt;
+  end_to_end_rtt_ = std::nullopt;
   effective_connection_type_ = EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
   rtt_observations_size_at_last_ect_computation_ = 0;
   throughput_observations_size_at_last_ect_computation_ = 0;
@@ -551,7 +551,7 @@
                         network_quality_.http_rtt());
   }
 
-  end_to_end_rtt_ = absl::nullopt;
+  end_to_end_rtt_ = std::nullopt;
   if (end_to_end_rtt != nqe::internal::InvalidRTT()) {
     end_to_end_rtt_ = end_to_end_rtt;
   }
@@ -574,9 +574,9 @@
   new_throughput_observations_since_last_ect_computation_ = 0;
 }
 
-absl::optional<net::EffectiveConnectionType>
+std::optional<net::EffectiveConnectionType>
 NetworkQualityEstimator::GetOverrideECT() const {
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void NetworkQualityEstimator::ClampKbpsBasedOnEct() {
@@ -655,7 +655,7 @@
     const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  absl::optional<net::EffectiveConnectionType> override_ect = GetOverrideECT();
+  std::optional<net::EffectiveConnectionType> override_ect = GetOverrideECT();
   if (override_ect) {
     return override_ect.value();
   }
@@ -1040,7 +1040,7 @@
 void NetworkQualityEstimator::OnUpdatedTransportRTTAvailable(
     SocketPerformanceWatcherFactory::Protocol protocol,
     const base::TimeDelta& rtt,
-    const absl::optional<nqe::internal::IPHash>& host) {
+    const std::optional<nqe::internal::IPHash>& host) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK_LT(nqe::internal::INVALID_RTT_THROUGHPUT, rtt.InMilliseconds());
   Observation observation(rtt.InMilliseconds(), tick_clock_->NowTicks(),
@@ -1205,7 +1205,7 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK_NE(EFFECTIVE_CONNECTION_TYPE_LAST, effective_connection_type_);
 
-  absl::optional<net::EffectiveConnectionType> override_ect = GetOverrideECT();
+  std::optional<net::EffectiveConnectionType> override_ect = GetOverrideECT();
 
   // TODO(tbansal): Add hysteresis in the notification.
   for (auto& observer : effective_connection_type_observer_list_)
@@ -1236,7 +1236,7 @@
   if (!effective_connection_type_observer_list_.HasObserver(observer))
     return;
 
-  absl::optional<net::EffectiveConnectionType> override_ect = GetOverrideECT();
+  std::optional<net::EffectiveConnectionType> override_ect = GetOverrideECT();
   if (override_ect) {
     observer->OnEffectiveConnectionTypeChanged(override_ect.value());
     return;
@@ -1317,30 +1317,30 @@
 }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
-absl::optional<base::TimeDelta> NetworkQualityEstimator::GetHttpRTT() const {
+std::optional<base::TimeDelta> NetworkQualityEstimator::GetHttpRTT() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (network_quality_.http_rtt() == nqe::internal::InvalidRTT())
-    return absl::optional<base::TimeDelta>();
+    return std::optional<base::TimeDelta>();
   return network_quality_.http_rtt();
 }
 
-absl::optional<base::TimeDelta> NetworkQualityEstimator::GetTransportRTT()
+std::optional<base::TimeDelta> NetworkQualityEstimator::GetTransportRTT()
     const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (network_quality_.transport_rtt() == nqe::internal::InvalidRTT())
-    return absl::optional<base::TimeDelta>();
+    return std::optional<base::TimeDelta>();
   return network_quality_.transport_rtt();
 }
 
-absl::optional<int32_t> NetworkQualityEstimator::GetDownstreamThroughputKbps()
+std::optional<int32_t> NetworkQualityEstimator::GetDownstreamThroughputKbps()
     const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (network_quality_.downstream_throughput_kbps() ==
       nqe::internal::INVALID_RTT_THROUGHPUT) {
-    return absl::optional<int32_t>();
+    return std::optional<int32_t>();
   }
   return network_quality_.downstream_throughput_kbps();
 }
diff --git a/net/nqe/network_quality_estimator.h b/net/nqe/network_quality_estimator.h
index 6268c2e..9d6d4d2 100644
--- a/net/nqe/network_quality_estimator.h
+++ b/net/nqe/network_quality_estimator.h
@@ -9,6 +9,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "base/gtest_prod_util.h"
@@ -36,7 +37,6 @@
 #include "net/nqe/peer_to_peer_connections_count_observer.h"
 #include "net/nqe/rtt_throughput_estimates_observer.h"
 #include "net/nqe/socket_watcher_factory.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class TickClock;
@@ -144,18 +144,18 @@
   // time from when the request was sent (this happens after the connection is
   // established) to the time when the response headers were received.
   // Virtualized for testing.
-  virtual absl::optional<base::TimeDelta> GetHttpRTT() const;
+  virtual std::optional<base::TimeDelta> GetHttpRTT() const;
 
   // Returns the current transport RTT estimate. If the estimate is
   // unavailable, the returned optional value is null.  The RTT at the transport
   // layer provides an aggregate estimate of the transport RTT as computed by
   // various underlying TCP and QUIC connections. Virtualized for testing.
-  virtual absl::optional<base::TimeDelta> GetTransportRTT() const;
+  virtual std::optional<base::TimeDelta> GetTransportRTT() const;
 
   // Returns the current downstream throughput estimate (in kilobits per
   // second). If the estimate is unavailable, the returned optional value is
   // null.
-  absl::optional<int32_t> GetDownstreamThroughputKbps() const;
+  std::optional<int32_t> GetDownstreamThroughputKbps() const;
 
   // Adds |observer| to the list of RTT and throughput estimate observers.
   // The observer must register and unregister itself on the same thread.
@@ -341,7 +341,7 @@
   void OnUpdatedTransportRTTAvailable(
       SocketPerformanceWatcherFactory::Protocol protocol,
       const base::TimeDelta& rtt,
-      const absl::optional<nqe::internal::IPHash>& host);
+      const std::optional<nqe::internal::IPHash>& host);
 
   // Returns an estimate of network quality at the specified |percentile|.
   // Only the observations later than |start_time| are taken into account.
@@ -393,7 +393,7 @@
 
   // Returns a non-null value if the value of the effective connection type has
   // been overridden for testing.
-  virtual absl::optional<net::EffectiveConnectionType> GetOverrideECT() const;
+  virtual std::optional<net::EffectiveConnectionType> GetOverrideECT() const;
 
   // Observer list for RTT or throughput estimates. Protected for testing.
   base::ObserverList<RTTAndThroughputEstimatesObserver>::Unchecked
@@ -593,7 +593,7 @@
 
   // Current estimate of the network quality.
   nqe::internal::NetworkQuality network_quality_;
-  absl::optional<base::TimeDelta> end_to_end_rtt_;
+  std::optional<base::TimeDelta> end_to_end_rtt_;
 
   // Current effective connection type. It is updated on connection change
   // events. It is also updated every time there is network traffic (provided
@@ -619,7 +619,7 @@
   // Time when the last RTT observation from a socket watcher was received.
   base::TimeTicks last_socket_watcher_rtt_notification_;
 
-  absl::optional<base::TimeTicks> last_signal_strength_check_timestamp_;
+  std::optional<base::TimeTicks> last_signal_strength_check_timestamp_;
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // Whether the network id should be obtained on a worker thread.
diff --git a/net/nqe/network_quality_estimator_params.cc b/net/nqe/network_quality_estimator_params.cc
index 3ec940c..5784d83f 100644
--- a/net/nqe/network_quality_estimator_params.cc
+++ b/net/nqe/network_quality_estimator_params.cc
@@ -392,13 +392,13 @@
          kEffectiveConnectionTypeSlow2GOnCellular;
 }
 
-absl::optional<EffectiveConnectionType> GetInitForcedEffectiveConnectionType(
+std::optional<EffectiveConnectionType> GetInitForcedEffectiveConnectionType(
     const std::map<std::string, std::string>& params) {
   if (GetForcedEffectiveConnectionTypeOnCellularOnly(params)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   std::string forced_value = GetForcedEffectiveConnectionTypeString(params);
-  absl::optional<EffectiveConnectionType> ect =
+  std::optional<EffectiveConnectionType> ect =
       GetEffectiveConnectionTypeForName(forced_value);
   DCHECK(forced_value.empty() || ect);
   return ect;
@@ -539,7 +539,7 @@
   forced_effective_connection_type_ = type;
 }
 
-absl::optional<EffectiveConnectionType>
+std::optional<EffectiveConnectionType>
 NetworkQualityEstimatorParams::GetForcedEffectiveConnectionType(
     NetworkChangeNotifier::ConnectionType connection_type) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -551,7 +551,7 @@
       net::NetworkChangeNotifier::IsConnectionCellular(connection_type)) {
     return EFFECTIVE_CONNECTION_TYPE_SLOW_2G;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 size_t NetworkQualityEstimatorParams::throughput_min_requests_in_flight()
diff --git a/net/nqe/network_quality_estimator_params.h b/net/nqe/network_quality_estimator_params.h
index 972dfaf..44fa588 100644
--- a/net/nqe/network_quality_estimator_params.h
+++ b/net/nqe/network_quality_estimator_params.h
@@ -6,6 +6,7 @@
 #define NET_NQE_NETWORK_QUALITY_ESTIMATOR_PARAMS_H_
 
 #include <map>
+#include <optional>
 #include <string>
 
 #include "base/sequence_checker.h"
@@ -14,7 +15,6 @@
 #include "net/base/network_change_notifier.h"
 #include "net/nqe/effective_connection_type.h"
 #include "net/nqe/network_quality.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -77,7 +77,7 @@
   // the effective connection type that has been forced. Forced ECT can be
   // forced based on |connection_type| (e.g. Slow-2G on cellular, and default on
   // other connection type).
-  absl::optional<EffectiveConnectionType> GetForcedEffectiveConnectionType(
+  std::optional<EffectiveConnectionType> GetForcedEffectiveConnectionType(
       NetworkChangeNotifier::ConnectionType connection_type);
 
   void SetForcedEffectiveConnectionType(
@@ -268,7 +268,7 @@
   const int throughput_min_transfer_size_kilobytes_;
   const double throughput_hanging_requests_cwnd_size_multiplier_;
   const double weight_multiplier_per_second_;
-  absl::optional<EffectiveConnectionType> forced_effective_connection_type_;
+  std::optional<EffectiveConnectionType> forced_effective_connection_type_;
   const bool forced_effective_connection_type_on_cellular_only_;
   bool persistent_cache_reading_enabled_;
   const base::TimeDelta min_socket_watcher_notification_interval_;
diff --git a/net/nqe/network_quality_estimator_params_unittest.cc b/net/nqe/network_quality_estimator_params_unittest.cc
index 09c4d3a8..0099bee 100644
--- a/net/nqe/network_quality_estimator_params_unittest.cc
+++ b/net/nqe/network_quality_estimator_params_unittest.cc
@@ -122,7 +122,7 @@
        ++i) {
     NetworkChangeNotifier::ConnectionType connection_type =
         static_cast<NetworkChangeNotifier::ConnectionType>(i);
-    absl::optional<EffectiveConnectionType> ect =
+    std::optional<EffectiveConnectionType> ect =
         params.GetForcedEffectiveConnectionType(connection_type);
 
     if (net::NetworkChangeNotifier::IsConnectionCellular(connection_type)) {
@@ -131,7 +131,7 @@
     } else {
       // Test for non-cellular connection types. Make sure that there is no
       // forced ect.
-      EXPECT_EQ(absl::nullopt, ect);
+      EXPECT_EQ(std::nullopt, ect);
     }
   }
 }
diff --git a/net/nqe/network_quality_estimator_test_util.cc b/net/nqe/network_quality_estimator_test_util.cc
index 1a62301..64996686 100644
--- a/net/nqe/network_quality_estimator_test_util.cc
+++ b/net/nqe/network_quality_estimator_test_util.cc
@@ -191,7 +191,7 @@
                                                rtt, observations_count);
 }
 
-absl::optional<base::TimeDelta> TestNetworkQualityEstimator::GetTransportRTT()
+std::optional<base::TimeDelta> TestNetworkQualityEstimator::GetTransportRTT()
     const {
   if (start_time_null_transport_rtt_)
     return start_time_null_transport_rtt_;
@@ -282,7 +282,7 @@
     observer.OnEffectiveConnectionTypeChanged(type);
 }
 
-absl::optional<net::EffectiveConnectionType>
+std::optional<net::EffectiveConnectionType>
 TestNetworkQualityEstimator::GetOverrideECT() const {
   return effective_connection_type_;
 }
diff --git a/net/nqe/network_quality_estimator_test_util.h b/net/nqe/network_quality_estimator_test_util.h
index 67e0fe9a..e2b3d8d 100644
--- a/net/nqe/network_quality_estimator_test_util.h
+++ b/net/nqe/network_quality_estimator_test_util.h
@@ -9,6 +9,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -22,7 +23,6 @@
 #include "net/nqe/network_quality_estimator.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace net {
@@ -137,7 +137,7 @@
     recent_transport_rtt_ = recent_transport_rtt;
   }
 
-  absl::optional<base::TimeDelta> GetTransportRTT() const override;
+  std::optional<base::TimeDelta> GetTransportRTT() const override;
 
   void set_start_time_null_downlink_throughput_kbps(
       int32_t downlink_throughput_kbps) {
@@ -237,15 +237,15 @@
   // network id and signal strength (instead of invoking platform APIs).
   nqe::internal::NetworkID GetCurrentNetworkID() const override;
 
-  absl::optional<net::EffectiveConnectionType> GetOverrideECT() const override;
+  std::optional<net::EffectiveConnectionType> GetOverrideECT() const override;
 
   // Net log observer used to test correctness of NetLog entries.
   net::RecordingNetLogObserver net_log_observer_;
 
   // If set, GetEffectiveConnectionType() and GetRecentEffectiveConnectionType()
   // would return the set values, respectively.
-  absl::optional<EffectiveConnectionType> effective_connection_type_;
-  absl::optional<EffectiveConnectionType> recent_effective_connection_type_;
+  std::optional<EffectiveConnectionType> effective_connection_type_;
+  std::optional<EffectiveConnectionType> recent_effective_connection_type_;
 
   NetworkChangeNotifier::ConnectionType current_network_type_ =
       NetworkChangeNotifier::CONNECTION_UNKNOWN;
@@ -254,27 +254,27 @@
   // If set, GetRecentHttpRTT() would return one of the set values.
   // |start_time_null_http_rtt_| is returned if the |start_time| is null.
   // Otherwise, |recent_http_rtt_| is returned.
-  absl::optional<base::TimeDelta> start_time_null_http_rtt_;
-  absl::optional<base::TimeDelta> recent_http_rtt_;
+  std::optional<base::TimeDelta> start_time_null_http_rtt_;
+  std::optional<base::TimeDelta> recent_http_rtt_;
 
   // If set, GetRecentTransportRTT() would return one of the set values.
   // |start_time_null_transport_rtt_| is returned if the |start_time| is null.
   // Otherwise, |recent_transport_rtt_| is returned.
-  absl::optional<base::TimeDelta> start_time_null_transport_rtt_;
-  absl::optional<base::TimeDelta> recent_transport_rtt_;
+  std::optional<base::TimeDelta> start_time_null_transport_rtt_;
+  std::optional<base::TimeDelta> recent_transport_rtt_;
 
   // If set, GetRecentDownlinkThroughputKbps() would return one of the set
   // values. |start_time_null_downlink_throughput_kbps_| is returned if the
   // |start_time| is null. Otherwise, |recent_downlink_throughput_kbps_| is
   // returned.
-  absl::optional<int32_t> start_time_null_downlink_throughput_kbps_;
-  absl::optional<int32_t> recent_downlink_throughput_kbps_;
+  std::optional<int32_t> start_time_null_downlink_throughput_kbps_;
+  std::optional<int32_t> recent_downlink_throughput_kbps_;
 
   // If set, GetRTTEstimateInternal() would return the set value.
-  absl::optional<base::TimeDelta> rtt_estimate_internal_;
+  std::optional<base::TimeDelta> rtt_estimate_internal_;
 
   // If set, GetRTTEstimateInternal() would return the set value.
-  absl::optional<base::TimeDelta> start_time_null_end_to_end_rtt_;
+  std::optional<base::TimeDelta> start_time_null_end_to_end_rtt_;
 
   LocalHttpTestServer embedded_test_server_;
 
@@ -283,7 +283,7 @@
 
   size_t ping_rtt_received_count_ = 0;
 
-  absl::optional<size_t> transport_rtt_observation_count_last_ect_computation_;
+  std::optional<size_t> transport_rtt_observation_count_last_ect_computation_;
 };
 
 }  // namespace net
diff --git a/net/nqe/network_quality_estimator_unittest.cc b/net/nqe/network_quality_estimator_unittest.cc
index 203993c8..5f82b10 100644
--- a/net/nqe/network_quality_estimator_unittest.cc
+++ b/net/nqe/network_quality_estimator_unittest.cc
@@ -10,6 +10,7 @@
 #include <cmath>
 #include <limits>
 #include <map>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -49,7 +50,6 @@
 #include "net/url_request/url_request_context_builder.h"
 #include "net/url_request/url_request_test_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace {
@@ -510,10 +510,10 @@
   TestNetworkQualityEstimator estimator(variation_params);
   estimator.OnUpdatedTransportRTTAvailable(
       SocketPerformanceWatcherFactory::PROTOCOL_TCP, base::Milliseconds(10),
-      absl::nullopt);
+      std::nullopt);
   estimator.OnUpdatedTransportRTTAvailable(
       SocketPerformanceWatcherFactory::PROTOCOL_QUIC, base::Milliseconds(10),
-      absl::nullopt);
+      std::nullopt);
   histogram_tester.ExpectBucketCount("NQE.RTT.ObservationSource",
                                      NETWORK_QUALITY_OBSERVATION_SOURCE_TCP, 1);
   histogram_tester.ExpectBucketCount(
@@ -536,7 +536,7 @@
   TestNetworkQualityEstimator estimator(variation_params);
   estimator.OnUpdatedTransportRTTAvailable(
       SocketPerformanceWatcherFactory::PROTOCOL_QUIC, base::Milliseconds(10),
-      absl::nullopt);
+      std::nullopt);
   histogram_tester.ExpectBucketCount(
       "NQE.RTT.ObservationSource", NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC, 1);
   histogram_tester.ExpectTotalCount("NQE.RTT.ObservationSource", 1);
diff --git a/net/nqe/network_quality_estimator_util_unittest.cc b/net/nqe/network_quality_estimator_util_unittest.cc
index 43b77e4..9be0273 100644
--- a/net/nqe/network_quality_estimator_util_unittest.cc
+++ b/net/nqe/network_quality_estimator_util_unittest.cc
@@ -5,6 +5,7 @@
 #include "net/nqe/network_quality_estimator_util.h"
 
 #include <memory>
+#include <optional>
 
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
@@ -20,7 +21,6 @@
 #include "net/dns/mock_host_resolver.h"
 #include "net/log/net_log.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace net::nqe::internal {
@@ -49,13 +49,13 @@
   EXPECT_EQ(0u, mock_host_resolver.num_resolve());
 
   // Load hostnames into HostResolver cache.
-  int rv = mock_host_resolver.LoadIntoCache(HostPortPair("example1.com", 443),
-                                            NetworkAnonymizationKey(),
-                                            absl::nullopt);
+  int rv =
+      mock_host_resolver.LoadIntoCache(HostPortPair("example1.com", 443),
+                                       NetworkAnonymizationKey(), std::nullopt);
   EXPECT_EQ(OK, rv);
-  rv = mock_host_resolver.LoadIntoCache(HostPortPair("example2.com", 443),
-                                        NetworkAnonymizationKey(),
-                                        absl::nullopt);
+  rv =
+      mock_host_resolver.LoadIntoCache(HostPortPair("example2.com", 443),
+                                       NetworkAnonymizationKey(), std::nullopt);
   EXPECT_EQ(OK, rv);
 
   EXPECT_EQ(2u, mock_host_resolver.num_non_local_resolves());
@@ -109,9 +109,9 @@
                                        NetworkAnonymizationKey()));
   EXPECT_EQ(0u, mock_host_resolver.num_non_local_resolves());
 
-  int rv = mock_host_resolver.LoadIntoCache(HostPortPair("example3.com", 443),
-                                            NetworkAnonymizationKey(),
-                                            absl::nullopt);
+  int rv =
+      mock_host_resolver.LoadIntoCache(HostPortPair("example3.com", 443),
+                                       NetworkAnonymizationKey(), std::nullopt);
   EXPECT_EQ(OK, rv);
   EXPECT_EQ(1u, mock_host_resolver.num_non_local_resolves());
 
@@ -159,7 +159,7 @@
 
   int rv =
       mock_host_resolver.LoadIntoCache(HostPortPair("example3.com", 443),
-                                       kNetworkAnonymizationKey, absl::nullopt);
+                                       kNetworkAnonymizationKey, std::nullopt);
   EXPECT_EQ(OK, rv);
   EXPECT_EQ(1u, mock_host_resolver.num_non_local_resolves());
 
diff --git a/net/nqe/network_quality_observation.cc b/net/nqe/network_quality_observation.cc
index 0e0f7a53..4852c66 100644
--- a/net/nqe/network_quality_observation.cc
+++ b/net/nqe/network_quality_observation.cc
@@ -13,13 +13,13 @@
                          base::TimeTicks timestamp,
                          int32_t signal_strength,
                          NetworkQualityObservationSource source)
-    : Observation(value, timestamp, signal_strength, source, absl::nullopt) {}
+    : Observation(value, timestamp, signal_strength, source, std::nullopt) {}
 
 Observation::Observation(int32_t value,
                          base::TimeTicks timestamp,
                          int32_t signal_strength,
                          NetworkQualityObservationSource source,
-                         const absl::optional<IPHash>& host)
+                         const std::optional<IPHash>& host)
     : value_(value),
       timestamp_(timestamp),
       signal_strength_(signal_strength),
diff --git a/net/nqe/network_quality_observation.h b/net/nqe/network_quality_observation.h
index e01e284..b08c2eb 100644
--- a/net/nqe/network_quality_observation.h
+++ b/net/nqe/network_quality_observation.h
@@ -7,13 +7,13 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
 #include "base/time/time.h"
 #include "net/base/net_export.h"
 #include "net/nqe/network_quality_estimator_util.h"
 #include "net/nqe/network_quality_observation_source.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net::nqe::internal {
 
@@ -32,7 +32,7 @@
               base::TimeTicks timestamp,
               int32_t signal_strength,
               NetworkQualityObservationSource source,
-              const absl::optional<IPHash>& host);
+              const std::optional<IPHash>& host);
 
   Observation(const Observation& other);
   Observation& operator=(const Observation& other);
@@ -53,7 +53,7 @@
   NetworkQualityObservationSource source() const { return source_; }
 
   // A unique identifier for the remote host which was used for the measurement.
-  absl::optional<IPHash> host() const { return host_; }
+  std::optional<IPHash> host() const { return host_; }
 
   // Returns the observation categories to which this observation belongs to.
   std::vector<ObservationCategory> GetObservationCategories() const;
@@ -70,7 +70,7 @@
 
   NetworkQualityObservationSource source_;
 
-  absl::optional<IPHash> host_;
+  std::optional<IPHash> host_;
 };
 
 }  // namespace net::nqe::internal
diff --git a/net/nqe/observation_buffer.cc b/net/nqe/observation_buffer.cc
index a79681e..9cbc51a 100644
--- a/net/nqe/observation_buffer.cc
+++ b/net/nqe/observation_buffer.cc
@@ -65,7 +65,7 @@
   DCHECK_LE(observations_.size(), params_->observation_buffer_size());
 }
 
-absl::optional<int32_t> ObservationBuffer::GetPercentile(
+std::optional<int32_t> ObservationBuffer::GetPercentile(
     base::TimeTicks begin_timestamp,
     int32_t current_signal_strength,
     int percentile,
@@ -88,7 +88,7 @@
   }
 
   if (weighted_observations.empty())
-    return absl::nullopt;
+    return std::nullopt;
 
   double desired_weight = percentile / 100.0 * total_weight;
 
diff --git a/net/nqe/observation_buffer.h b/net/nqe/observation_buffer.h
index 4f56417..5692c58 100644
--- a/net/nqe/observation_buffer.h
+++ b/net/nqe/observation_buffer.h
@@ -9,6 +9,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <vector>
 
@@ -19,7 +20,6 @@
 #include "net/nqe/network_quality_estimator_util.h"
 #include "net/nqe/network_quality_observation.h"
 #include "net/nqe/network_quality_observation_source.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
@@ -75,10 +75,10 @@
   // signal strength. |result| must not be null. If |observations_count| is not
   // null, then it is set to the number of observations that were available
   // in the observation buffer for computing the percentile.
-  absl::optional<int32_t> GetPercentile(base::TimeTicks begin_timestamp,
-                                        int32_t current_signal_strength,
-                                        int percentile,
-                                        size_t* observations_count) const;
+  std::optional<int32_t> GetPercentile(base::TimeTicks begin_timestamp,
+                                       int32_t current_signal_strength,
+                                       int percentile,
+                                       size_t* observations_count) const;
 
   void SetTickClockForTesting(const base::TickClock* tick_clock) {
     tick_clock_ = tick_clock;
diff --git a/net/nqe/observation_buffer_unittest.cc b/net/nqe/observation_buffer_unittest.cc
index ed92cd269..7eac6ca6 100644
--- a/net/nqe/observation_buffer_unittest.cc
+++ b/net/nqe/observation_buffer_unittest.cc
@@ -62,7 +62,7 @@
   for (int i = 1; i <= 100; ++i) {
     size_t observations_count = 0;
     // Verify that i'th percentile is more than i-1'th percentile.
-    absl::optional<int32_t> result_i = observation_buffer.GetPercentile(
+    std::optional<int32_t> result_i = observation_buffer.GetPercentile(
         now, INT32_MIN, i, &observations_count);
     EXPECT_EQ(100u, observations_count);
     ASSERT_TRUE(result_i.has_value());
@@ -70,7 +70,7 @@
 
     result_highest = std::max(result_highest, result_i.value());
 
-    absl::optional<int32_t> result_i_1 = observation_buffer.GetPercentile(
+    std::optional<int32_t> result_i_1 = observation_buffer.GetPercentile(
         now, INT32_MIN, i - 1, &observations_count);
     EXPECT_EQ(100u, observations_count);
     ASSERT_TRUE(result_i_1.has_value());
@@ -127,7 +127,7 @@
     // less than 1. This is required because computed percentiles may be
     // slightly different from what is expected due to floating point
     // computation errors and integer rounding off errors.
-    absl::optional<int32_t> result = buffer.GetPercentile(
+    std::optional<int32_t> result = buffer.GetPercentile(
         base::TimeTicks(), INT32_MIN, i, &observations_count);
     EXPECT_EQ(100u, observations_count);
     EXPECT_TRUE(result.has_value());
@@ -192,7 +192,7 @@
     // required because computed percentiles may be slightly different from
     // what is expected due to floating point computation errors and integer
     // rounding off errors.
-    absl::optional<int32_t> result =
+    std::optional<int32_t> result =
         buffer.GetPercentile(very_old, INT32_MIN, i, &observations_count);
     EXPECT_TRUE(result.has_value());
     EXPECT_NEAR(result.value(), 51 + 0.49 * i, 1);
@@ -237,7 +237,7 @@
   // When the current RSSI is |high_rssi|, higher weight should be assigned
   // to observations that were taken at |high_rssi|.
   for (int i = 1; i < 100; ++i) {
-    absl::optional<int32_t> result =
+    std::optional<int32_t> result =
         buffer.GetPercentile(now, high_rssi, i, nullptr);
     EXPECT_TRUE(result.has_value());
     EXPECT_NEAR(result.value(), 51 + 0.49 * i, 2);
@@ -246,7 +246,7 @@
   // When the current RSSI is |low_rssi|, higher weight should be assigned
   // to observations that were taken at |low_rssi|.
   for (int i = 1; i < 100; ++i) {
-    absl::optional<int32_t> result =
+    std::optional<int32_t> result =
         buffer.GetPercentile(now, low_rssi, i, nullptr);
     EXPECT_TRUE(result.has_value());
     EXPECT_NEAR(result.value(), i / 2, 2);
@@ -307,7 +307,7 @@
     // required because computed percentiles may be slightly different from
     // what is expected due to floating point computation errors and integer
     // rounding off errors.
-    absl::optional<int32_t> result =
+    std::optional<int32_t> result =
         buffer.GetPercentile(base::TimeTicks(), INT32_MIN, i, nullptr);
     EXPECT_TRUE(result.has_value());
     EXPECT_NEAR(result.value(), i, 1);
@@ -347,7 +347,7 @@
   };
 
   for (const auto& test : tests) {
-    absl::optional<int32_t> url_request_rtt =
+    std::optional<int32_t> url_request_rtt =
         buffer.GetPercentile(test.start_timestamp, INT32_MIN, 50, nullptr);
     EXPECT_EQ(test.expect_network_quality_available,
               url_request_rtt.has_value());
diff --git a/net/nqe/socket_watcher.cc b/net/nqe/socket_watcher.cc
index e0bb766..e04248d4 100644
--- a/net/nqe/socket_watcher.cc
+++ b/net/nqe/socket_watcher.cc
@@ -18,7 +18,7 @@
 // Generate a compact representation for |ip_addr|. For IPv4, all 32 bits
 // are used and for IPv6, the first 64 bits are used as the remote host
 // identifier.
-absl::optional<IPHash> CalculateIPHash(const IPAddress& ip_addr) {
+std::optional<IPHash> CalculateIPHash(const IPAddress& ip_addr) {
   IPAddressBytes bytes = ip_addr.bytes();
 
   // For IPv4, the first four bytes are taken. For IPv6, the first 8 bytes are
diff --git a/net/nqe/socket_watcher.h b/net/nqe/socket_watcher.h
index 195502f..f862b6d 100644
--- a/net/nqe/socket_watcher.h
+++ b/net/nqe/socket_watcher.h
@@ -5,6 +5,8 @@
 #ifndef NET_NQE_SOCKET_WATCHER_H_
 #define NET_NQE_SOCKET_WATCHER_H_
 
+#include <optional>
+
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
@@ -15,7 +17,6 @@
 #include "net/nqe/network_quality_estimator_util.h"
 #include "net/socket/socket_performance_watcher.h"
 #include "net/socket/socket_performance_watcher_factory.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class SingleThreadTaskRunner;
@@ -32,7 +33,7 @@
 typedef base::RepeatingCallback<void(
     SocketPerformanceWatcherFactory::Protocol protocol,
     const base::TimeDelta& rtt,
-    const absl::optional<nqe::internal::IPHash>& host)>
+    const std::optional<nqe::internal::IPHash>& host)>
     OnUpdatedRTTAvailableCallback;
 
 typedef base::RepeatingCallback<bool(base::TimeTicks)> ShouldNotifyRTTCallback;
@@ -111,7 +112,7 @@
   bool first_quic_rtt_notification_received_ = false;
 
   // A unique identifier for the remote host that this socket connects to.
-  const absl::optional<IPHash> host_;
+  const std::optional<IPHash> host_;
 };
 
 }  // namespace nqe::internal
diff --git a/net/nqe/socket_watcher_factory.h b/net/nqe/socket_watcher_factory.h
index aad6c50..cf711c21 100644
--- a/net/nqe/socket_watcher_factory.h
+++ b/net/nqe/socket_watcher_factory.h
@@ -6,6 +6,7 @@
 #define NET_NQE_SOCKET_WATCHER_FACTORY_H_
 
 #include <memory>
+#include <optional>
 
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
@@ -17,7 +18,6 @@
 #include "net/nqe/network_quality_estimator_util.h"
 #include "net/socket/socket_performance_watcher.h"
 #include "net/socket/socket_performance_watcher_factory.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class TickClock;
@@ -31,7 +31,7 @@
 typedef base::RepeatingCallback<void(
     SocketPerformanceWatcherFactory::Protocol protocol,
     const base::TimeDelta& rtt,
-    const absl::optional<nqe::internal::IPHash>& host)>
+    const std::optional<nqe::internal::IPHash>& host)>
     OnUpdatedRTTAvailableCallback;
 
 typedef base::RepeatingCallback<bool(base::TimeTicks)> ShouldNotifyRTTCallback;
diff --git a/net/nqe/socket_watcher_unittest.cc b/net/nqe/socket_watcher_unittest.cc
index 64420b0..7994b6d 100644
--- a/net/nqe/socket_watcher_unittest.cc
+++ b/net/nqe/socket_watcher_unittest.cc
@@ -33,7 +33,7 @@
   static void OnUpdatedRTTAvailableStoreParams(
       SocketPerformanceWatcherFactory::Protocol protocol,
       const base::TimeDelta& rtt,
-      const absl::optional<IPHash>& host) {
+      const std::optional<IPHash>& host) {
     // Need to verify before another callback is executed, or explicitly call
     // |ResetCallbackParams()|.
     ASSERT_FALSE(callback_executed_);
@@ -45,7 +45,7 @@
   static void OnUpdatedRTTAvailable(
       SocketPerformanceWatcherFactory::Protocol protocol,
       const base::TimeDelta& rtt,
-      const absl::optional<IPHash>& host) {
+      const std::optional<IPHash>& host) {
     // Need to verify before another callback is executed, or explicitly call
     // |ResetCallbackParams()|.
     ASSERT_FALSE(callback_executed_);
@@ -61,7 +61,7 @@
   }
 
   static void VerifyCallbackParams(const base::TimeDelta& rtt,
-                                   const absl::optional<IPHash>& host) {
+                                   const std::optional<IPHash>& host) {
     ASSERT_TRUE(callback_executed_);
     EXPECT_EQ(rtt, callback_rtt_);
     if (host)
@@ -73,7 +73,7 @@
 
   static void ResetExpectedCallbackParams() {
     callback_rtt_ = base::Milliseconds(0);
-    callback_host_ = absl::nullopt;
+    callback_host_ = std::nullopt;
     callback_executed_ = false;
     should_notify_rtt_callback_ = false;
   }
@@ -82,7 +82,7 @@
 
  private:
   static base::TimeDelta callback_rtt_;
-  static absl::optional<IPHash> callback_host_;
+  static std::optional<IPHash> callback_host_;
   static bool callback_executed_;
   static bool should_notify_rtt_callback_;
 };
@@ -90,8 +90,8 @@
 base::TimeDelta NetworkQualitySocketWatcherTest::callback_rtt_ =
     base::Milliseconds(0);
 
-absl::optional<IPHash> NetworkQualitySocketWatcherTest::callback_host_ =
-    absl::nullopt;
+std::optional<IPHash> NetworkQualitySocketWatcherTest::callback_host_ =
+    std::nullopt;
 
 bool NetworkQualitySocketWatcherTest::callback_executed_ = false;
 
diff --git a/net/nqe/throughput_analyzer_unittest.cc b/net/nqe/throughput_analyzer_unittest.cc
index 123e3e2..08a95c4 100644
--- a/net/nqe/throughput_analyzer_unittest.cc
+++ b/net/nqe/throughput_analyzer_unittest.cc
@@ -57,7 +57,7 @@
   // local.com resolves to a private IP address.
   host_resolver->rules()->AddRule("local.com", "127.0.0.1");
   host_resolver->LoadIntoCache(HostPortPair("local.com", 80),
-                               NetworkAnonymizationKey(), absl::nullopt);
+                               NetworkAnonymizationKey(), std::nullopt);
   // Hosts not listed here (e.g., "example.com") are treated as external. See
   // ThroughputAnalyzerTest.PrivateHost below.
 
@@ -215,14 +215,14 @@
     // empty NetworkAnonymizationKey.
     mock_host_resolver->rules()->AddRule(kUrl.host(), "1.2.3.4");
     mock_host_resolver->LoadIntoCache(HostPortPair::FromURL(kUrl),
-                                      NetworkAnonymizationKey(), absl::nullopt);
+                                      NetworkAnonymizationKey(), std::nullopt);
 
     // Add an entry to the host cache mapping kUrl to local IP when using
     // kNetworkAnonymizationKey.
     mock_host_resolver->rules()->ClearRules();
     mock_host_resolver->rules()->AddRule(kUrl.host(), "127.0.0.1");
     mock_host_resolver->LoadIntoCache(HostPortPair::FromURL(kUrl),
-                                      kNetworkAnonymizationKey, absl::nullopt);
+                                      kNetworkAnonymizationKey, std::nullopt);
 
     context_builder->set_host_resolver(std::move(mock_host_resolver));
     auto context = context_builder->Build();
diff --git a/net/proxy_resolution/configured_proxy_resolution_service.cc b/net/proxy_resolution/configured_proxy_resolution_service.cc
index 5cc04a7e..ec65e84 100644
--- a/net/proxy_resolution/configured_proxy_resolution_service.cc
+++ b/net/proxy_resolution/configured_proxy_resolution_service.cc
@@ -337,7 +337,7 @@
 
 // Returns NetLog parameters describing a proxy configuration change.
 base::Value::Dict NetLogProxyConfigChangedParams(
-    const absl::optional<ProxyConfigWithAnnotation>* old_config,
+    const std::optional<ProxyConfigWithAnnotation>* old_config,
     const ProxyConfigWithAnnotation* new_config) {
   base::Value::Dict dict;
   // The "old_config" is optional -- the first notification will not have
@@ -1361,9 +1361,9 @@
   init_proxy_resolver_.reset();
   SuspendAllPendingRequests();
   resolver_.reset();
-  config_ = absl::nullopt;
+  config_ = std::nullopt;
   if (reset_fetched_config)
-    fetched_config_ = absl::nullopt;
+    fetched_config_ = std::nullopt;
   current_state_ = STATE_NONE;
 
   return previous_state;
diff --git a/net/proxy_resolution/configured_proxy_resolution_service.h b/net/proxy_resolution/configured_proxy_resolution_service.h
index af361e54..409a571 100644
--- a/net/proxy_resolution/configured_proxy_resolution_service.h
+++ b/net/proxy_resolution/configured_proxy_resolution_service.h
@@ -8,6 +8,7 @@
 #include <stddef.h>
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
@@ -29,7 +30,6 @@
 #include "net/proxy_resolution/proxy_resolution_service.h"
 #include "net/proxy_resolution/proxy_resolver.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace base {
@@ -154,12 +154,12 @@
   void OnShutdown() override;
 
   // Returns the last configuration fetched from ProxyConfigService.
-  const absl::optional<ProxyConfigWithAnnotation>& fetched_config() const {
+  const std::optional<ProxyConfigWithAnnotation>& fetched_config() const {
     return fetched_config_;
   }
 
   // Returns the current configuration being used by ProxyConfigService.
-  const absl::optional<ProxyConfigWithAnnotation>& config() const {
+  const std::optional<ProxyConfigWithAnnotation>& config() const {
     return config_;
   }
 
@@ -362,8 +362,8 @@
   // and custom PAC url).
   //
   // These are "optional" as their value remains unset while being calculated.
-  absl::optional<ProxyConfigWithAnnotation> fetched_config_;
-  absl::optional<ProxyConfigWithAnnotation> config_;
+  std::optional<ProxyConfigWithAnnotation> fetched_config_;
+  std::optional<ProxyConfigWithAnnotation> config_;
 
   // Map of the known bad proxies and the information about the retry time.
   ProxyRetryInfoMap proxy_retry_info_;
diff --git a/net/proxy_resolution/network_delegate_error_observer_unittest.cc b/net/proxy_resolution/network_delegate_error_observer_unittest.cc
index f53faca..93603ca 100644
--- a/net/proxy_resolution/network_delegate_error_observer_unittest.cc
+++ b/net/proxy_resolution/network_delegate_error_observer_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "net/proxy_resolution/network_delegate_error_observer.h"
 
+#include <optional>
+
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/location.h"
@@ -14,7 +16,6 @@
 #include "net/base/net_errors.h"
 #include "net/base/network_delegate_impl.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
diff --git a/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc b/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc
index f4663683..f0099c4f 100644
--- a/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc
+++ b/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "net/proxy_resolution/pac_file_fetcher_impl.h"
 
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -49,7 +50,6 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using net::test::IsError;
 using net::test::IsOk;
diff --git a/net/proxy_resolution/proxy_config_service_linux.cc b/net/proxy_resolution/proxy_config_service_linux.cc
index ed483ef6..1256fe4d 100644
--- a/net/proxy_resolution/proxy_config_service_linux.cc
+++ b/net/proxy_resolution/proxy_config_service_linux.cc
@@ -106,7 +106,7 @@
 }
 
 ProxyConfigWithAnnotation GetConfigOrDirect(
-    const absl::optional<ProxyConfigWithAnnotation>& optional_config) {
+    const std::optional<ProxyConfigWithAnnotation>& optional_config) {
   if (optional_config)
     return optional_config.value();
 
@@ -148,7 +148,7 @@
                                      result_chain);
 }
 
-absl::optional<ProxyConfigWithAnnotation>
+std::optional<ProxyConfigWithAnnotation>
 ProxyConfigServiceLinux::Delegate::GetConfigFromEnv() {
   ProxyConfig config;
 
@@ -219,7 +219,7 @@
     return !no_proxy.empty()
                ? ProxyConfigWithAnnotation(
                      config, NetworkTrafficAnnotationTag(traffic_annotation_))
-               : absl::optional<ProxyConfigWithAnnotation>();
+               : std::optional<ProxyConfigWithAnnotation>();
   }
   // Note that this uses "suffix" matching. So a bypass of "google.com"
   // is understood to mean a bypass of "*google.com".
@@ -1070,7 +1070,7 @@
   return false;
 }
 
-absl::optional<ProxyConfigWithAnnotation>
+std::optional<ProxyConfigWithAnnotation>
 ProxyConfigServiceLinux::Delegate::GetConfigFromSettings() {
   ProxyConfig config;
   config.set_from_system(true);
@@ -1079,7 +1079,7 @@
   if (!setting_getter_->GetString(SettingGetter::PROXY_MODE, &mode)) {
     // We expect this to always be set, so if we don't see it then we probably
     // have a gsettings problem, and so we don't have a valid proxy config.
-    return absl::nullopt;
+    return std::nullopt;
   }
   if (mode == "none") {
     // Specifically specifies no proxy.
@@ -1098,7 +1098,7 @@
           pac_url_str = "file://" + pac_url_str;
         GURL pac_url(pac_url_str);
         if (!pac_url.is_valid())
-          return absl::nullopt;
+          return std::nullopt;
         config.set_pac_url(pac_url);
         return ProxyConfigWithAnnotation(
             config, NetworkTrafficAnnotationTag(traffic_annotation_));
@@ -1111,7 +1111,7 @@
 
   if (mode != "manual") {
     // Mode is unrecognized.
-    return absl::nullopt;
+    return std::nullopt;
   }
   bool use_http_proxy;
   if (setting_getter_->GetBool(SettingGetter::PROXY_USE_HTTP_PROXY,
@@ -1175,7 +1175,7 @@
 
   if (config.proxy_rules().empty()) {
     // Manual mode but we couldn't parse any rules.
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Check for authentication, just so we can warn.
@@ -1216,8 +1216,8 @@
 
 ProxyConfigServiceLinux::Delegate::Delegate(
     std::unique_ptr<base::Environment> env_var_getter,
-    absl::optional<std::unique_ptr<SettingGetter>> setting_getter,
-    absl::optional<NetworkTrafficAnnotationTag> traffic_annotation)
+    std::optional<std::unique_ptr<SettingGetter>> setting_getter,
+    std::optional<NetworkTrafficAnnotationTag> traffic_annotation)
     : env_var_getter_(std::move(env_var_getter)) {
   if (traffic_annotation) {
     traffic_annotation_ =
@@ -1291,7 +1291,7 @@
   // does so even if the proxy mode is set to auto, which would
   // mislead us.
 
-  cached_config_ = absl::nullopt;
+  cached_config_ = std::nullopt;
   if (setting_getter_ && setting_getter_->Init(glib_task_runner)) {
     cached_config_ = GetConfigFromSettings();
   }
@@ -1387,8 +1387,7 @@
   scoped_refptr<base::SequencedTaskRunner> required_loop =
       setting_getter_->GetNotificationTaskRunner();
   DCHECK(!required_loop.get() || required_loop->RunsTasksInCurrentSequence());
-  absl::optional<ProxyConfigWithAnnotation> new_config =
-      GetConfigFromSettings();
+  std::optional<ProxyConfigWithAnnotation> new_config = GetConfigFromSettings();
 
   // See if it is different from what we had before.
   if (new_config.has_value() != reference_config_.has_value() ||
@@ -1408,7 +1407,7 @@
 }
 
 void ProxyConfigServiceLinux::Delegate::SetNewProxyConfig(
-    const absl::optional<ProxyConfigWithAnnotation>& new_config) {
+    const std::optional<ProxyConfigWithAnnotation>& new_config) {
   DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
   VLOG(1) << "Proxy configuration changed";
   cached_config_ = new_config;
@@ -1445,8 +1444,8 @@
 
 ProxyConfigServiceLinux::ProxyConfigServiceLinux()
     : delegate_(base::MakeRefCounted<Delegate>(base::Environment::Create(),
-                                               absl::nullopt,
-                                               absl::nullopt)) {}
+                                               std::nullopt,
+                                               std::nullopt)) {}
 
 ProxyConfigServiceLinux::~ProxyConfigServiceLinux() {
   delegate_->PostDestroyTask();
@@ -1456,7 +1455,7 @@
     std::unique_ptr<base::Environment> env_var_getter,
     const NetworkTrafficAnnotationTag& traffic_annotation)
     : delegate_(base::MakeRefCounted<Delegate>(std::move(env_var_getter),
-                                               absl::nullopt,
+                                               std::nullopt,
                                                traffic_annotation)) {}
 
 ProxyConfigServiceLinux::ProxyConfigServiceLinux(
diff --git a/net/proxy_resolution/proxy_config_service_linux.h b/net/proxy_resolution/proxy_config_service_linux.h
index 63a386b..0c0c998 100644
--- a/net/proxy_resolution/proxy_config_service_linux.h
+++ b/net/proxy_resolution/proxy_config_service_linux.h
@@ -8,6 +8,7 @@
 #include <stddef.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -20,7 +21,6 @@
 #include "net/base/proxy_server.h"
 #include "net/proxy_resolution/proxy_config_service.h"
 #include "net/proxy_resolution/proxy_config_with_annotation.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class SingleThreadTaskRunner;
@@ -173,8 +173,8 @@
     // Test code can set |setting_getter| and |traffic_annotation|. If left
     // unspecified, reasonable defaults will be used.
     Delegate(std::unique_ptr<base::Environment> env_var_getter,
-             absl::optional<std::unique_ptr<SettingGetter>> setting_getter,
-             absl::optional<NetworkTrafficAnnotationTag> traffic_annotation);
+             std::optional<std::unique_ptr<SettingGetter>> setting_getter,
+             std::optional<NetworkTrafficAnnotationTag> traffic_annotation);
 
     Delegate(const Delegate&) = delete;
     Delegate& operator=(const Delegate&) = delete;
@@ -228,7 +228,7 @@
                             ProxyChain* result_chain);
     // Returns a proxy config based on the environment variables, or empty value
     // on failure.
-    absl::optional<ProxyConfigWithAnnotation> GetConfigFromEnv();
+    std::optional<ProxyConfigWithAnnotation> GetConfigFromEnv();
 
     // Obtains host and port config settings and parses a proxy server
     // specification from it and puts it in result. Returns true if the
@@ -237,12 +237,12 @@
                               ProxyServer* result_server);
     // Returns a proxy config based on the settings, or empty value
     // on failure.
-    absl::optional<ProxyConfigWithAnnotation> GetConfigFromSettings();
+    std::optional<ProxyConfigWithAnnotation> GetConfigFromSettings();
 
     // This method is posted from the glib thread to the main TaskRunner to
     // carry the new config information.
     void SetNewProxyConfig(
-        const absl::optional<ProxyConfigWithAnnotation>& new_config);
+        const std::optional<ProxyConfigWithAnnotation>& new_config);
 
     // This method is run on the getter's notification thread.
     void SetUpNotifications();
@@ -253,12 +253,12 @@
     // Cached proxy configuration, to be returned by
     // GetLatestProxyConfig. Initially populated from the glib thread, but
     // afterwards only accessed from the main TaskRunner.
-    absl::optional<ProxyConfigWithAnnotation> cached_config_;
+    std::optional<ProxyConfigWithAnnotation> cached_config_;
 
     // A copy kept on the glib thread of the last seen proxy config, so as
     // to avoid posting a call to SetNewProxyConfig when we get a
     // notification but the config has not actually changed.
-    absl::optional<ProxyConfigWithAnnotation> reference_config_;
+    std::optional<ProxyConfigWithAnnotation> reference_config_;
 
     // The task runner for the glib thread, aka main browser thread. This thread
     // is where we run the glib main loop (see
diff --git a/net/proxy_resolution/proxy_info_unittest.cc b/net/proxy_resolution/proxy_info_unittest.cc
index 25da284..1fd3d4a 100644
--- a/net/proxy_resolution/proxy_info_unittest.cc
+++ b/net/proxy_resolution/proxy_info_unittest.cc
@@ -69,9 +69,9 @@
 
   ProxyChain ip_protection_proxy_chain = ProxyChain::ForIpProtection({
       ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTPS, "proxy1",
-                                         absl::nullopt),
+                                         std::nullopt),
       ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTPS, "proxy2",
-                                         absl::nullopt),
+                                         std::nullopt),
   });
   info.UseProxyChain(ip_protection_proxy_chain);
   EXPECT_TRUE(info.is_for_ip_protection());
diff --git a/net/proxy_resolution/proxy_list.h b/net/proxy_resolution/proxy_list.h
index b68f33b7..d7db976 100644
--- a/net/proxy_resolution/proxy_list.h
+++ b/net/proxy_resolution/proxy_list.h
@@ -8,13 +8,13 @@
 #include <stddef.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "net/base/net_export.h"
 #include "net/base/proxy_server.h"
 #include "net/proxy_resolution/proxy_retry_info.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class TimeDelta;
diff --git a/net/quic/bidirectional_stream_quic_impl.cc b/net/quic/bidirectional_stream_quic_impl.cc
index 42526eba..b4cc447 100644
--- a/net/quic/bidirectional_stream_quic_impl.cc
+++ b/net/quic/bidirectional_stream_quic_impl.cc
@@ -116,7 +116,7 @@
   http_request_info.method = request_info_->method;
   http_request_info.extra_headers = request_info_->extra_headers;
 
-  CreateSpdyHeadersFromHttpRequest(http_request_info, absl::nullopt,
+  CreateSpdyHeadersFromHttpRequest(http_request_info, std::nullopt,
                                    http_request_info.extra_headers, &headers);
   int rv = stream_->WriteHeaders(std::move(headers),
                                  request_info_->end_stream_on_headers, nullptr);
diff --git a/net/quic/dedicated_web_transport_http3_client.cc b/net/quic/dedicated_web_transport_http3_client.cc
index ff7e5a8..96e7abe 100644
--- a/net/quic/dedicated_web_transport_http3_client.cc
+++ b/net/quic/dedicated_web_transport_http3_client.cc
@@ -119,7 +119,7 @@
     NetLogWithSource& net_log,
     WebTransportState last_state,
     WebTransportState next_state,
-    const absl::optional<WebTransportError>& error) {
+    const std::optional<WebTransportError>& error) {
   net_log.AddEvent(
       NetLogEventType::QUIC_SESSION_WEBTRANSPORT_CLIENT_STATE_CHANGED, [&] {
         auto dict = base::Value::Dict()
@@ -239,11 +239,10 @@
     return stream_ptr;
   }
 
-  void OnDatagramProcessed(
-      absl::optional<quic::MessageStatus> status) override {
+  void OnDatagramProcessed(std::optional<quic::MessageStatus> status) override {
     client_->OnDatagramProcessed(
-        status.has_value() ? absl::optional<quic::MessageStatus>(*status)
-                           : absl::optional<quic::MessageStatus>());
+        status.has_value() ? std::optional<quic::MessageStatus>(*status)
+                           : std::optional<quic::MessageStatus>());
   }
 
  private:
@@ -414,7 +413,7 @@
 }
 
 void DedicatedWebTransportHttp3Client::Close(
-    const absl::optional<WebTransportCloseInfo>& close_info) {
+    const std::optional<WebTransportCloseInfo>& close_info) {
   CHECK(session());
   base::TimeDelta probe_timeout = base::Microseconds(
       connection_->sent_packet_manager().GetPtoDelay().ToMicroseconds());
@@ -549,7 +548,7 @@
   next_connect_state_ = CONNECT_STATE_RESOLVE_HOST_COMPLETE;
   HostResolver::ResolveHostParameters parameters;
   resolve_host_request_ = context_->host_resolver()->CreateRequest(
-      url::SchemeHostPort(url_), anonymization_key_, net_log_, absl::nullopt);
+      url::SchemeHostPort(url_), anonymization_key_, net_log_, std::nullopt);
   return resolve_host_request_->Start(base::BindOnce(
       &DedicatedWebTransportHttp3Client::DoLoop, base::Unretained(this)));
 }
@@ -972,7 +971,7 @@
 }
 
 void DedicatedWebTransportHttp3Client::OnDatagramProcessed(
-    absl::optional<quic::MessageStatus> status) {
+    std::optional<quic::MessageStatus> status) {
   visitor_->OnDatagramProcessed(status);
 }
 
diff --git a/net/quic/dedicated_web_transport_http3_client.h b/net/quic/dedicated_web_transport_http3_client.h
index 44605eb..d3674db9 100644
--- a/net/quic/dedicated_web_transport_http3_client.h
+++ b/net/quic/dedicated_web_transport_http3_client.h
@@ -5,6 +5,8 @@
 #ifndef NET_QUIC_DEDICATED_WEB_TRANSPORT_HTTP3_CLIENT_H_
 #define NET_QUIC_DEDICATED_WEB_TRANSPORT_HTTP3_CLIENT_H_
 
+#include <optional>
+
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/task/sequenced_task_runner.h"
@@ -27,7 +29,6 @@
 #include "net/third_party/quiche/src/quiche/quic/core/quic_connection_id.h"
 #include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
 #include "net/third_party/quiche/src/quiche/quic/core/web_transport_interface.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -59,7 +60,7 @@
   // Connect() is an asynchronous operation.  Once the operation is finished,
   // OnConnected() or OnConnectionFailed() is called on the Visitor.
   void Connect() override;
-  void Close(const absl::optional<WebTransportCloseInfo>& close_info) override;
+  void Close(const std::optional<WebTransportCloseInfo>& close_info) override;
 
   quic::WebTransportSession* session() override;
 
@@ -69,7 +70,7 @@
   void OnConnectStreamAborted();
   void OnConnectStreamDeleted();
   void OnCloseTimeout();
-  void OnDatagramProcessed(absl::optional<quic::MessageStatus> status);
+  void OnDatagramProcessed(std::optional<quic::MessageStatus> status);
 
   // QuicTransportClientSession::ClientVisitor methods.
   void OnSessionReady() override;
@@ -165,7 +166,7 @@
 
   WebTransportState state_ = WebTransportState::NEW;
   ConnectState next_connect_state_ = CONNECT_STATE_NONE;
-  absl::optional<WebTransportError> error_;
+  std::optional<WebTransportError> error_;
   bool retried_with_new_version_ = false;
   bool session_ready_ = false;
   bool safe_to_report_error_details_ = false;
@@ -184,7 +185,7 @@
   quic::DeterministicConnectionIdGenerator connection_id_generator_{
       quic::kQuicDefaultConnectionIdLength};
 
-  absl::optional<WebTransportCloseInfo> close_info_;
+  std::optional<WebTransportCloseInfo> close_info_;
 
   base::OneShotTimer close_timeout_timer_;
   base::WeakPtrFactory<DedicatedWebTransportHttp3Client> weak_factory_{this};
diff --git a/net/quic/dedicated_web_transport_http3_client_test.cc b/net/quic/dedicated_web_transport_http3_client_test.cc
index 2670c19..d93455c 100644
--- a/net/quic/dedicated_web_transport_http3_client_test.cc
+++ b/net/quic/dedicated_web_transport_http3_client_test.cc
@@ -46,7 +46,7 @@
   MOCK_METHOD(void, OnConnectionFailed, (const WebTransportError&), (override));
   MOCK_METHOD(void,
               OnClosed,
-              (const absl::optional<WebTransportCloseInfo>&),
+              (const std::optional<WebTransportCloseInfo>&),
               (override));
   MOCK_METHOD(void, OnError, (const WebTransportError&), (override));
 
@@ -55,7 +55,7 @@
   MOCK_METHOD1(OnDatagramReceived, void(base::StringPiece));
   MOCK_METHOD0(OnCanCreateNewOutgoingBidirectionalStream, void());
   MOCK_METHOD0(OnCanCreateNewOutgoingUnidirectionalStream, void());
-  MOCK_METHOD1(OnDatagramProcessed, void(absl::optional<quic::MessageStatus>));
+  MOCK_METHOD1(OnDatagramProcessed, void(std::optional<quic::MessageStatus>));
 };
 
 // A clock that only mocks out WallNow(), but uses real Now() and
@@ -199,7 +199,7 @@
   Run();
   ASSERT_TRUE(client_->session() != nullptr);
 
-  client_->Close(absl::nullopt);
+  client_->Close(std::nullopt);
   EXPECT_CALL(visitor_, OnClosed(_)).WillOnce(StopRunning());
   Run();
 }
@@ -231,7 +231,7 @@
   noop_socket->AllowAddressReuse();
   ASSERT_GE(noop_socket->Listen(bind_address), 0);
 
-  client_->Close(absl::nullopt);
+  client_->Close(std::nullopt);
   EXPECT_CALL(visitor_, OnError(_)).WillOnce(StopRunning());
   Run();
 }
@@ -254,7 +254,7 @@
   EXPECT_TRUE(stream->SendFin());
 
   WebTransportCloseInfo close_info(42, "test error");
-  absl::optional<WebTransportCloseInfo> received_close_info;
+  std::optional<WebTransportCloseInfo> received_close_info;
   EXPECT_CALL(visitor_, OnClosed(_))
       .WillOnce(DoAll(StopRunning(), SaveArg<0>(&received_close_info)));
   Run();
diff --git a/net/quic/quic_chromium_packet_writer.cc b/net/quic/quic_chromium_packet_writer.cc
index 4964b544..00796a9 100644
--- a/net/quic/quic_chromium_packet_writer.cc
+++ b/net/quic/quic_chromium_packet_writer.cc
@@ -201,7 +201,7 @@
   write_in_progress_ = false;
 }
 
-absl::optional<int> QuicChromiumPacketWriter::MessageTooBigErrorCode() const {
+std::optional<int> QuicChromiumPacketWriter::MessageTooBigErrorCode() const {
   return ERR_MSG_TOO_BIG;
 }
 
diff --git a/net/quic/quic_chromium_packet_writer.h b/net/quic/quic_chromium_packet_writer.h
index 9694705..f529254 100644
--- a/net/quic/quic_chromium_packet_writer.h
+++ b/net/quic/quic_chromium_packet_writer.h
@@ -96,7 +96,7 @@
       const quic::QuicPacketWriterParams& params) override;
   bool IsWriteBlocked() const override;
   void SetWritable() override;
-  absl::optional<int> MessageTooBigErrorCode() const override;
+  std::optional<int> MessageTooBigErrorCode() const override;
   quic::QuicByteCount GetMaxPacketSize(
       const quic::QuicSocketAddress& peer_address) const override;
   bool SupportsReleaseTime() const override;
diff --git a/net/quic/quic_connectivity_monitor.cc b/net/quic/quic_connectivity_monitor.cc
index 1d369a6a..6bc84cf 100644
--- a/net/quic/quic_connectivity_monitor.cc
+++ b/net/quic/quic_connectivity_monitor.cc
@@ -149,7 +149,7 @@
 
   num_all_degraded_sessions_ = 0u;
   num_sessions_active_during_current_speculative_connectivity_failure_ =
-      absl::nullopt;
+      std::nullopt;
 }
 
 void QuicConnectivityMonitor::OnSessionEncounteringWriteError(
@@ -229,7 +229,7 @@
   active_sessions_.clear();
   degrading_sessions_.clear();
   num_sessions_active_during_current_speculative_connectivity_failure_ =
-      absl::nullopt;
+      std::nullopt;
   write_error_map_.clear();
   quic_error_map_.clear();
 }
diff --git a/net/quic/quic_connectivity_monitor.h b/net/quic/quic_connectivity_monitor.h
index 273e1b3a..42eae9e 100644
--- a/net/quic/quic_connectivity_monitor.h
+++ b/net/quic/quic_connectivity_monitor.h
@@ -104,7 +104,7 @@
   //   related packet write error,
   // - ends immediately by the detection of path recovery or a network change.
   // Use clamped math to cap number of sessions at INT_MAX.
-  absl::optional<base::ClampedNumeric<int>>
+  std::optional<base::ClampedNumeric<int>>
       num_sessions_active_during_current_speculative_connectivity_failure_;
   // Total number of sessions that has been degraded before any recovery,
   // including no longer active sessions.
diff --git a/net/quic/quic_context.h b/net/quic/quic_context.h
index aaa6b3ed..231da97 100644
--- a/net/quic/quic_context.h
+++ b/net/quic/quic_context.h
@@ -200,11 +200,11 @@
   // (best effort).
   int ios_network_service_type = 0;
   // Delay for the 1st time the alternative service is marked broken.
-  absl::optional<base::TimeDelta> initial_delay_for_broken_alternative_service;
+  std::optional<base::TimeDelta> initial_delay_for_broken_alternative_service;
   // If true, the delay for broke alternative service would be initial_delay *
   // (1 << broken_count). Otherwise, the delay would be initial_delay, 5min,
   // 10min and so on.
-  absl::optional<bool> exponential_backoff_on_initial_delay;
+  std::optional<bool> exponential_backoff_on_initial_delay;
   // If true, delay main job even the request can be sent immediately on an
   // available SPDY session.
   bool delay_main_job_with_available_spdy_session = false;
diff --git a/net/quic/quic_http_stream.cc b/net/quic/quic_http_stream.cc
index 1cfbbd6..23a1ac4 100644
--- a/net/quic/quic_http_stream.cc
+++ b/net/quic/quic_http_stream.cc
@@ -350,14 +350,14 @@
   return session()->GetAcceptChViaAlps(url::SchemeHostPort(request_info_->url));
 }
 
-absl::optional<quic::QuicErrorCode> QuicHttpStream::GetQuicErrorCode() const {
+std::optional<quic::QuicErrorCode> QuicHttpStream::GetQuicErrorCode() const {
   if (stream_) {
     return stream_->connection_error();
   }
   return connection_error_;
 }
 
-absl::optional<quic::QuicRstStreamErrorCode>
+std::optional<quic::QuicRstStreamErrorCode>
 QuicHttpStream::GetQuicRstStreamErrorCode() const {
   if (stream_) {
     return stream_->stream_error();
diff --git a/net/quic/quic_http_stream.h b/net/quic/quic_http_stream.h
index 6a04f07..1f3591b17 100644
--- a/net/quic/quic_http_stream.h
+++ b/net/quic/quic_http_stream.h
@@ -75,8 +75,8 @@
   void SetRequestIdempotency(Idempotency idempotency) override;
   const std::set<std::string>& GetDnsAliases() const override;
   base::StringPiece GetAcceptChViaAlps() const override;
-  absl::optional<quic::QuicErrorCode> GetQuicErrorCode() const override;
-  absl::optional<quic::QuicRstStreamErrorCode> GetQuicRstStreamErrorCode()
+  std::optional<quic::QuicErrorCode> GetQuicErrorCode() const override;
+  std::optional<quic::QuicRstStreamErrorCode> GetQuicRstStreamErrorCode()
       const override;
 
   static HttpConnectionInfo ConnectionInfoFromQuicVersion(
@@ -204,8 +204,8 @@
   // the default value of false.
   bool closed_is_first_stream_ = false;
 
-  absl::optional<quic::QuicErrorCode> connection_error_;
-  absl::optional<quic::QuicRstStreamErrorCode> stream_error_;
+  std::optional<quic::QuicErrorCode> connection_error_;
+  std::optional<quic::QuicRstStreamErrorCode> stream_error_;
 
   // The caller's callback to be used for asynchronous operations.
   CompletionOnceCallback callback_;
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc
index 01eb1da..4ada5cb 100644
--- a/net/quic/quic_network_transaction_unittest.cc
+++ b/net/quic/quic_network_transaction_unittest.cc
@@ -7496,7 +7496,7 @@
       EXPECT_EQ(407, response->headers->response_code());
       EXPECT_EQ(10, response->headers->GetContentLength());
       EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
-      absl::optional<AuthChallengeInfo> auth_challenge =
+      std::optional<AuthChallengeInfo> auth_challenge =
           response->auth_challenge;
       ASSERT_TRUE(auth_challenge.has_value());
       EXPECT_TRUE(auth_challenge->is_proxy);
diff --git a/net/quic/quic_proxy_client_socket.cc b/net/quic/quic_proxy_client_socket.cc
index 12df2d8..a663ea7 100644
--- a/net/quic/quic_proxy_client_socket.cc
+++ b/net/quic/quic_proxy_client_socket.cc
@@ -355,7 +355,7 @@
                        request_line, &request_.extra_headers);
 
   spdy::Http2HeaderBlock headers;
-  CreateSpdyHeadersFromHttpRequest(request_, absl::nullopt,
+  CreateSpdyHeadersFromHttpRequest(request_, std::nullopt,
                                    request_.extra_headers, &headers);
 
   return stream_->WriteHeaders(std::move(headers), false, nullptr);
diff --git a/net/quic/quic_test_packet_printer.cc b/net/quic/quic_test_packet_printer.cc
index 080ffa2..149f2aa 100644
--- a/net/quic/quic_test_packet_printer.cc
+++ b/net/quic/quic_test_packet_printer.cc
@@ -97,7 +97,7 @@
     return true;
   }
   bool OnAckFrameEnd(QuicPacketNumber start,
-                     const absl::optional<QuicEcnCounts>& ecn_counts) override {
+                     const std::optional<QuicEcnCounts>& ecn_counts) override {
     *output_ << "OnAckFrameEnd, start: " << start << ", "
              << ecn_counts.value_or(QuicEcnCounts()).ToString() << "\n";
     return true;
diff --git a/net/quic/web_transport_client.cc b/net/quic/web_transport_client.cc
index ee9b5f6..cf19e956 100644
--- a/net/quic/web_transport_client.cc
+++ b/net/quic/web_transport_client.cc
@@ -21,7 +21,7 @@
                /*safe_to_report_details=*/true),
         visitor_(visitor) {}
   void Connect() override { visitor_->OnConnectionFailed(error_); }
-  void Close(const absl::optional<WebTransportCloseInfo>& close_info) override {
+  void Close(const std::optional<WebTransportCloseInfo>& close_info) override {
     NOTREACHED();
   }
 
diff --git a/net/quic/web_transport_client.h b/net/quic/web_transport_client.h
index fd4b312..1c3e9cea 100644
--- a/net/quic/web_transport_client.h
+++ b/net/quic/web_transport_client.h
@@ -5,6 +5,7 @@
 #ifndef NET_QUIC_WEB_TRANSPORT_CLIENT_H_
 #define NET_QUIC_WEB_TRANSPORT_CLIENT_H_
 
+#include <optional>
 #include <vector>
 
 #include "base/memory/scoped_refptr.h"
@@ -14,7 +15,6 @@
 #include "net/third_party/quiche/src/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.h"
 #include "net/third_party/quiche/src/quiche/quic/core/quic_types.h"
 #include "net/third_party/quiche/src/quiche/quic/core/web_transport_interface.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -81,7 +81,7 @@
   virtual void OnConnectionFailed(const WebTransportError& error) = 0;
   // CONNECTED -> CLOSED
   virtual void OnClosed(
-      const absl::optional<WebTransportCloseInfo>& close_info) = 0;
+      const std::optional<WebTransportCloseInfo>& close_info) = 0;
   // CONNECTED -> FAILED
   virtual void OnError(const WebTransportError& error) = 0;
 
@@ -91,7 +91,7 @@
   virtual void OnCanCreateNewOutgoingBidirectionalStream() = 0;
   virtual void OnCanCreateNewOutgoingUnidirectionalStream() = 0;
   virtual void OnDatagramProcessed(
-      absl::optional<quic::MessageStatus> status) = 0;
+      std::optional<quic::MessageStatus> status) = 0;
 };
 
 // Parameters that determine the way WebTransport session is established.
@@ -126,7 +126,7 @@
   // when the state is CONNECTED. The associated visitor is still waiting for
   // OnClosed or OnError to be called.
   virtual void Close(
-      const absl::optional<WebTransportCloseInfo>& close_info) = 0;
+      const std::optional<WebTransportCloseInfo>& close_info) = 0;
 
   // session() can be nullptr in states other than CONNECTED.
   virtual quic::WebTransportSession* session() = 0;
diff --git a/net/reporting/reporting_browsing_data_remover_unittest.cc b/net/reporting/reporting_browsing_data_remover_unittest.cc
index 12d6649..3cb9a53 100644
--- a/net/reporting/reporting_browsing_data_remover_unittest.cc
+++ b/net/reporting/reporting_browsing_data_remover_unittest.cc
@@ -44,7 +44,7 @@
 
   // TODO(chlily): Take NAK.
   void AddReport(const GURL& url) {
-    cache()->AddReport(absl::nullopt, NetworkAnonymizationKey(), url,
+    cache()->AddReport(std::nullopt, NetworkAnonymizationKey(), url,
                        kUserAgent_, kGroup_, kType_, base::Value::Dict(), 0,
                        tick_clock()->NowTicks(), 0);
   }
diff --git a/net/reporting/reporting_cache.h b/net/reporting/reporting_cache.h
index 3fe4c2a..83236f44 100644
--- a/net/reporting/reporting_cache.h
+++ b/net/reporting/reporting_cache.h
@@ -6,6 +6,7 @@
 #define NET_REPORTING_REPORTING_CACHE_H_
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
@@ -21,7 +22,6 @@
 #include "net/reporting/reporting_endpoint.h"
 #include "net/reporting/reporting_header_parser.h"
 #include "net/reporting/reporting_report.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -68,7 +68,7 @@
   // All other parameters correspond to the desired values for the relevant
   // fields in ReportingReport.
   virtual void AddReport(
-      const absl::optional<base::UnguessableToken>& reporting_source,
+      const std::optional<base::UnguessableToken>& reporting_source,
       const NetworkAnonymizationKey& network_anonymization_key,
       const GURL& url,
       const std::string& user_agent,
diff --git a/net/reporting/reporting_cache_impl.cc b/net/reporting/reporting_cache_impl.cc
index a588733..064616a 100644
--- a/net/reporting/reporting_cache_impl.cc
+++ b/net/reporting/reporting_cache_impl.cc
@@ -5,6 +5,7 @@
 #include "net/reporting/reporting_cache_impl.h"
 
 #include <algorithm>
+#include <optional>
 #include <unordered_map>
 #include <unordered_set>
 #include <utility>
@@ -18,7 +19,6 @@
 #include "net/base/network_anonymization_key.h"
 #include "net/base/url_util.h"
 #include "net/log/net_log.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -30,7 +30,7 @@
 ReportingCacheImpl::~ReportingCacheImpl() = default;
 
 void ReportingCacheImpl::AddReport(
-    const absl::optional<base::UnguessableToken>& reporting_source,
+    const std::optional<base::UnguessableToken>& reporting_source,
     const NetworkAnonymizationKey& network_anonymization_key,
     const GURL& url,
     const std::string& user_agent,
@@ -607,7 +607,7 @@
   auto endpoints_it = loaded_endpoints.begin();
   auto endpoint_groups_it = loaded_endpoint_groups.begin();
 
-  absl::optional<Client> client;
+  std::optional<Client> client;
 
   while (endpoint_groups_it != loaded_endpoint_groups.end() &&
          endpoints_it != loaded_endpoints.end()) {
@@ -660,7 +660,7 @@
         EnforcePerClientAndGlobalEndpointLimits(client_it);
       }
       DCHECK(FindClientIt(group_key) == clients_.end());
-      client = absl::make_optional(
+      client = std::make_optional(
           Client(group_key.network_anonymization_key, group_key.origin));
     }
     DCHECK(client.has_value());
@@ -1286,7 +1286,7 @@
 
     // This may invalidate |group_it| (and also possibly |client_it|), but only
     // if we are processing the last remaining endpoint in the group.
-    absl::optional<EndpointMap::iterator> next_it =
+    std::optional<EndpointMap::iterator> next_it =
         RemoveEndpointInternal(client_it, group_it, it);
     if (!next_it.has_value())
       return;
@@ -1342,7 +1342,7 @@
     store()->UpdateReportingEndpointGroupAccessTime(group_it->second);
 }
 
-absl::optional<ReportingCacheImpl::EndpointMap::iterator>
+std::optional<ReportingCacheImpl::EndpointMap::iterator>
 ReportingCacheImpl::RemoveEndpointInternal(ClientMap::iterator client_it,
                                            EndpointGroupMap::iterator group_it,
                                            EndpointMap::iterator endpoint_it) {
@@ -1356,7 +1356,7 @@
   // be removed if it becomes empty.
   if (endpoints_.count(group_key) == 1) {
     RemoveEndpointGroupInternal(client_it, group_it);
-    return absl::nullopt;
+    return std::nullopt;
   }
   // Otherwise, there are other endpoints in the group, so there is no chance
   // of needing to remove the group/client. Just remove this endpoint and
@@ -1369,7 +1369,7 @@
   return endpoints_.erase(endpoint_it);
 }
 
-absl::optional<ReportingCacheImpl::EndpointGroupMap::iterator>
+std::optional<ReportingCacheImpl::EndpointGroupMap::iterator>
 ReportingCacheImpl::RemoveEndpointGroupInternal(
     ClientMap::iterator client_it,
     EndpointGroupMap::iterator group_it,
@@ -1411,7 +1411,7 @@
   if (client.endpoint_count == 0) {
     DCHECK(client.endpoint_group_names.empty());
     clients_.erase(client_it);
-    return absl::nullopt;
+    return std::nullopt;
   }
   return rv;
 }
diff --git a/net/reporting/reporting_cache_impl.h b/net/reporting/reporting_cache_impl.h
index 225f063..6e71ba9 100644
--- a/net/reporting/reporting_cache_impl.h
+++ b/net/reporting/reporting_cache_impl.h
@@ -7,6 +7,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <unordered_set>
@@ -28,7 +29,6 @@
 #include "net/reporting/reporting_endpoint.h"
 #include "net/reporting/reporting_header_parser.h"
 #include "net/reporting/reporting_report.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -44,7 +44,7 @@
   ~ReportingCacheImpl() override;
 
   // ReportingCache implementation
-  void AddReport(const absl::optional<base::UnguessableToken>& reporting_source,
+  void AddReport(const std::optional<base::UnguessableToken>& reporting_source,
                  const NetworkAnonymizationKey& network_anonymization_key,
                  const GURL& url,
                  const std::string& user_agent,
@@ -276,10 +276,10 @@
   // Also takes iterators to the client and endpoint group to avoid repeated
   // lookups. May cause the client and/or group to be removed if they become
   // empty, which would invalidate those iterators.
-  // Returns the iterator following the endpoint removed, or absl::nullopt if
+  // Returns the iterator following the endpoint removed, or std::nullopt if
   // either of |group_it| or |client_it| were invalidated. (If |client_it| is
   // invalidated, then so must |group_it|).
-  absl::optional<EndpointMap::iterator> RemoveEndpointInternal(
+  std::optional<EndpointMap::iterator> RemoveEndpointInternal(
       ClientMap::iterator client_it,
       EndpointGroupMap::iterator group_it,
       EndpointMap::iterator endpoint_it);
@@ -290,9 +290,9 @@
   // invalidate |client_it|. If |num_endpoints_removed| is not null, then
   // |*num_endpoints_removed| is incremented by the number of endpoints
   // removed.
-  // Returns the iterator following the endpoint group removed, or absl::nullopt
+  // Returns the iterator following the endpoint group removed, or std::nullopt
   // if |client_it| was invalidated.
-  absl::optional<EndpointGroupMap::iterator> RemoveEndpointGroupInternal(
+  std::optional<EndpointGroupMap::iterator> RemoveEndpointGroupInternal(
       ClientMap::iterator client_it,
       EndpointGroupMap::iterator group_it,
       size_t* num_endpoints_removed = nullptr);
diff --git a/net/reporting/reporting_cache_unittest.cc b/net/reporting/reporting_cache_unittest.cc
index f37c4c8..6287454 100644
--- a/net/reporting/reporting_cache_unittest.cc
+++ b/net/reporting/reporting_cache_unittest.cc
@@ -123,9 +123,8 @@
     // in test cases, so I've optimized for readability over execution speed.
     std::vector<raw_ptr<const ReportingReport, VectorExperimental>> before;
     cache()->GetReports(&before);
-    cache()->AddReport(absl::nullopt, network_anonymization_key, url,
-                       user_agent, group, type, std::move(body), depth, queued,
-                       attempts);
+    cache()->AddReport(std::nullopt, network_anonymization_key, url, user_agent,
+                       group, type, std::move(body), depth, queued, attempts);
     std::vector<raw_ptr<const ReportingReport, VectorExperimental>> after;
     cache()->GetReports(&after);
 
@@ -183,7 +182,7 @@
   const GURL kUrl2_ = GURL("https://origin2/path");
   const url::Origin kOrigin1_ = url::Origin::Create(GURL("https://origin1/"));
   const url::Origin kOrigin2_ = url::Origin::Create(GURL("https://origin2/"));
-  const absl::optional<base::UnguessableToken> kReportingSource_ =
+  const std::optional<base::UnguessableToken> kReportingSource_ =
       base::UnguessableToken::Create();
   const NetworkAnonymizationKey kNak_;
   const NetworkAnonymizationKey kOtherNak_ =
@@ -502,8 +501,8 @@
                      base::Value::Dict(), 0, kNowTicks_, 0);
   cache()->AddReport(source2, kNak_, kUrl1_, kUserAgent_, kGroup1_, kType_,
                      base::Value::Dict(), 0, kNowTicks_, 0);
-  cache()->AddReport(absl::nullopt, kNak_, kUrl1_, kUserAgent_, kGroup1_,
-                     kType_, base::Value::Dict(), 0, kNowTicks_, 0);
+  cache()->AddReport(std::nullopt, kNak_, kUrl1_, kUserAgent_, kGroup1_, kType_,
+                     base::Value::Dict(), 0, kNowTicks_, 0);
   EXPECT_EQ(3, observer()->cached_reports_update_count());
 
   std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
@@ -516,7 +515,7 @@
   const auto report2 =
       base::ranges::find(reports, source2, &ReportingReport::reporting_source);
   DCHECK(report2 != reports.end());
-  const auto report3 = base::ranges::find(reports, absl::nullopt,
+  const auto report3 = base::ranges::find(reports, std::nullopt,
                                           &ReportingReport::reporting_source);
   DCHECK(report3 != reports.end());
 
@@ -1133,7 +1132,7 @@
   SetV1EndpointInCache(kDocumentGroupKey, reporting_source, kIsolationInfo1_,
                        kEndpoint1_);
   const ReportingEndpointGroupKey kNetworkReportGroupKey =
-      ReportingEndpointGroupKey(network_anonymization_key, absl::nullopt,
+      ReportingEndpointGroupKey(network_anonymization_key, std::nullopt,
                                 kOrigin1_, kGroup1_);
   std::vector<ReportingEndpoint> candidate_endpoints =
       cache()->GetCandidateEndpointsForDelivery(kNetworkReportGroupKey);
@@ -1211,7 +1210,7 @@
   // returned.
   candidate_endpoints =
       cache()->GetCandidateEndpointsForDelivery(ReportingEndpointGroupKey(
-          network_anonymization_key1, absl::nullopt, kOrigin1_, kGroup1_));
+          network_anonymization_key1, std::nullopt, kOrigin1_, kGroup1_));
   ASSERT_EQ(2u, candidate_endpoints.size());
   EXPECT_EQ(group_key_11, candidate_endpoints[0].group_key);
   EXPECT_EQ(group_key_11, candidate_endpoints[1].group_key);
diff --git a/net/reporting/reporting_delivery_agent.cc b/net/reporting/reporting_delivery_agent.cc
index 52f6dfe..f9fd48b 100644
--- a/net/reporting/reporting_delivery_agent.cc
+++ b/net/reporting/reporting_delivery_agent.cc
@@ -96,7 +96,7 @@
            const NetworkAnonymizationKey& network_anonymization_key,
            const url::Origin& origin,
            const GURL& endpoint_url,
-           const absl::optional<base::UnguessableToken> reporting_source)
+           const std::optional<base::UnguessableToken> reporting_source)
         : isolation_info(isolation_info),
           network_anonymization_key(network_anonymization_key),
           origin(origin),
@@ -123,7 +123,7 @@
     NetworkAnonymizationKey network_anonymization_key;
     url::Origin origin;
     GURL endpoint_url;
-    absl::optional<base::UnguessableToken> reporting_source;
+    std::optional<base::UnguessableToken> reporting_source;
   };
 
   explicit Delivery(const Target& target) : target_(target) {}
diff --git a/net/reporting/reporting_delivery_agent_unittest.cc b/net/reporting/reporting_delivery_agent_unittest.cc
index cff79ba..94f5ce8 100644
--- a/net/reporting/reporting_delivery_agent_unittest.cc
+++ b/net/reporting/reporting_delivery_agent_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "net/reporting/reporting_delivery_agent.h"
 
+#include <optional>
 #include <vector>
 
 #include "base/json/json_reader.h"
@@ -26,7 +27,6 @@
 #include "net/reporting/reporting_test_util.h"
 #include "net/reporting/reporting_uploader.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -56,7 +56,7 @@
     UsePolicy(policy);
   }
 
-  void AddReport(const absl::optional<base::UnguessableToken>& reporting_source,
+  void AddReport(const std::optional<base::UnguessableToken>& reporting_source,
                  const NetworkAnonymizationKey& network_anonymization_key,
                  const GURL& url,
                  const std::string& group) {
@@ -78,7 +78,7 @@
         url::Origin::Create(GURL("https://dummy.test")), "dummy");
     ASSERT_TRUE(SetEndpointInCache(
         dummy_group, GURL("https://dummy.test/upload"), kExpires_));
-    AddReport(absl::nullopt, dummy_group.network_anonymization_key,
+    AddReport(std::nullopt, dummy_group.network_anonymization_key,
               dummy_group.origin.GetURL(), dummy_group.group_name);
 
     ASSERT_EQ(1u, pending_uploads().size());
@@ -116,8 +116,8 @@
   const url::Origin kOrigin_ = url::Origin::Create(GURL("https://origin/"));
   const url::Origin kOtherOrigin_ =
       url::Origin::Create(GURL("https://other-origin/"));
-  const absl::optional<base::UnguessableToken> kEmptyReportingSource_ =
-      absl::nullopt;
+  const std::optional<base::UnguessableToken> kEmptyReportingSource_ =
+      std::nullopt;
   const base::UnguessableToken kDocumentReportingSource_ =
       base::UnguessableToken::Create();
   const NetworkAnonymizationKey kNak_ =
diff --git a/net/reporting/reporting_endpoint.cc b/net/reporting/reporting_endpoint.cc
index eb62f5c8..2fe25db 100644
--- a/net/reporting/reporting_endpoint.cc
+++ b/net/reporting/reporting_endpoint.cc
@@ -21,13 +21,13 @@
     const url::Origin& origin,
     const std::string& group_name)
     : ReportingEndpointGroupKey(network_anonymization_key,
-                                absl::nullopt,
+                                std::nullopt,
                                 origin,
                                 group_name) {}
 
 ReportingEndpointGroupKey::ReportingEndpointGroupKey(
     const NetworkAnonymizationKey& network_anonymization_key,
-    absl::optional<base::UnguessableToken> reporting_source,
+    std::optional<base::UnguessableToken> reporting_source,
     const url::Origin& origin,
     const std::string& group_name)
     : network_anonymization_key(network_anonymization_key),
@@ -41,7 +41,7 @@
 
 ReportingEndpointGroupKey::ReportingEndpointGroupKey(
     const ReportingEndpointGroupKey& other,
-    const absl::optional<base::UnguessableToken>& reporting_source)
+    const std::optional<base::UnguessableToken>& reporting_source)
     : ReportingEndpointGroupKey(other.network_anonymization_key,
                                 reporting_source,
                                 other.origin,
diff --git a/net/reporting/reporting_endpoint.h b/net/reporting/reporting_endpoint.h
index 1b99c0c..6d85fa5 100644
--- a/net/reporting/reporting_endpoint.h
+++ b/net/reporting/reporting_endpoint.h
@@ -5,6 +5,7 @@
 #ifndef NET_REPORTING_REPORTING_ENDPOINT_H_
 #define NET_REPORTING_REPORTING_ENDPOINT_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -12,7 +13,6 @@
 #include "base/unguessable_token.h"
 #include "net/base/net_export.h"
 #include "net/base/network_anonymization_key.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -29,13 +29,13 @@
 
   ReportingEndpointGroupKey(
       const NetworkAnonymizationKey& network_anonymization_key,
-      absl::optional<base::UnguessableToken> reporting_source,
+      std::optional<base::UnguessableToken> reporting_source,
       const url::Origin& origin,
       const std::string& group_name);
 
   ReportingEndpointGroupKey(
       const ReportingEndpointGroupKey& other,
-      const absl::optional<base::UnguessableToken>& reporting_source);
+      const std::optional<base::UnguessableToken>& reporting_source);
 
   ReportingEndpointGroupKey(const ReportingEndpointGroupKey& other);
   ReportingEndpointGroupKey(ReportingEndpointGroupKey&& other);
@@ -58,7 +58,7 @@
   // Source token for the document or worker which configured this endpoint, if
   // this was configured with the Reporting-Endpoints header. For endpoint
   // groups configured with the Report-To header, this will be nullopt.
-  absl::optional<base::UnguessableToken> reporting_source;
+  std::optional<base::UnguessableToken> reporting_source;
 
   // Origin that configured this endpoint group.
   url::Origin origin;
diff --git a/net/reporting/reporting_endpoint_manager_unittest.cc b/net/reporting/reporting_endpoint_manager_unittest.cc
index 25f46b0a..7291ee4 100644
--- a/net/reporting/reporting_endpoint_manager_unittest.cc
+++ b/net/reporting/reporting_endpoint_manager_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "net/reporting/reporting_endpoint_manager.h"
 
+#include <optional>
 #include <string>
 
 #include "base/memory/raw_ptr.h"
@@ -20,7 +21,6 @@
 #include "net/reporting/reporting_policy.h"
 #include "net/reporting/reporting_test_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -56,7 +56,7 @@
   }
 
   // Everything below is NOTREACHED.
-  void AddReport(const absl::optional<base::UnguessableToken>& reporting_source,
+  void AddReport(const std::optional<base::UnguessableToken>& reporting_source,
                  const NetworkAnonymizationKey& network_anonymization_key,
                  const GURL& url,
                  const std::string& user_agent,
diff --git a/net/reporting/reporting_garbage_collector_unittest.cc b/net/reporting/reporting_garbage_collector_unittest.cc
index 9a2e161..497d2738 100644
--- a/net/reporting/reporting_garbage_collector_unittest.cc
+++ b/net/reporting/reporting_garbage_collector_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "net/reporting/reporting_garbage_collector.h"
 
+#include <optional>
 #include <string>
 
 #include "base/memory/raw_ptr.h"
@@ -17,7 +18,6 @@
 #include "net/reporting/reporting_report.h"
 #include "net/reporting/reporting_test_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 namespace {
@@ -30,7 +30,7 @@
     return reports.size();
   }
 
-  const absl::optional<base::UnguessableToken> kReportingSource_ =
+  const std::optional<base::UnguessableToken> kReportingSource_ =
       base::UnguessableToken::Create();
   const NetworkAnonymizationKey kNak_;
   const IsolationInfo kIsolationInfo_;
@@ -49,7 +49,7 @@
 TEST_F(ReportingGarbageCollectorTest, Timer) {
   EXPECT_FALSE(garbage_collection_timer()->IsRunning());
 
-  cache()->AddReport(absl::nullopt, kNak_, kUrl_, kUserAgent_, kGroup_, kType_,
+  cache()->AddReport(std::nullopt, kNak_, kUrl_, kUserAgent_, kGroup_, kType_,
                      base::Value::Dict(), 0, tick_clock()->NowTicks(), 0);
 
   EXPECT_TRUE(garbage_collection_timer()->IsRunning());
@@ -60,7 +60,7 @@
 }
 
 TEST_F(ReportingGarbageCollectorTest, Report) {
-  cache()->AddReport(absl::nullopt, kNak_, kUrl_, kUserAgent_, kGroup_, kType_,
+  cache()->AddReport(std::nullopt, kNak_, kUrl_, kUserAgent_, kGroup_, kType_,
                      base::Value::Dict(), 0, tick_clock()->NowTicks(), 0);
   garbage_collection_timer()->Fire();
 
@@ -68,7 +68,7 @@
 }
 
 TEST_F(ReportingGarbageCollectorTest, ExpiredReport) {
-  cache()->AddReport(absl::nullopt, kNak_, kUrl_, kUserAgent_, kGroup_, kType_,
+  cache()->AddReport(std::nullopt, kNak_, kUrl_, kUserAgent_, kGroup_, kType_,
                      base::Value::Dict(), 0, tick_clock()->NowTicks(), 0);
   tick_clock()->Advance(2 * policy().max_report_age);
   garbage_collection_timer()->Fire();
@@ -77,7 +77,7 @@
 }
 
 TEST_F(ReportingGarbageCollectorTest, FailedReport) {
-  cache()->AddReport(absl::nullopt, kNak_, kUrl_, kUserAgent_, kGroup_, kType_,
+  cache()->AddReport(std::nullopt, kNak_, kUrl_, kUserAgent_, kGroup_, kType_,
                      base::Value::Dict(), 0, tick_clock()->NowTicks(), 0);
 
   std::vector<raw_ptr<const ReportingReport, VectorExperimental>> reports;
diff --git a/net/reporting/reporting_header_parser.cc b/net/reporting/reporting_header_parser.cc
index 30f9897..36ecc129 100644
--- a/net/reporting/reporting_header_parser.cc
+++ b/net/reporting/reporting_header_parser.cc
@@ -149,7 +149,7 @@
   }
   parsed_endpoint_group_out->ttl = base::Seconds(ttl_sec);
 
-  absl::optional<bool> subdomains_bool = dict->FindBool(kIncludeSubdomainsKey);
+  std::optional<bool> subdomains_bool = dict->FindBool(kIncludeSubdomainsKey);
   if (subdomains_bool && subdomains_bool.value()) {
     // Disallow eTLDs from setting include_subdomains endpoint groups.
     if (registry_controlled_domains::GetRegistryLength(
@@ -239,18 +239,18 @@
 
 }  // namespace
 
-absl::optional<base::flat_map<std::string, std::string>>
-ParseReportingEndpoints(const std::string& header) {
+std::optional<base::flat_map<std::string, std::string>> ParseReportingEndpoints(
+    const std::string& header) {
   // Ignore empty header values. Skip logging metric to maintain parity with
   // ReportingHeaderType::kReportToInvalid.
   if (header.empty())
-    return absl::nullopt;
-  absl::optional<structured_headers::Dictionary> header_dict =
+    return std::nullopt;
+  std::optional<structured_headers::Dictionary> header_dict =
       structured_headers::ParseDictionary(header);
   if (!header_dict) {
     ReportingHeaderParser::RecordReportingHeaderType(
         ReportingHeaderParser::ReportingHeaderType::kReportingEndpointsInvalid);
-    return absl::nullopt;
+    return std::nullopt;
   }
   base::flat_map<std::string, std::string> parsed_header;
   for (const structured_headers::DictionaryMember& entry : *header_dict) {
@@ -259,7 +259,7 @@
       ReportingHeaderParser::RecordReportingHeaderType(
           ReportingHeaderParser::ReportingHeaderType::
               kReportingEndpointsInvalid);
-      return absl::nullopt;
+      return std::nullopt;
     }
     const std::string& endpoint_url_string =
         entry.second.member.front().item.GetString();
diff --git a/net/reporting/reporting_header_parser.h b/net/reporting/reporting_header_parser.h
index 76ff3b21..7bb7ef3 100644
--- a/net/reporting/reporting_header_parser.h
+++ b/net/reporting/reporting_header_parser.h
@@ -6,12 +6,12 @@
 #define NET_REPORTING_REPORTING_HEADER_PARSER_H_
 
 #include <memory>
+#include <optional>
 
 #include "base/containers/flat_map.h"
 #include "base/values.h"
 #include "net/base/net_export.h"
 #include "net/http/structured_headers.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -25,8 +25,8 @@
 // failed and the header should be ignored; otherwise returns a (possibly
 // empty) mapping of endpoint names to URLs.
 NET_EXPORT
-absl::optional<base::flat_map<std::string, std::string>>
-ParseReportingEndpoints(const std::string& header);
+std::optional<base::flat_map<std::string, std::string>> ParseReportingEndpoints(
+    const std::string& header);
 
 class NET_EXPORT ReportingHeaderParser {
  public:
diff --git a/net/reporting/reporting_header_parser_fuzzer.cc b/net/reporting/reporting_header_parser_fuzzer.cc
index b8e728e..1f6c2c6 100644
--- a/net/reporting/reporting_header_parser_fuzzer.cc
+++ b/net/reporting/reporting_header_parser_fuzzer.cc
@@ -2,7 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "net/reporting/reporting_header_parser.h"
+
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "base/json/json_reader.h"
@@ -12,15 +15,12 @@
 #include "base/values.h"
 #include "net/base/network_anonymization_key.h"
 #include "net/reporting/reporting_cache.h"
-#include "net/reporting/reporting_header_parser.h"
 #include "net/reporting/reporting_policy.pb.h"
 #include "net/reporting/reporting_test_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
-#include "url/gurl.h"
-#include "url/origin.h"
-
 #include "testing/libfuzzer/proto/json_proto_converter.h"
 #include "third_party/libprotobuf-mutator/src/src/libfuzzer/libfuzzer_macro.h"
+#include "url/gurl.h"
+#include "url/origin.h"
 
 // Silence logging from the protobuf library.
 protobuf_mutator::protobuf::LogSilencer log_silencer;
@@ -34,7 +34,7 @@
                                     policy);
   // Emulate what ReportingService::OnHeader does before calling
   // ReportingHeaderParser::ParseHeader.
-  absl::optional<base::Value> data_value =
+  std::optional<base::Value> data_value =
       base::JSONReader::Read("[" + data_json + "]");
   if (!data_value)
     return;
diff --git a/net/reporting/reporting_header_parser_unittest.cc b/net/reporting/reporting_header_parser_unittest.cc
index 6c0baa4..3416d59 100644
--- a/net/reporting/reporting_header_parser_unittest.cc
+++ b/net/reporting/reporting_header_parser_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "net/reporting/reporting_header_parser.h"
 
+#include <optional>
 #include <sstream>
 #include <string>
 #include <vector>
@@ -26,7 +27,6 @@
 #include "net/reporting/reporting_endpoint.h"
 #include "net/reporting/reporting_test_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -188,8 +188,7 @@
   void ParseHeader(const NetworkAnonymizationKey& network_anonymization_key,
                    const url::Origin& origin,
                    const std::string& json) {
-    absl::optional<base::Value> value =
-        base::JSONReader::Read("[" + json + "]");
+    std::optional<base::Value> value = base::JSONReader::Read("[" + json + "]");
     if (value) {
       ReportingHeaderParser::ParseReportToHeader(
           context(), network_anonymization_key, origin, value->GetList());
@@ -1784,7 +1783,7 @@
                    const IsolationInfo& isolation_info,
                    const url::Origin& origin,
                    const std::string& header_string) {
-    absl::optional<base::flat_map<std::string, std::string>> header_map =
+    std::optional<base::flat_map<std::string, std::string>> header_map =
         ParseReportingEndpoints(header_string);
 
     if (header_map) {
@@ -1797,7 +1796,7 @@
       const base::UnguessableToken& reporting_source,
       const IsolationInfo& isolation_info,
       const url::Origin& origin,
-      const absl::optional<base::flat_map<std::string, std::string>>&
+      const std::optional<base::flat_map<std::string, std::string>>&
           header_map) {
     ReportingHeaderParser::ProcessParsedReportingEndpointsHeader(
         context(), reporting_source, isolation_info,
diff --git a/net/reporting/reporting_network_change_observer_unittest.cc b/net/reporting/reporting_network_change_observer_unittest.cc
index 81436ea..b2e0978 100644
--- a/net/reporting/reporting_network_change_observer_unittest.cc
+++ b/net/reporting/reporting_network_change_observer_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "net/reporting/reporting_network_change_observer.h"
 
+#include <optional>
+
 #include "base/functional/bind.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
@@ -15,7 +17,6 @@
 #include "net/reporting/reporting_report.h"
 #include "net/reporting/reporting_test_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 namespace {
@@ -45,8 +46,7 @@
     return reports.size();
   }
 
-  const absl::optional<base::UnguessableToken> kReportingSource_ =
-      absl::nullopt;
+  const std::optional<base::UnguessableToken> kReportingSource_ = std::nullopt;
   const NetworkAnonymizationKey kNak_;
   const GURL kUrl_ = GURL("https://origin/path");
   const url::Origin kOrigin_ = url::Origin::Create(kUrl_);
diff --git a/net/reporting/reporting_report.cc b/net/reporting/reporting_report.cc
index ecb36458..cecee747 100644
--- a/net/reporting/reporting_report.cc
+++ b/net/reporting/reporting_report.cc
@@ -16,7 +16,7 @@
 namespace net {
 
 ReportingReport::ReportingReport(
-    const absl::optional<base::UnguessableToken>& reporting_source,
+    const std::optional<base::UnguessableToken>& reporting_source,
     const NetworkAnonymizationKey& network_anonymization_key,
     const GURL& url,
     const std::string& user_agent,
diff --git a/net/reporting/reporting_report.h b/net/reporting/reporting_report.h
index 27f8d8d..bece78c7 100644
--- a/net/reporting/reporting_report.h
+++ b/net/reporting/reporting_report.h
@@ -6,6 +6,7 @@
 #define NET_REPORTING_REPORTING_REPORT_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "base/time/time.h"
@@ -14,7 +15,6 @@
 #include "net/base/net_export.h"
 #include "net/base/network_anonymization_key.h"
 #include "net/reporting/reporting_endpoint.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace net {
@@ -40,17 +40,16 @@
   };
 
   // TODO(chlily): Remove |attempts| argument as it is (almost?) always 0.
-  ReportingReport(
-      const absl::optional<base::UnguessableToken>& reporting_source,
-      const NetworkAnonymizationKey& network_anonymization_key,
-      const GURL& url,
-      const std::string& user_agent,
-      const std::string& group,
-      const std::string& type,
-      base::Value::Dict body,
-      int depth,
-      base::TimeTicks queued,
-      int attempts);
+  ReportingReport(const std::optional<base::UnguessableToken>& reporting_source,
+                  const NetworkAnonymizationKey& network_anonymization_key,
+                  const GURL& url,
+                  const std::string& user_agent,
+                  const std::string& group,
+                  const std::string& type,
+                  base::Value::Dict body,
+                  int depth,
+                  base::TimeTicks queued,
+                  int attempts);
 
   // Do NOT use this constructor outside of mojo deserialization context.
   ReportingReport();
@@ -82,7 +81,7 @@
   // endpoint group without a source. Reports without a source token can only be
   // delivered to endpoint groups without one.
   // (Not included in the delivered report.)
-  absl::optional<base::UnguessableToken> reporting_source;
+  std::optional<base::UnguessableToken> reporting_source;
 
   // The NAK of the request that triggered this report. (Not included in the
   // delivered report.)
diff --git a/net/reporting/reporting_service.cc b/net/reporting/reporting_service.cc
index 6fce6f7..e575851 100644
--- a/net/reporting/reporting_service.cc
+++ b/net/reporting/reporting_service.cc
@@ -4,6 +4,7 @@
 
 #include "net/reporting/reporting_service.h"
 
+#include <optional>
 #include <utility>
 
 #include "base/feature_list.h"
@@ -25,7 +26,6 @@
 #include "net/reporting/reporting_delivery_agent.h"
 #include "net/reporting/reporting_header_parser.h"
 #include "net/reporting/reporting_uploader.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -81,7 +81,7 @@
 
   void QueueReport(
       const GURL& url,
-      const absl::optional<base::UnguessableToken>& reporting_source,
+      const std::optional<base::UnguessableToken>& reporting_source,
       const NetworkAnonymizationKey& network_anonymization_key,
       const std::string& user_agent,
       const std::string& group,
@@ -120,7 +120,7 @@
     if (header_string.size() > kMaxJsonSize)
       return;
 
-    absl::optional<base::Value> header_value = base::JSONReader::Read(
+    std::optional<base::Value> header_value = base::JSONReader::Read(
         "[" + header_string + "]", base::JSON_PARSE_RFC, kMaxJsonDepth);
     if (!header_value)
       return;
@@ -205,7 +205,7 @@
   }
 
   void DoQueueReport(
-      const absl::optional<base::UnguessableToken>& reporting_source,
+      const std::optional<base::UnguessableToken>& reporting_source,
       const NetworkAnonymizationKey& network_anonymization_key,
       GURL sanitized_url,
       const std::string& user_agent,
diff --git a/net/reporting/reporting_service.h b/net/reporting/reporting_service.h
index 0ee6750..91f2d7f 100644
--- a/net/reporting/reporting_service.h
+++ b/net/reporting/reporting_service.h
@@ -6,6 +6,7 @@
 #define NET_REPORTING_REPORTING_SERVICE_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "base/containers/flat_map.h"
@@ -15,7 +16,6 @@
 #include "net/base/net_export.h"
 #include "net/reporting/reporting_cache.h"
 #include "net/reporting/reporting_cache_observer.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class GURL;
 
@@ -73,7 +73,7 @@
   // will be copied.
   virtual void QueueReport(
       const GURL& url,
-      const absl::optional<base::UnguessableToken>& reporting_source,
+      const std::optional<base::UnguessableToken>& reporting_source,
       const NetworkAnonymizationKey& network_anonymization_key,
       const std::string& user_agent,
       const std::string& group,
diff --git a/net/reporting/reporting_service_unittest.cc b/net/reporting/reporting_service_unittest.cc
index 433b28d..46cf10760 100644
--- a/net/reporting/reporting_service_unittest.cc
+++ b/net/reporting/reporting_service_unittest.cc
@@ -5,6 +5,7 @@
 #include "net/reporting/reporting_service.h"
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "base/functional/bind.h"
@@ -29,7 +30,6 @@
 #include "net/test/test_with_task_environment.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -53,7 +53,7 @@
   const std::string kGroup_ = "group";
   const std::string kGroup2_ = "group2";
   const std::string kType_ = "type";
-  const absl::optional<base::UnguessableToken> kReportingSource_ =
+  const std::optional<base::UnguessableToken> kReportingSource_ =
       base::UnguessableToken::Create();
   const NetworkAnonymizationKey kNak_ =
       NetworkAnonymizationKey::CreateSameSite(SchemefulSite(kOrigin_));
diff --git a/net/reporting/reporting_test_util.cc b/net/reporting/reporting_test_util.cc
index ef4197b5..059d514 100644
--- a/net/reporting/reporting_test_util.cc
+++ b/net/reporting/reporting_test_util.cc
@@ -3,9 +3,9 @@
 // found in the LICENSE file.
 
 #include "net/reporting/reporting_test_util.h"
-#include "base/memory/raw_ptr.h"
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -13,6 +13,7 @@
 #include "base/functional/bind.h"
 #include "base/json/json_reader.h"
 #include "base/memory/ptr_util.h"
+#include "base/memory/raw_ptr.h"
 #include "base/notreached.h"
 #include "base/strings/stringprintf.h"
 #include "base/test/simple_test_clock.h"
@@ -29,7 +30,6 @@
 #include "net/reporting/reporting_policy.h"
 #include "net/reporting/reporting_uploader.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -58,7 +58,7 @@
   const url::Origin& report_origin() const override { return report_origin_; }
   const GURL& url() const override { return url_; }
   const std::string& json() const override { return json_; }
-  absl::optional<base::Value> GetValue() const override {
+  std::optional<base::Value> GetValue() const override {
     return base::JSONReader::Read(json_);
   }
 
@@ -336,7 +336,7 @@
 
 void TestReportingService::QueueReport(
     const GURL& url,
-    const absl::optional<base::UnguessableToken>& reporting_source,
+    const std::optional<base::UnguessableToken>& reporting_source,
     const NetworkAnonymizationKey& network_anonymization_key,
     const std::string& user_agent,
     const std::string& group,
diff --git a/net/reporting/reporting_test_util.h b/net/reporting/reporting_test_util.h
index f9668b1..1e487259 100644
--- a/net/reporting/reporting_test_util.h
+++ b/net/reporting/reporting_test_util.h
@@ -6,6 +6,7 @@
 #define NET_REPORTING_REPORTING_TEST_UTIL_H_
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
@@ -24,7 +25,6 @@
 #include "net/test/test_with_task_environment.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace base {
@@ -66,7 +66,7 @@
     virtual const url::Origin& report_origin() const = 0;
     virtual const GURL& url() const = 0;
     virtual const std::string& json() const = 0;
-    virtual absl::optional<base::Value> GetValue() const = 0;
+    virtual std::optional<base::Value> GetValue() const = 0;
 
     virtual void Complete(Outcome outcome) = 0;
 
@@ -344,7 +344,7 @@
 
   void QueueReport(
       const GURL& url,
-      const absl::optional<base::UnguessableToken>& reporting_source,
+      const std::optional<base::UnguessableToken>& reporting_source,
       const NetworkAnonymizationKey& network_anonymization_key,
       const std::string& user_agent,
       const std::string& group,
diff --git a/net/reporting/reporting_uploader_unittest.cc b/net/reporting/reporting_uploader_unittest.cc
index c51c7f8..17b6ac11 100644
--- a/net/reporting/reporting_uploader_unittest.cc
+++ b/net/reporting/reporting_uploader_unittest.cc
@@ -532,8 +532,8 @@
   ResultSavingCookieCallback<CookieAccessResult> cookie_callback;
   GURL url = server_.GetURL("/");
   auto cookie = CanonicalCookie::Create(
-      url, "foo=bar", base::Time::Now(), absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */);
+      url, "foo=bar", base::Time::Now(), std::nullopt /* server_time */,
+      std::nullopt /* cookie_partition_key */);
   context_->cookie_store()->SetCanonicalCookieAsync(
       std::move(cookie), url, CookieOptions::MakeAllInclusive(),
       cookie_callback.MakeCallback());
diff --git a/net/socket/client_socket_handle.cc b/net/socket/client_socket_handle.cc
index 35d15c2..54712c1 100644
--- a/net/socket/client_socket_handle.cc
+++ b/net/socket/client_socket_handle.cc
@@ -31,7 +31,7 @@
 int ClientSocketHandle::Init(
     const ClientSocketPool::GroupId& group_id,
     scoped_refptr<ClientSocketPool::SocketParams> socket_params,
-    const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+    const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
     RequestPriority priority,
     const SocketTag& socket_tag,
     ClientSocketPool::RespectLimits respect_limits,
diff --git a/net/socket/client_socket_handle.h b/net/socket/client_socket_handle.h
index 2c7b2b66..a14430b 100644
--- a/net/socket/client_socket_handle.h
+++ b/net/socket/client_socket_handle.h
@@ -6,6 +6,7 @@
 #define NET_SOCKET_CLIENT_SOCKET_HANDLE_H_
 
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "base/check.h"
@@ -27,7 +28,6 @@
 #include "net/socket/connection_attempts.h"
 #include "net/socket/stream_socket.h"
 #include "net/ssl/ssl_cert_request_info.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -89,7 +89,7 @@
   int Init(
       const ClientSocketPool::GroupId& group_id,
       scoped_refptr<ClientSocketPool::SocketParams> socket_params,
-      const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+      const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
       RequestPriority priority,
       const SocketTag& socket_tag,
       ClientSocketPool::RespectLimits respect_limits,
diff --git a/net/socket/client_socket_pool.cc b/net/socket/client_socket_pool.cc
index 2c2b7783..aafd43f 100644
--- a/net/socket/client_socket_pool.cc
+++ b/net/socket/client_socket_pool.cc
@@ -177,7 +177,7 @@
     GroupId group_id,
     scoped_refptr<SocketParams> socket_params,
     const ProxyChain& proxy_chain,
-    const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+    const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
     RequestPriority request_priority,
     SocketTag socket_tag,
     ConnectJob::Delegate* delegate) {
diff --git a/net/socket/client_socket_pool.h b/net/socket/client_socket_pool.h
index 3ccabeba..aa76fd2 100644
--- a/net/socket/client_socket_pool.h
+++ b/net/socket/client_socket_pool.h
@@ -6,6 +6,7 @@
 #define NET_SOCKET_CLIENT_SOCKET_POOL_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -26,7 +27,6 @@
 #include "net/socket/connect_job.h"
 #include "net/socket/socket_tag.h"
 #include "net/ssl/ssl_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/scheme_host_port.h"
 
 namespace net {
@@ -245,7 +245,7 @@
   virtual int RequestSocket(
       const GroupId& group_id,
       scoped_refptr<SocketParams> params,
-      const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+      const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
       RequestPriority priority,
       const SocketTag& socket_tag,
       RespectLimits respect_limits,
@@ -269,7 +269,7 @@
   virtual int RequestSockets(
       const GroupId& group_id,
       scoped_refptr<SocketParams> params,
-      const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+      const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
       int num_sockets,
       CompletionOnceCallback callback,
       const NetLogWithSource& net_log) = 0;
@@ -365,7 +365,7 @@
       GroupId group_id,
       scoped_refptr<SocketParams> socket_params,
       const ProxyChain& proxy_chain,
-      const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+      const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
       RequestPriority request_priority,
       SocketTag socket_tag,
       ConnectJob::Delegate* delegate);
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc
index edae2ec..d6938b4 100644
--- a/net/socket/client_socket_pool_base_unittest.cc
+++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -4,6 +4,7 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -65,7 +66,6 @@
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/scheme_host_port.h"
 #include "url/url_constants.h"
 
@@ -454,7 +454,7 @@
         return ERR_IO_PENDING;
       default:
         NOTREACHED();
-        SetSocket(std::unique_ptr<StreamSocket>(), absl::nullopt);
+        SetSocket(std::unique_ptr<StreamSocket>(), std::nullopt);
         return ERR_FAILED;
     }
   }
@@ -466,15 +466,15 @@
     has_established_connection_ = true;
     if (succeed) {
       SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()),
-                absl::nullopt);
+                std::nullopt);
       socket()->Connect(CompletionOnceCallback());
     } else if (cert_error) {
       SetSocket(std::make_unique<MockClientSocket>(net_log().net_log()),
-                absl::nullopt);
+                std::nullopt);
       result = ERR_CERT_COMMON_NAME_INVALID;
     } else {
       result = ERR_CONNECTION_FAILED;
-      SetSocket(std::unique_ptr<StreamSocket>(), absl::nullopt);
+      SetSocket(std::unique_ptr<StreamSocket>(), std::nullopt);
     }
 
     if (was_async) {
@@ -547,7 +547,7 @@
   std::unique_ptr<ConnectJob> CreateConnectJob(
       Endpoint endpoint,
       const ProxyChain& proxy_chain,
-      const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+      const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
       const std::vector<SSLConfig::CertAndStatus>& allowed_bad_certs,
       ConnectJobFactory::AlpnMode alpn_mode,
       bool force_tunnel,
@@ -743,7 +743,7 @@
   TestLoadTimingInfoNotConnected(handle);
 
   EXPECT_EQ(OK, handle.Init(
-                    TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+                    TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), net_log_with_source));
@@ -785,7 +785,7 @@
   handle.set_ssl_cert_request_info(base::MakeRefCounted<SSLCertRequestInfo>());
   EXPECT_EQ(
       ERR_CONNECTION_FAILED,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), net_log_with_source));
@@ -906,7 +906,7 @@
 
             // Since the group is empty, requesting a socket should not complete
             // synchronously.
-            EXPECT_THAT(handle.Init(group_id, params_, absl::nullopt,
+            EXPECT_THAT(handle.Init(group_id, params_, std::nullopt,
                                     DEFAULT_PRIORITY, SocketTag(),
                                     ClientSocketPool::RespectLimits::ENABLED,
                                     callback.callback(),
@@ -927,7 +927,7 @@
 
             // Requesting a socket again should return the same socket as
             // before, so should complete synchronously.
-            EXPECT_THAT(handle.Init(group_id, params_, absl::nullopt,
+            EXPECT_THAT(handle.Init(group_id, params_, std::nullopt,
                                     DEFAULT_PRIORITY, SocketTag(),
                                     ClientSocketPool::RespectLimits::ENABLED,
                                     callback.callback(),
@@ -1274,7 +1274,7 @@
   ClientSocketHandle stalled_handle;
   EXPECT_EQ(ERR_IO_PENDING,
             stalled_handle.Init(
-                TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+                TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                 pool_.get(), NetLogWithSource()));
@@ -1283,7 +1283,7 @@
   for (auto& handle : handles) {
     EXPECT_EQ(
         ERR_IO_PENDING,
-        handle.Init(TestGroupId("b"), params_, absl::nullopt, DEFAULT_PRIORITY,
+        handle.Init(TestGroupId("b"), params_, std::nullopt, DEFAULT_PRIORITY,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource()));
@@ -1306,7 +1306,7 @@
     TestCompletionCallback callbacks[kDefaultMaxSockets];
     for (int i = 0; i < kDefaultMaxSockets; ++i) {
       EXPECT_EQ(OK, handles[i].Init(TestGroupId("a" + base::NumberToString(i)),
-                                    params_, absl::nullopt, DEFAULT_PRIORITY,
+                                    params_, std::nullopt, DEFAULT_PRIORITY,
                                     SocketTag(),
                                     ClientSocketPool::RespectLimits::ENABLED,
                                     callbacks[i].callback(),
@@ -1319,7 +1319,7 @@
     TestCompletionCallback callback;
     EXPECT_EQ(ERR_IO_PENDING,
               stalled_handle.Init(
-                  TestGroupId("foo"), params_, absl::nullopt, DEFAULT_PRIORITY,
+                  TestGroupId("foo"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -1348,7 +1348,7 @@
       EXPECT_EQ(ERR_IO_PENDING,
                 handles[i].Init(
                     TestGroupId("a" + base::NumberToString(i)), params_,
-                    absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
+                    std::nullopt, DEFAULT_PRIORITY, SocketTag(),
                     ClientSocketPool::RespectLimits::ENABLED,
                     callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource()));
@@ -1360,7 +1360,7 @@
     TestCompletionCallback callback;
     EXPECT_EQ(ERR_IO_PENDING,
               stalled_handle.Init(
-                  TestGroupId("foo"), params_, absl::nullopt, DEFAULT_PRIORITY,
+                  TestGroupId("foo"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -1413,7 +1413,7 @@
       EXPECT_EQ(
           OK, handles[i].Init(
                   TestGroupId(base::StringPrintf("take-2-%d", i)), params_,
-                  absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
+                  std::nullopt, DEFAULT_PRIORITY, SocketTag(),
                   ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
                   ClientSocketPool::ProxyAuthCallback(), pool_.get(),
                   NetLogWithSource()));
@@ -1426,7 +1426,7 @@
     // Now we will hit the socket limit.
     EXPECT_EQ(ERR_IO_PENDING,
               stalled_handle.Init(
-                  TestGroupId("foo"), params_, absl::nullopt, DEFAULT_PRIORITY,
+                  TestGroupId("foo"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -1455,7 +1455,7 @@
     EXPECT_EQ(
         OK,
         handle.Init(TestGroupId("a" + base::NumberToString(i)), params_,
-                    absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
+                    std::nullopt, DEFAULT_PRIORITY, SocketTag(),
                     ClientSocketPool::RespectLimits::ENABLED,
                     callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource()));
@@ -1474,7 +1474,7 @@
   // which is the one which we would close an idle socket for.  We shouldn't
   // close an idle socket though, since we should reuse the idle socket.
   EXPECT_EQ(OK, handle.Init(
-                    TestGroupId("a0"), params_, absl::nullopt, DEFAULT_PRIORITY,
+                    TestGroupId("a0"), params_, std::nullopt, DEFAULT_PRIORITY,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource()));
@@ -1543,7 +1543,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -1568,7 +1568,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -1594,7 +1594,7 @@
     TestCompletionCallback callback;
     EXPECT_EQ(
         ERR_IO_PENDING,
-        handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+        handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource()));
@@ -1632,7 +1632,7 @@
           std::make_unique<ClientSocketHandle>();
       EXPECT_EQ(ERR_IO_PENDING,
                 handle->Init(
-                    TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+                    TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource()));
@@ -1692,7 +1692,7 @@
 
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -1706,7 +1706,7 @@
   TestCompletionCallback callback2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -1790,7 +1790,7 @@
   TestCompletionCallback callback;
   int rv = handle->Init(
       TestGroupId("a"),
-      ClientSocketPool::SocketParams::CreateForHttpForTesting(), absl::nullopt,
+      ClientSocketPool::SocketParams::CreateForHttpForTesting(), std::nullopt,
       LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
       nested_callback->callback(), ClientSocketPool::ProxyAuthCallback(), pool,
       NetLogWithSource());
@@ -1812,7 +1812,7 @@
   ClientSocketHandle handle;
   TestCompletionCallback second_result_callback;
   int rv = handle.Init(
-      TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED,
       base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
                      connect_job_factory_, TestConnectJob::kMockPendingJob,
@@ -1833,7 +1833,7 @@
   ClientSocketHandle handle;
   TestCompletionCallback second_result_callback;
   int rv = handle.Init(
-      TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED,
       base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(),
                      connect_job_factory_, TestConnectJob::kMockPendingJob,
@@ -1937,7 +1937,7 @@
   ClientSocketHandle handle;
   TestCompletionCallback callback;
   int rv = handle.Init(
-      TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -1945,7 +1945,7 @@
   // Cancel the active request.
   handle.Reset();
 
-  rv = handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+  rv = handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource());
@@ -1964,7 +1964,7 @@
   ClientSocketHandle handle;
   TestCompletionCallback callback;
   int rv =
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST, SocketTag(),
+      handle.Init(TestGroupId("a"), params_, std::nullopt, LOWEST, SocketTag(),
                   ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
                   ClientSocketPool::ProxyAuthCallback(), pool_.get(),
                   NetLogWithSource::Make(NetLogSourceType::NONE));
@@ -1984,17 +1984,17 @@
       NetLogWithSource::Make(NetLogSourceType::NONE);
   ClientSocketHandle handle1;
   int rv = handle1.Init(
-      TestGroupId("a"), params_, absl::nullopt, LOWEST, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, LOWEST, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_.get(), net_log_with_source);
   EXPECT_THAT(rv, IsOk());
   ClientSocketHandle handle2;
-  rv = handle2.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
+  rv = handle2.Init(TestGroupId("a"), params_, std::nullopt, LOWEST,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), net_log_with_source);
   ClientSocketHandle handle3;
-  rv = handle3.Init(TestGroupId("b"), params_, absl::nullopt, LOWEST,
+  rv = handle3.Init(TestGroupId("b"), params_, std::nullopt, LOWEST,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), net_log_with_source);
@@ -2014,7 +2014,7 @@
   NetLogWithSource net_log_with_source =
       NetLogWithSource::Make(NetLogSourceType::NONE);
   int rv = handle.Init(
-      TestGroupId("a"), params_, absl::nullopt, LOWEST, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, LOWEST, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_.get(), net_log_with_source);
   EXPECT_THAT(rv, IsOk());
@@ -2027,7 +2027,7 @@
   NetLogSource source = socket->NetLog().source();
   socket->Disconnect();
   ClientSocketHandle handle2;
-  rv = handle2.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
+  rv = handle2.Init(TestGroupId("a"), params_, std::nullopt, LOWEST,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), net_log_with_source);
@@ -2091,7 +2091,7 @@
   NetLogWithSource net_log_with_source =
       NetLogWithSource::Make(NetLogSourceType::NONE);
   int rv = handle.Init(
-      TestGroupId("a"), params_, absl::nullopt, LOWEST, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, LOWEST, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_.get(), net_log_with_source);
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2137,7 +2137,7 @@
   handle.set_ssl_cert_request_info(base::MakeRefCounted<SSLCertRequestInfo>());
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), net_log_with_source));
@@ -2192,14 +2192,14 @@
 
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
   RecordingNetLogObserver log2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -2257,7 +2257,7 @@
   size_t completion_count;  // unused
   TestSocketRequest req1(&request_order, &completion_count);
   int rv = req1.handle()->Init(
-      TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2269,13 +2269,13 @@
 
   TestSocketRequest req2(&request_order, &completion_count);
   rv = req2.handle()->Init(
-      TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
   TestSocketRequest req3(&request_order, &completion_count);
   rv = req3.handle()->Init(
-      TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2312,14 +2312,14 @@
   size_t completion_count;  // unused
   TestSocketRequest req1(&request_order, &completion_count);
   int rv = req1.handle()->Init(
-      TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, req1.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
 
   TestSocketRequest req2(&request_order, &completion_count);
   rv = req2.handle()->Init(
-      TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, req2.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2329,7 +2329,7 @@
 
   TestSocketRequest req3(&request_order, &completion_count);
   rv = req3.handle()->Init(
-      TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, req3.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2352,7 +2352,7 @@
   ClientSocketHandle handle;
   TestCompletionCallback callback;
   int rv = handle.Init(
-      TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2373,7 +2373,7 @@
   ClientSocketHandle handle;
   TestCompletionCallback callback;
   int rv = handle.Init(
-      TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2381,7 +2381,7 @@
 
   ClientSocketHandle handle2;
   TestCompletionCallback callback2;
-  rv = handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+  rv = handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource());
@@ -2421,7 +2421,7 @@
   ClientSocketHandle handle;
   TestCompletionCallback callback;
   int rv = handle.Init(
-      TestGroupId("a"), params_, absl::nullopt, MEDIUM, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, MEDIUM, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2431,7 +2431,7 @@
   // The first request should now be stalled at the socket group limit.
   ClientSocketHandle handle2;
   TestCompletionCallback callback2;
-  rv = handle2.Init(TestGroupId("a"), params_, absl::nullopt, HIGHEST,
+  rv = handle2.Init(TestGroupId("a"), params_, std::nullopt, HIGHEST,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource());
@@ -2465,7 +2465,7 @@
   ClientSocketHandle handle;
   TestCompletionCallback callback;
   int rv = handle.Init(
-      TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2473,7 +2473,7 @@
   // Request for socket from another pool.
   ClientSocketHandle handle2;
   TestCompletionCallback callback2;
-  rv = handle2.Init(TestGroupId("b"), params_, absl::nullopt, DEFAULT_PRIORITY,
+  rv = handle2.Init(TestGroupId("b"), params_, std::nullopt, DEFAULT_PRIORITY,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource());
@@ -2483,7 +2483,7 @@
   // socket pool limit.
   ClientSocketHandle handle3;
   TestCompletionCallback callback3;
-  rv = handle3.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+  rv = handle3.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource());
@@ -2518,7 +2518,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_CERT_COMMON_NAME_INVALID,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -2534,7 +2534,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -2554,7 +2554,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_CONNECTION_FAILED,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -2573,7 +2573,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -2598,7 +2598,7 @@
   ClientSocketHandle handle;
   TestCompletionCallback callback;
   int rv = handle.Init(
-      TestGroupId("a"), params_, absl::nullopt, LOWEST, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, LOWEST, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2620,7 +2620,7 @@
   NetLogWithSource net_log_with_source =
       NetLogWithSource::Make(NetLogSourceType::NONE);
   rv = handle.Init(
-      TestGroupId("a"), params_, absl::nullopt, LOWEST, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, LOWEST, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
       ClientSocketPool::ProxyAuthCallback(), pool_.get(), net_log_with_source);
   ASSERT_THAT(rv, IsOk());
@@ -2655,7 +2655,7 @@
   ClientSocketHandle handle;
   TestCompletionCallback callback;
   int rv = handle.Init(
-      TestGroupId("a"), params_, absl::nullopt, LOWEST, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, LOWEST, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2664,7 +2664,7 @@
 
   ClientSocketHandle handle2;
   TestCompletionCallback callback2;
-  rv = handle2.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
+  rv = handle2.Init(TestGroupId("a"), params_, std::nullopt, LOWEST,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource());
@@ -2701,8 +2701,8 @@
   NetLogWithSource net_log_with_source =
       NetLogWithSource::Make(NetLogSourceType::NONE);
   TestCompletionCallback callback3;
-  rv = handle.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
-                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
+  rv = handle.Init(TestGroupId("a"), params_, std::nullopt, LOWEST, SocketTag(),
+                   ClientSocketPool::RespectLimits::ENABLED,
                    callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), net_log_with_source);
   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -2737,14 +2737,14 @@
   ClientSocketHandle handle;
   TestCompletionCallback callback;
   int rv = handle.Init(
-      TestGroupId("a"), params_, absl::nullopt, LOWEST, SocketTag(),
+      TestGroupId("a"), params_, std::nullopt, LOWEST, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource());
   EXPECT_THAT(rv, IsOk());
 
   ClientSocketHandle handle2;
   TestCompletionCallback callback2;
-  rv = handle2.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
+  rv = handle2.Init(TestGroupId("a"), params_, std::nullopt, LOWEST,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource());
@@ -2752,7 +2752,7 @@
 
   ClientSocketHandle handle3;
   TestCompletionCallback callback3;
-  rv = handle3.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
+  rv = handle3.Init(TestGroupId("a"), params_, std::nullopt, LOWEST,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource());
@@ -2760,7 +2760,7 @@
 
   ClientSocketHandle handle4;
   TestCompletionCallback callback4;
-  rv = handle4.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
+  rv = handle4.Init(TestGroupId("a"), params_, std::nullopt, LOWEST,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource());
@@ -2798,13 +2798,13 @@
   TestCompletionCallback callback_b[4];
 
   for (int i = 0; i < 2; ++i) {
-    EXPECT_EQ(OK, handle_a[i].Init(TestGroupId("a"), params_, absl::nullopt,
+    EXPECT_EQ(OK, handle_a[i].Init(TestGroupId("a"), params_, std::nullopt,
                                    LOWEST, SocketTag(),
                                    ClientSocketPool::RespectLimits::ENABLED,
                                    callback_a[i].callback(),
                                    ClientSocketPool::ProxyAuthCallback(),
                                    pool_.get(), NetLogWithSource()));
-    EXPECT_EQ(OK, handle_b[i].Init(TestGroupId("b"), params_, absl::nullopt,
+    EXPECT_EQ(OK, handle_b[i].Init(TestGroupId("b"), params_, std::nullopt,
                                    LOWEST, SocketTag(),
                                    ClientSocketPool::RespectLimits::ENABLED,
                                    callback_b[i].callback(),
@@ -2817,14 +2817,14 @@
   for (int i = 2; i < 4; ++i) {
     EXPECT_EQ(
         ERR_IO_PENDING,
-        handle_a[i].Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
+        handle_a[i].Init(TestGroupId("a"), params_, std::nullopt, LOWEST,
                          SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                          callback_a[i].callback(),
                          ClientSocketPool::ProxyAuthCallback(), pool_.get(),
                          NetLogWithSource()));
     EXPECT_EQ(
         ERR_IO_PENDING,
-        handle_b[i].Init(TestGroupId("b"), params_, absl::nullopt, LOWEST,
+        handle_b[i].Init(TestGroupId("b"), params_, std::nullopt, LOWEST,
                          SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                          callback_b[i].callback(),
                          ClientSocketPool::ProxyAuthCallback(), pool_.get(),
@@ -2921,7 +2921,7 @@
         handle2_.Init(
             TestGroupId("a"),
             ClientSocketPool::SocketParams::CreateForHttpForTesting(),
-            absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
+            std::nullopt, DEFAULT_PRIORITY, SocketTag(),
             ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
             ClientSocketPool::ProxyAuthCallback(), pool_, NetLogWithSource()));
   }
@@ -2948,7 +2948,7 @@
   TestReleasingSocketRequest req(pool_.get(), OK, false);
   EXPECT_EQ(ERR_IO_PENDING,
             req.handle()->Init(
-                TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+                TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                 req.callback(), ClientSocketPool::ProxyAuthCallback(),
                 pool_.get(), NetLogWithSource()));
@@ -2978,7 +2978,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -2997,7 +2997,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -3012,7 +3012,7 @@
 
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -3048,7 +3048,7 @@
     SetResult(result);
     EXPECT_EQ(
         ERR_IO_PENDING,
-        handle_.Init(group_id_, params_, absl::nullopt, DEFAULT_PRIORITY,
+        handle_.Init(group_id_, params_, std::nullopt, DEFAULT_PRIORITY,
                      SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                      nested_callback_.callback(),
                      ClientSocketPool::ProxyAuthCallback(), pool_,
@@ -3072,7 +3072,7 @@
   ConnectWithinCallback callback(TestGroupId("a"), params_, pool_.get());
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -3094,7 +3094,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("bar"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("bar"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -3124,7 +3124,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("bar"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("bar"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -3156,7 +3156,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("bar"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("bar"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -3165,7 +3165,7 @@
   connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
   ClientSocketHandle handles[kDefaultMaxSockets];
   for (int i = 1; i < kDefaultMaxSockets; ++i) {
-    EXPECT_EQ(OK, handles[i].Init(TestGroupId("bar"), params_, absl::nullopt,
+    EXPECT_EQ(OK, handles[i].Init(TestGroupId("bar"), params_, std::nullopt,
                                   DEFAULT_PRIORITY, SocketTag(),
                                   ClientSocketPool::RespectLimits::ENABLED,
                                   callback.callback(),
@@ -3196,7 +3196,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("bar"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("bar"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -3228,7 +3228,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("bar"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("bar"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -3237,7 +3237,7 @@
   TestCompletionCallback callback2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle2.Init(TestGroupId("bar"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle2.Init(TestGroupId("bar"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3265,7 +3265,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3280,7 +3280,7 @@
   ClientSocketHandle handle2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3321,7 +3321,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3336,7 +3336,7 @@
   ClientSocketHandle handle2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3379,7 +3379,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3394,7 +3394,7 @@
   ClientSocketHandle handle2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3440,7 +3440,7 @@
   TestCompletionCallback callback1;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3455,7 +3455,7 @@
   // when created.
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3476,7 +3476,7 @@
   TestCompletionCallback callback1;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3485,7 +3485,7 @@
   TestCompletionCallback callback2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3493,7 +3493,7 @@
   TestCompletionCallback callback3;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle3.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle3.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3513,17 +3513,17 @@
   handle3.Reset();
 
   EXPECT_EQ(OK, handle1.Init(
-                    TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+                    TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource()));
   EXPECT_EQ(OK, handle2.Init(
-                    TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+                    TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource()));
   EXPECT_EQ(OK, handle3.Init(
-                    TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+                    TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource()));
@@ -3539,7 +3539,7 @@
 
   TestCompletionCallback preconnect_callback;
   EXPECT_EQ(ERR_IO_PENDING,
-            pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
+            pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
                                   preconnect_callback.callback(),
                                   NetLogWithSource()));
 
@@ -3555,7 +3555,7 @@
   TestCompletionCallback callback1;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3564,7 +3564,7 @@
   TestCompletionCallback callback2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3598,7 +3598,7 @@
   TestCompletionCallback callback1;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3613,7 +3613,7 @@
 
   TestCompletionCallback preconnect_callback;
   EXPECT_EQ(ERR_IO_PENDING,
-            pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
+            pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
                                   preconnect_callback.callback(),
                                   NetLogWithSource()));
 
@@ -3628,7 +3628,7 @@
   TestCompletionCallback callback2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3663,7 +3663,7 @@
   TestCompletionCallback callback1;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3672,7 +3672,7 @@
   TestCompletionCallback callback2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3681,7 +3681,7 @@
   TestCompletionCallback callback3;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle3.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle3.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3695,7 +3695,7 @@
   EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
 
   EXPECT_EQ(
-      OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
+      OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
                                 CompletionOnceCallback(), NetLogWithSource()));
 
   EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
@@ -3729,7 +3729,7 @@
   TestCompletionCallback preconnect_callback;
   EXPECT_EQ(ERR_IO_PENDING,
             pool_->RequestSockets(
-                TestGroupId("a"), params_, absl::nullopt, kDefaultMaxSockets,
+                TestGroupId("a"), params_, std::nullopt, kDefaultMaxSockets,
                 preconnect_callback.callback(), NetLogWithSource()));
 
   ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
@@ -3746,10 +3746,9 @@
 
   ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
 
-  EXPECT_EQ(OK,
-            pool_->RequestSockets(TestGroupId("b"), params_, absl::nullopt,
-                                  kDefaultMaxSockets, CompletionOnceCallback(),
-                                  NetLogWithSource()));
+  EXPECT_EQ(OK, pool_->RequestSockets(
+                    TestGroupId("b"), params_, std::nullopt, kDefaultMaxSockets,
+                    CompletionOnceCallback(), NetLogWithSource()));
 
   ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b")));
 
@@ -3764,10 +3763,9 @@
 
   TestCompletionCallback preconnect_callback1;
   EXPECT_EQ(ERR_IO_PENDING,
-            pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt,
-                                  kDefaultMaxSockets - 1,
-                                  preconnect_callback1.callback(),
-                                  NetLogWithSource()));
+            pool_->RequestSockets(
+                TestGroupId("a"), params_, std::nullopt, kDefaultMaxSockets - 1,
+                preconnect_callback1.callback(), NetLogWithSource()));
 
   ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
   EXPECT_EQ(kDefaultMaxSockets - 1,
@@ -3787,7 +3785,7 @@
   TestCompletionCallback preconnect_callback2;
   EXPECT_EQ(ERR_IO_PENDING,
             pool_->RequestSockets(
-                TestGroupId("b"), params_, absl::nullopt, kDefaultMaxSockets,
+                TestGroupId("b"), params_, std::nullopt, kDefaultMaxSockets,
                 preconnect_callback2.callback(), NetLogWithSource()));
 
   ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("b")));
@@ -3806,7 +3804,7 @@
   TestCompletionCallback callback1;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3823,7 +3821,7 @@
 
   TestCompletionCallback preconnect_callback;
   EXPECT_EQ(ERR_IO_PENDING,
-            pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
+            pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
                                   preconnect_callback.callback(),
                                   NetLogWithSource()));
 
@@ -3845,7 +3843,7 @@
   TestCompletionCallback callback1;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3862,7 +3860,7 @@
 
   TestCompletionCallback preconnect_callback;
   EXPECT_EQ(ERR_IO_PENDING,
-            pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
+            pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
                                   preconnect_callback.callback(),
                                   NetLogWithSource()));
 
@@ -3882,7 +3880,7 @@
   connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
 
   EXPECT_EQ(
-      OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt,
+      OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt,
                                 kDefaultMaxSocketsPerGroup,
                                 CompletionOnceCallback(), NetLogWithSource()));
 
@@ -3896,7 +3894,7 @@
             static_cast<int>(pool_->IdleSocketCountInGroup(TestGroupId("a"))));
 
   EXPECT_EQ(
-      OK, pool_->RequestSockets(TestGroupId("b"), params_, absl::nullopt,
+      OK, pool_->RequestSockets(TestGroupId("b"), params_, std::nullopt,
                                 kDefaultMaxSocketsPerGroup,
                                 CompletionOnceCallback(), NetLogWithSource()));
 
@@ -3914,7 +3912,7 @@
   connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob);
 
   EXPECT_EQ(
-      OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt,
+      OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt,
                                 kDefaultMaxSocketsPerGroup,
                                 CompletionOnceCallback(), NetLogWithSource()));
 
@@ -3924,7 +3922,7 @@
       TestConnectJob::kMockAdditionalErrorStateJob);
 
   EXPECT_EQ(
-      OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt,
+      OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt,
                                 kDefaultMaxSocketsPerGroup,
                                 CompletionOnceCallback(), NetLogWithSource()));
 
@@ -3937,7 +3935,7 @@
 
   TestCompletionCallback preconnect_callback;
   EXPECT_EQ(ERR_IO_PENDING,
-            pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
+            pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
                                   preconnect_callback.callback(),
                                   NetLogWithSource()));
 
@@ -3951,7 +3949,7 @@
   EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
 
   EXPECT_EQ(
-      OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
+      OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
                                 CompletionOnceCallback(), NetLogWithSource()));
   EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
   EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
@@ -3965,7 +3963,7 @@
   TestCompletionCallback callback1;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -3985,7 +3983,7 @@
   TestCompletionCallback callback2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -4013,7 +4011,7 @@
   EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
 
   EXPECT_EQ(
-      OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
+      OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
                                 CompletionOnceCallback(), NetLogWithSource()));
   EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
   EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
@@ -4030,7 +4028,7 @@
 
   TestCompletionCallback preconnect_callback1;
   EXPECT_EQ(ERR_IO_PENDING,
-            pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 1,
+            pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 1,
                                   preconnect_callback1.callback(),
                                   NetLogWithSource()));
 
@@ -4044,7 +4042,7 @@
 
   TestCompletionCallback preconnect_callback2;
   EXPECT_EQ(ERR_IO_PENDING,
-            pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
+            pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
                                   preconnect_callback2.callback(),
                                   NetLogWithSource()));
   EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
@@ -4056,7 +4054,7 @@
 
   TestCompletionCallback preconnect_callback3;
   EXPECT_EQ(ERR_IO_PENDING,
-            pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 3,
+            pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 3,
                                   preconnect_callback3.callback(),
                                   NetLogWithSource()));
   EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
@@ -4067,7 +4065,7 @@
   EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a")));
 
   EXPECT_EQ(
-      OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 1,
+      OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 1,
                                 CompletionOnceCallback(), NetLogWithSource()));
   EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
   EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
@@ -4083,7 +4081,7 @@
 
   TestCompletionCallback preconnect_callback;
   EXPECT_EQ(ERR_IO_PENDING,
-            pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 1,
+            pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 1,
                                   preconnect_callback.callback(),
                                   NetLogWithSource()));
 
@@ -4099,7 +4097,7 @@
   TestCompletionCallback callback1;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -4138,7 +4136,7 @@
   connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
 
   EXPECT_EQ(
-      OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 1,
+      OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 1,
                                 CompletionOnceCallback(), NetLogWithSource()));
 
   ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
@@ -4152,7 +4150,7 @@
   ClientSocketHandle handle;
   TestCompletionCallback callback;
   EXPECT_EQ(OK, handle.Init(
-                    TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+                    TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource()));
@@ -4180,7 +4178,7 @@
   TestCompletionCallback callback1;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -4209,13 +4207,13 @@
   TestCompletionCallback callback2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("b"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("b"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle2.Init(TestGroupId("b"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle2.Init(TestGroupId("b"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -4244,7 +4242,7 @@
   // sockets for "a", and "b" should still have 2 active sockets.
 
   EXPECT_EQ(
-      OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
+      OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
                                 CompletionOnceCallback(), NetLogWithSource()));
   EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
   EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting(
@@ -4271,7 +4269,7 @@
 
   TestCompletionCallback preconnect_callback;
   EXPECT_EQ(ERR_IO_PENDING,
-            pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 2,
+            pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 2,
                                   preconnect_callback.callback(),
                                   NetLogWithSource()));
   EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
@@ -4299,7 +4297,7 @@
   connect_job_factory_->set_timeout_duration(base::Milliseconds(500));
   TestCompletionCallback preconnect_callback;
   EXPECT_EQ(ERR_IO_PENDING,
-            pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 1,
+            pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 1,
                                   preconnect_callback.callback(),
                                   NetLogWithSource()));
   EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
@@ -4328,7 +4326,7 @@
   connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
   TestCompletionCallback preconnect_callback;
   EXPECT_EQ(ERR_IO_PENDING,
-            pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 1,
+            pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 1,
                                   preconnect_callback.callback(),
                                   NetLogWithSource()));
   EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")));
@@ -4345,7 +4343,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -4377,7 +4375,7 @@
   connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob);
 
   EXPECT_EQ(
-      OK, pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 1,
+      OK, pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 1,
                                 CompletionOnceCallback(), NetLogWithSource()));
 
   ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a")));
@@ -4394,7 +4392,7 @@
   ClientSocketHandle handle;
   TestCompletionCallback callback;
   EXPECT_EQ(OK, handle.Init(
-                    TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+                    TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                     SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource()));
@@ -4426,7 +4424,7 @@
   TestCompletionCallback callback1;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -4450,7 +4448,7 @@
   TestCompletionCallback callback1;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -4466,7 +4464,7 @@
   TestCompletionCallback callback2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -4505,7 +4503,7 @@
 
   TestCompletionCallback preconnect_callback;
   EXPECT_EQ(ERR_IO_PENDING,
-            pool_->RequestSockets(TestGroupId("a"), params_, absl::nullopt, 1,
+            pool_->RequestSockets(TestGroupId("a"), params_, std::nullopt, 1,
                                   preconnect_callback.callback(),
                                   NetLogWithSource()));
 
@@ -4521,7 +4519,7 @@
   TestCompletionCallback callback1;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -4545,7 +4543,7 @@
   TestCompletionCallback callback1;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -4565,7 +4563,7 @@
   TestCompletionCallback callback2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle2.Init(TestGroupId("a"), params_, absl::nullopt, HIGHEST,
+      handle2.Init(TestGroupId("a"), params_, std::nullopt, HIGHEST,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -4593,7 +4591,7 @@
   TestCompletionCallback callback_lowest;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle_lowest.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
+      handle_lowest.Init(TestGroupId("a"), params_, std::nullopt, LOWEST,
                          SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                          callback_lowest.callback(),
                          ClientSocketPool::ProxyAuthCallback(), pool_.get(),
@@ -4610,7 +4608,7 @@
   TestCompletionCallback callback_highest;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle_highest.Init(TestGroupId("a"), params_, absl::nullopt, HIGHEST,
+      handle_highest.Init(TestGroupId("a"), params_, std::nullopt, HIGHEST,
                           SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                           callback_highest.callback(),
                           ClientSocketPool::ProxyAuthCallback(), pool_.get(),
@@ -4627,7 +4625,7 @@
   TestCompletionCallback callback_low;
   EXPECT_EQ(ERR_IO_PENDING,
             handle_low.Init(
-                TestGroupId("a"), params_, absl::nullopt, LOW, SocketTag(),
+                TestGroupId("a"), params_, std::nullopt, LOW, SocketTag(),
                 ClientSocketPool::RespectLimits::ENABLED,
                 callback_low.callback(), ClientSocketPool::ProxyAuthCallback(),
                 pool_.get(), NetLogWithSource()));
@@ -4643,7 +4641,7 @@
   TestCompletionCallback callback_lowest2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle_lowest2.Init(TestGroupId("a"), params_, absl::nullopt, LOWEST,
+      handle_lowest2.Init(TestGroupId("a"), params_, std::nullopt, LOWEST,
                           SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                           callback_lowest2.callback(),
                           ClientSocketPool::ProxyAuthCallback(), pool_.get(),
@@ -4672,7 +4670,7 @@
   TestCompletionCallback callback_medium;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle_medium.Init(TestGroupId("a"), params_, absl::nullopt, MEDIUM,
+      handle_medium.Init(TestGroupId("a"), params_, std::nullopt, MEDIUM,
                          SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                          callback_medium.callback(),
                          ClientSocketPool::ProxyAuthCallback(), pool_.get(),
@@ -4704,7 +4702,7 @@
   TestCompletionCallback callback1;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -4720,7 +4718,7 @@
   TestCompletionCallback callback2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -4755,7 +4753,7 @@
   TestCompletionCallback callback1;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -4774,7 +4772,7 @@
   TestCompletionCallback callback2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -4813,7 +4811,7 @@
   TestCompletionCallback callback1;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle1.Init(TestGroupId("a"), params_, absl::nullopt, HIGHEST,
+      handle1.Init(TestGroupId("a"), params_, std::nullopt, HIGHEST,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -4829,7 +4827,7 @@
   TestCompletionCallback callback2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle2.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle2.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -4876,7 +4874,7 @@
   int RequestSocket(TransportClientSocketPool* pool) {
     return handle_.Init(
         group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
-        absl::nullopt, DEFAULT_PRIORITY, SocketTag(),
+        std::nullopt, DEFAULT_PRIORITY, SocketTag(),
         ClientSocketPool::RespectLimits::ENABLED, callback_.callback(),
         ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
   }
@@ -4884,7 +4882,7 @@
   int RequestSocketWithoutLimits(TransportClientSocketPool* pool) {
     return handle_.Init(
         group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
-        absl::nullopt, MAXIMUM_PRIORITY, SocketTag(),
+        std::nullopt, MAXIMUM_PRIORITY, SocketTag(),
         ClientSocketPool::RespectLimits::DISABLED, callback_.callback(),
         ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
   }
@@ -4927,7 +4925,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -4951,7 +4949,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -4973,7 +4971,7 @@
   // has the maximum number of connections already, it's not stalled).
   ClientSocketHandle handle1;
   TestCompletionCallback callback1;
-  EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, absl::nullopt,
+  EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, std::nullopt,
                              DEFAULT_PRIORITY, SocketTag(),
                              ClientSocketPool::RespectLimits::ENABLED,
                              callback1.callback(),
@@ -4989,7 +4987,7 @@
   TestCompletionCallback callback2;
   EXPECT_EQ(ERR_IO_PENDING,
             handle.Init(
-                TestGroupId("group2"), params_, absl::nullopt, DEFAULT_PRIORITY,
+                TestGroupId("group2"), params_, std::nullopt, DEFAULT_PRIORITY,
                 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                 pool_.get(), NetLogWithSource()));
@@ -5010,7 +5008,7 @@
 
   ClientSocketHandle handle1;
   TestCompletionCallback callback1;
-  EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, absl::nullopt,
+  EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, std::nullopt,
                              DEFAULT_PRIORITY, SocketTag(),
                              ClientSocketPool::RespectLimits::ENABLED,
                              callback1.callback(),
@@ -5029,7 +5027,7 @@
   TestCompletionCallback callback3;
   EXPECT_EQ(ERR_IO_PENDING,
             handle3.Init(
-                TestGroupId("group3"), params_, absl::nullopt, DEFAULT_PRIORITY,
+                TestGroupId("group3"), params_, std::nullopt, DEFAULT_PRIORITY,
                 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                 callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
                 pool_.get(), NetLogWithSource()));
@@ -5045,7 +5043,7 @@
   TestCompletionCallback callback4;
   EXPECT_EQ(ERR_IO_PENDING,
             handle4.Init(
-                TestGroupId("group3"), params_, absl::nullopt, DEFAULT_PRIORITY,
+                TestGroupId("group3"), params_, std::nullopt, DEFAULT_PRIORITY,
                 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                 callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
                 pool_.get(), NetLogWithSource()));
@@ -5075,7 +5073,7 @@
 
   ClientSocketHandle handle1;
   TestCompletionCallback callback1;
-  EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, absl::nullopt,
+  EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, std::nullopt,
                              DEFAULT_PRIORITY, SocketTag(),
                              ClientSocketPool::RespectLimits::ENABLED,
                              callback1.callback(),
@@ -5094,7 +5092,7 @@
   TestCompletionCallback callback3;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle3.Init(TestGroupId("group3"), params_, absl::nullopt, MEDIUM,
+      handle3.Init(TestGroupId("group3"), params_, std::nullopt, MEDIUM,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -5109,7 +5107,7 @@
   TestCompletionCallback callback4;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle4.Init(TestGroupId("group3"), params_, absl::nullopt, HIGHEST,
+      handle4.Init(TestGroupId("group3"), params_, std::nullopt, HIGHEST,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback4.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()));
@@ -5141,7 +5139,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -5223,7 +5221,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(TestGroupId("a"), params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(TestGroupId("a"), params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()));
@@ -5255,7 +5253,7 @@
           ClientSocketPool::RespectLimits::ENABLED,
       const ClientSocketPool::GroupId& group_id_in = TestGroupId("a")) {
     EXPECT_EQ(ERR_IO_PENDING,
-              handle_.Init(group_id_in, params, absl::nullopt, priority,
+              handle_.Init(group_id_in, params, std::nullopt, priority,
                            SocketTag(), respect_limits, callback_.callback(),
                            base::BindRepeating(&TestAuthHelper::AuthCallback,
                                                base::Unretained(this)),
@@ -5787,7 +5785,7 @@
   ClientSocketHandle handle;
   TestCompletionCallback callback;
   EXPECT_THAT(
-      handle.Init(kGroupId, params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(kGroupId, params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()),
@@ -5817,11 +5815,11 @@
   const ClientSocketPool::GroupId kGroupIdInPartition = GetGroupIdInPartition();
 
   EXPECT_EQ(
-      OK, pool_->RequestSockets(kGroupId, params_, absl::nullopt, 2,
+      OK, pool_->RequestSockets(kGroupId, params_, std::nullopt, 2,
                                 CompletionOnceCallback(), NetLogWithSource()));
 
   EXPECT_EQ(
-      OK, pool_->RequestSockets(kGroupIdInPartition, params_, absl::nullopt, 2,
+      OK, pool_->RequestSockets(kGroupIdInPartition, params_, std::nullopt, 2,
                                 CompletionOnceCallback(), NetLogWithSource()));
   ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId));
   ASSERT_TRUE(pool_->HasGroupForTesting(kGroupIdInPartition));
@@ -5844,7 +5842,7 @@
       TestGroupId("b", 443, url::kHttpsScheme);
 
   EXPECT_EQ(
-      OK, pool_->RequestSockets(kOtherGroupId, params_, absl::nullopt, 2,
+      OK, pool_->RequestSockets(kOtherGroupId, params_, std::nullopt, 2,
                                 CompletionOnceCallback(), NetLogWithSource()));
   ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId));
   EXPECT_EQ(2, pool_->IdleSocketCount());
@@ -5863,7 +5861,7 @@
   ClientSocketHandle handle;
   TestCompletionCallback callback;
   EXPECT_THAT(
-      handle.Init(kGroupId, params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(kGroupId, params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()),
@@ -5889,7 +5887,7 @@
   ClientSocketHandle handle;
   TestCompletionCallback callback;
   EXPECT_THAT(
-      handle.Init(kOtherGroupId, params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle.Init(kOtherGroupId, params_, std::nullopt, DEFAULT_PRIORITY,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource()),
@@ -5969,19 +5967,19 @@
   ClientSocketHandle handle1, handle2, handle3;
   TestCompletionCallback callback;
   EXPECT_THAT(
-      handle1.Init(kGroupId1, params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(kGroupId1, params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()),
       IsOk());
   EXPECT_THAT(
-      handle2.Init(kGroupId2, params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle2.Init(kGroupId2, params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()),
       IsOk());
   EXPECT_THAT(
-      handle3.Init(kGroupId3, params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle3.Init(kGroupId3, params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()),
@@ -6041,19 +6039,19 @@
   ClientSocketHandle handle1, handle2, handle3;
   TestCompletionCallback callback;
   EXPECT_THAT(
-      handle1.Init(kGroupId, params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle1.Init(kGroupId, params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()),
       IsOk());
   EXPECT_THAT(
-      handle2.Init(kGroupIdPrivacy, params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle2.Init(kGroupIdPrivacy, params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()),
       IsOk());
   EXPECT_THAT(
-      handle3.Init(kOtherGroupId, params_, absl::nullopt, DEFAULT_PRIORITY,
+      handle3.Init(kOtherGroupId, params_, std::nullopt, DEFAULT_PRIORITY,
                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource()),
diff --git a/net/socket/client_socket_pool_manager.cc b/net/socket/client_socket_pool_manager.cc
index f158fd8..5502c5d6 100644
--- a/net/socket/client_socket_pool_manager.cc
+++ b/net/socket/client_socket_pool_manager.cc
@@ -23,7 +23,6 @@
 #include "net/socket/client_socket_pool.h"
 #include "net/socket/connect_job.h"
 #include "net/ssl/ssl_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/scheme_host_port.h"
 #include "url/url_constants.h"
@@ -125,9 +124,9 @@
   if ((request_load_flags & LOAD_IGNORE_LIMITS) != 0)
     respect_limits = ClientSocketPool::RespectLimits::DISABLED;
 
-  absl::optional<NetworkTrafficAnnotationTag> proxy_annotation =
-      proxy_info.is_direct() ? absl::nullopt
-                             : absl::optional<NetworkTrafficAnnotationTag>(
+  std::optional<NetworkTrafficAnnotationTag> proxy_annotation =
+      proxy_info.is_direct() ? std::nullopt
+                             : std::optional<NetworkTrafficAnnotationTag>(
                                    proxy_info.traffic_annotation());
   if (num_preconnect_streams) {
     return pool->RequestSockets(connection_group, std::move(socket_params),
diff --git a/net/socket/connect_job.cc b/net/socket/connect_job.cc
index ae4f3054..519c2be2 100644
--- a/net/socket/connect_job.cc
+++ b/net/socket/connect_job.cc
@@ -154,13 +154,13 @@
   done_closure_ = base::ScopedClosureRunner(std::move(done_closure));
 }
 
-absl::optional<HostResolverEndpointResult>
+std::optional<HostResolverEndpointResult>
 ConnectJob::GetHostResolverEndpointResult() const {
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void ConnectJob::SetSocket(std::unique_ptr<StreamSocket> socket,
-                           absl::optional<std::set<std::string>> dns_aliases) {
+                           std::optional<std::set<std::string>> dns_aliases) {
   if (socket) {
     net_log().AddEventReferencingSource(NetLogEventType::CONNECT_JOB_SET_SOCKET,
                                         socket->NetLog().source());
@@ -212,7 +212,7 @@
 
 void ConnectJob::OnTimeout() {
   // Make sure the socket is NULL before calling into |delegate|.
-  SetSocket(nullptr, absl::nullopt /* dns_aliases */);
+  SetSocket(nullptr, std::nullopt /* dns_aliases */);
 
   OnTimedOutInternal();
 
diff --git a/net/socket/connect_job.h b/net/socket/connect_job.h
index 07440227..32cf820 100644
--- a/net/socket/connect_job.h
+++ b/net/socket/connect_job.h
@@ -6,6 +6,7 @@
 #define NET_SOCKET_CONNECT_JOB_H_
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 
@@ -29,7 +30,6 @@
 #include "net/socket/ssl_client_socket.h"
 #include "net/ssl/ssl_config.h"
 #include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -254,9 +254,9 @@
   // Returns the `HostResolverEndpointResult` structure corresponding to the
   // chosen route. Should only be called on a successful connect. If the
   // `ConnectJob` does not make DNS queries, or does not use the SVCB/HTTPS
-  // record, it may return `absl::nullopt`, to avoid callers getting confused by
+  // record, it may return `std::nullopt`, to avoid callers getting confused by
   // an empty `IPEndPoint` list.
-  virtual absl::optional<HostResolverEndpointResult>
+  virtual std::optional<HostResolverEndpointResult>
   GetHostResolverEndpointResult() const;
 
   const LoadTimingInfo::ConnectTiming& connect_timing() const {
@@ -299,7 +299,7 @@
   }
 
   void SetSocket(std::unique_ptr<StreamSocket> socket,
-                 absl::optional<std::set<std::string>> dns_aliases);
+                 std::optional<std::set<std::string>> dns_aliases);
   void NotifyDelegateOfCompletion(int rv);
   void NotifyDelegateOfProxyAuth(const HttpResponseInfo& response,
                                  HttpAuthController* auth_controller,
diff --git a/net/socket/connect_job_factory.cc b/net/socket/connect_job_factory.cc
index 5061fd87..bce3d31 100644
--- a/net/socket/connect_job_factory.cc
+++ b/net/socket/connect_job_factory.cc
@@ -5,6 +5,7 @@
 #include "net/socket/connect_job_factory.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -27,7 +28,6 @@
 #include "net/socket/transport_connect_job.h"
 #include "net/ssl/ssl_config.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
 #include "url/gurl.h"
 #include "url/scheme_host_port.h"
@@ -172,7 +172,7 @@
 std::unique_ptr<ConnectJob> ConnectJobFactory::CreateConnectJob(
     url::SchemeHostPort endpoint,
     const ProxyChain& proxy_chain,
-    const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+    const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
     const std::vector<SSLConfig::CertAndStatus>& allowed_bad_certs,
     ConnectJobFactory::AlpnMode alpn_mode,
     bool force_tunnel,
@@ -197,7 +197,7 @@
     bool using_ssl,
     HostPortPair endpoint,
     const ProxyChain& proxy_chain,
-    const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+    const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
     bool force_tunnel,
     PrivacyMode privacy_mode,
     const OnHostResolutionCallback& resolution_callback,
@@ -220,7 +220,7 @@
 std::unique_ptr<ConnectJob> ConnectJobFactory::CreateConnectJob(
     Endpoint endpoint,
     const ProxyChain& proxy_chain,
-    const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+    const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
     const std::vector<SSLConfig::CertAndStatus>& allowed_bad_certs,
     ConnectJobFactory::AlpnMode alpn_mode,
     bool force_tunnel,
diff --git a/net/socket/connect_job_factory.h b/net/socket/connect_job_factory.h
index ebf6a59..782fb3b 100644
--- a/net/socket/connect_job_factory.h
+++ b/net/socket/connect_job_factory.h
@@ -6,6 +6,7 @@
 #define NET_SOCKET_CONNECT_JOB_FACTORY_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "net/base/host_port_pair.h"
@@ -20,7 +21,6 @@
 #include "net/socket/ssl_connect_job.h"
 #include "net/socket/transport_connect_job.h"
 #include "net/ssl/ssl_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
 #include "url/scheme_host_port.h"
 
@@ -86,7 +86,7 @@
   std::unique_ptr<ConnectJob> CreateConnectJob(
       url::SchemeHostPort endpoint,
       const ProxyChain& proxy_chain,
-      const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+      const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
       const std::vector<SSLConfig::CertAndStatus>& allowed_bad_certs,
       ConnectJobFactory::AlpnMode alpn_mode,
       bool force_tunnel,
@@ -106,7 +106,7 @@
       bool using_ssl,
       HostPortPair endpoint,
       const ProxyChain& proxy_chain,
-      const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+      const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
       bool force_tunnel,
       PrivacyMode privacy_mode,
       const OnHostResolutionCallback& resolution_callback,
@@ -121,7 +121,7 @@
   virtual std::unique_ptr<ConnectJob> CreateConnectJob(
       Endpoint endpoint,
       const ProxyChain& proxy_chain,
-      const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+      const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
       const std::vector<SSLConfig::CertAndStatus>& allowed_bad_certs,
       ConnectJobFactory::AlpnMode alpn_mode,
       bool force_tunnel,
diff --git a/net/socket/connect_job_factory_unittest.cc b/net/socket/connect_job_factory_unittest.cc
index c2e0b4e..93a0b64 100644
--- a/net/socket/connect_job_factory_unittest.cc
+++ b/net/socket/connect_job_factory_unittest.cc
@@ -5,6 +5,7 @@
 #include "net/socket/connect_job_factory.h"
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "base/memory/raw_ptr.h"
@@ -31,7 +32,6 @@
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/scheme_host_port.h"
 #include "url/url_constants.h"
 
@@ -205,7 +205,7 @@
   const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 82);
 
   std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
-      kEndpoint, ProxyChain::Direct(), /*proxy_annotation_tag=*/absl::nullopt,
+      kEndpoint, ProxyChain::Direct(), /*proxy_annotation_tag=*/std::nullopt,
       /*allowed_bad_certs=*/{}, ConnectJobFactory::AlpnMode::kHttpAll,
       /*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
       OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
@@ -226,7 +226,7 @@
 
   std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
       /*using_ssl=*/false, kEndpoint, ProxyChain::Direct(),
-      /*proxy_annotation_tag=*/absl::nullopt,
+      /*proxy_annotation_tag=*/std::nullopt,
       /*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
       OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
@@ -244,7 +244,7 @@
   const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 84);
 
   std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
-      kEndpoint, ProxyChain::Direct(), /*proxy_annotation_tag=*/absl::nullopt,
+      kEndpoint, ProxyChain::Direct(), /*proxy_annotation_tag=*/std::nullopt,
       /*allowed_bad_certs=*/{}, ConnectJobFactory::AlpnMode::kHttpAll,
       /*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
       OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
@@ -280,7 +280,7 @@
   const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 84);
 
   std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
-      kEndpoint, ProxyChain::Direct(), /*proxy_annotation_tag=*/absl::nullopt,
+      kEndpoint, ProxyChain::Direct(), /*proxy_annotation_tag=*/std::nullopt,
       /*allowed_bad_certs=*/{}, ConnectJobFactory::AlpnMode::kHttp11Only,
       /*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
       OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
@@ -317,7 +317,7 @@
 
   std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
       /*using_ssl=*/true, kEndpoint, ProxyChain::Direct(),
-      /*proxy_annotation_tag=*/absl::nullopt, /*force_tunnel=*/false,
+      /*proxy_annotation_tag=*/std::nullopt, /*force_tunnel=*/false,
       PrivacyMode::PRIVACY_MODE_DISABLED, OnHostResolutionCallback(),
       DEFAULT_PRIORITY, SocketTag(), NetworkAnonymizationKey(),
       SecureDnsPolicy::kAllow, &common_connect_job_params_, &delegate_);
@@ -965,7 +965,7 @@
       &websocket_endpoint_lock_manager;
 
   std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
-      kEndpoint, ProxyChain::Direct(), /*proxy_annotation_tag=*/absl::nullopt,
+      kEndpoint, ProxyChain::Direct(), /*proxy_annotation_tag=*/std::nullopt,
       /*allowed_bad_certs=*/{}, ConnectJobFactory::AlpnMode::kHttpAll,
       /*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
       OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
@@ -991,7 +991,7 @@
 
   std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
       /*using_ssl=*/false, kEndpoint, ProxyChain::Direct(),
-      /*proxy_annotation_tag=*/absl::nullopt, /*force_tunnel=*/false,
+      /*proxy_annotation_tag=*/std::nullopt, /*force_tunnel=*/false,
       PrivacyMode::PRIVACY_MODE_DISABLED, OnHostResolutionCallback(),
       DEFAULT_PRIORITY, SocketTag(), NetworkAnonymizationKey(),
       SecureDnsPolicy::kAllow, &common_connect_job_params, &delegate_);
diff --git a/net/socket/connect_job_unittest.cc b/net/socket/connect_job_unittest.cc
index 6abeb0c3..edf17c5a 100644
--- a/net/socket/connect_job_unittest.cc
+++ b/net/socket/connect_job_unittest.cc
@@ -70,7 +70,7 @@
   int ConnectInternal() override {
     SetSocket(std::make_unique<MockTCPClientSocket>(
                   AddressList(), net_log().net_log(), &socket_data_provider_),
-              absl::nullopt /* dns_aliases */);
+              std::nullopt /* dns_aliases */);
     return socket()->Connect(base::BindOnce(
         &TestConnectJob::NotifyDelegateOfCompletion, base::Unretained(this)));
   }
diff --git a/net/socket/fuzzed_server_socket.cc b/net/socket/fuzzed_server_socket.cc
index 7e97c0f..cb1765dac 100644
--- a/net/socket/fuzzed_server_socket.cc
+++ b/net/socket/fuzzed_server_socket.cc
@@ -21,7 +21,7 @@
 
 int FuzzedServerSocket::Listen(const IPEndPoint& address,
                                int backlog,
-                               absl::optional<bool> ipv6_only) {
+                               std::optional<bool> ipv6_only) {
   DCHECK(!listen_called_);
   listening_on_ = address;
   listen_called_ = true;
diff --git a/net/socket/fuzzed_server_socket.h b/net/socket/fuzzed_server_socket.h
index d4ab620c..fde3a77 100644
--- a/net/socket/fuzzed_server_socket.h
+++ b/net/socket/fuzzed_server_socket.h
@@ -40,7 +40,7 @@
 
   int Listen(const IPEndPoint& address,
              int backlog,
-             absl::optional<bool> ipv6_only) override;
+             std::optional<bool> ipv6_only) override;
   int GetLocalAddress(IPEndPoint* address) const override;
 
   int Accept(std::unique_ptr<StreamSocket>* socket,
diff --git a/net/socket/server_socket.cc b/net/socket/server_socket.cc
index 5d8c8f0..333103a 100644
--- a/net/socket/server_socket.cc
+++ b/net/socket/server_socket.cc
@@ -23,7 +23,7 @@
   }
 
   return Listen(IPEndPoint(ip_address, port), backlog,
-                /*ipv6_only=*/absl::nullopt);
+                /*ipv6_only=*/std::nullopt);
 }
 
 int ServerSocket::Accept(std::unique_ptr<StreamSocket>* socket,
diff --git a/net/socket/server_socket.h b/net/socket/server_socket.h
index 6fc0b7a..d4c8735 100644
--- a/net/socket/server_socket.h
+++ b/net/socket/server_socket.h
@@ -8,11 +8,11 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "net/base/completion_once_callback.h"
 #include "net/base/net_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -36,7 +36,7 @@
   // default behavior (|true| on Windows, |false| on Posix).
   virtual int Listen(const IPEndPoint& address,
                      int backlog,
-                     absl::optional<bool> ipv6_only) = 0;
+                     std::optional<bool> ipv6_only) = 0;
 
   // Binds the socket with address and port, and starts listening. It expects
   // a valid IPv4 or IPv6 address. Otherwise, it returns ERR_ADDRESS_INVALID.
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index dc3017b..0bfdf2f 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -1405,7 +1405,7 @@
   return data_->next_proto;
 }
 
-absl::optional<base::StringPiece>
+std::optional<base::StringPiece>
 MockSSLClientSocket::GetPeerApplicationSettings() const {
   return data_->peer_application_settings;
 }
@@ -1944,7 +1944,7 @@
 int MockTransportClientSocketPool::RequestSocket(
     const ClientSocketPool::GroupId& group_id,
     scoped_refptr<ClientSocketPool::SocketParams> socket_params,
-    const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+    const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
     RequestPriority priority,
     const SocketTag& socket_tag,
     RespectLimits respect_limits,
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h
index 253ca31..2c72d959 100644
--- a/net/socket/socket_test_util.h
+++ b/net/socket/socket_test_util.h
@@ -10,6 +10,7 @@
 
 #include <cstring>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -42,7 +43,6 @@
 #include "net/ssl/ssl_config_service.h"
 #include "net/ssl/ssl_info.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class RunLoop;
@@ -286,7 +286,7 @@
   }
   bool set_keep_alive_result() const { return set_keep_alive_result_; }
 
-  const absl::optional<AddressList>& expected_addresses() const {
+  const std::optional<AddressList>& expected_addresses() const {
     return expected_addresses_;
   }
   void set_expected_addresses(net::AddressList addresses) {
@@ -331,7 +331,7 @@
   int set_send_buffer_size_result_ = net::OK;
   bool set_no_delay_result_ = true;
   bool set_keep_alive_result_ = true;
-  absl::optional<AddressList> expected_addresses_;
+  std::optional<AddressList> expected_addresses_;
 };
 
 // The AsyncSocket is an interface used by the SocketDataProvider to
@@ -486,7 +486,7 @@
   NextProto next_proto = kProtoUnknown;
 
   // Result for GetPeerApplicationSettings().
-  absl::optional<std::string> peer_application_settings;
+  std::optional<std::string> peer_application_settings;
 
   // Result for GetSSLInfo().
   SSLInfo ssl_info;
@@ -497,19 +497,19 @@
   // Result for GetECHRetryConfigs().
   std::vector<uint8_t> ech_retry_configs;
 
-  absl::optional<NextProtoVector> next_protos_expected_in_ssl_config;
-  absl::optional<SSLConfig::ApplicationSettings> expected_application_settings;
+  std::optional<NextProtoVector> next_protos_expected_in_ssl_config;
+  std::optional<SSLConfig::ApplicationSettings> expected_application_settings;
 
   uint16_t expected_ssl_version_min;
   uint16_t expected_ssl_version_max;
-  absl::optional<bool> expected_early_data_enabled;
-  absl::optional<bool> expected_send_client_cert;
+  std::optional<bool> expected_early_data_enabled;
+  std::optional<bool> expected_send_client_cert;
   scoped_refptr<X509Certificate> expected_client_cert;
-  absl::optional<HostPortPair> expected_host_and_port;
-  absl::optional<bool> expected_ignore_certificate_errors;
-  absl::optional<NetworkAnonymizationKey> expected_network_anonymization_key;
-  absl::optional<bool> expected_disable_sha1_server_signatures;
-  absl::optional<std::vector<uint8_t>> expected_ech_config_list;
+  std::optional<HostPortPair> expected_host_and_port;
+  std::optional<bool> expected_ignore_certificate_errors;
+  std::optional<NetworkAnonymizationKey> expected_network_anonymization_key;
+  std::optional<bool> expected_disable_sha1_server_signatures;
+  std::optional<std::vector<uint8_t>> expected_ech_config_list;
 
   bool is_connect_data_consumed = false;
   bool is_confirm_data_consumed = false;
@@ -902,7 +902,7 @@
   int GetPeerAddress(IPEndPoint* address) const override;
   int GetLocalAddress(IPEndPoint* address) const override;
   NextProto GetNegotiatedProtocol() const override;
-  absl::optional<base::StringPiece> GetPeerApplicationSettings() const override;
+  std::optional<base::StringPiece> GetPeerApplicationSettings() const override;
   bool GetSSLInfo(SSLInfo* ssl_info) override;
   void GetSSLCertRequestInfo(
       SSLCertRequestInfo* cert_request_info) const override;
@@ -1115,7 +1115,7 @@
         new TestSocketRequest(&request_order_, &completion_count_));
     requests_.push_back(base::WrapUnique(request));
     int rv = request->handle()->Init(
-        group_id, socket_params, absl::nullopt /* proxy_annotation_tag */,
+        group_id, socket_params, std::nullopt /* proxy_annotation_tag */,
         priority, SocketTag(), respect_limits, request->callback(),
         ClientSocketPool::ProxyAuthCallback(), socket_pool, NetLogWithSource());
     if (rv != ERR_IO_PENDING)
@@ -1223,7 +1223,7 @@
   int RequestSocket(
       const GroupId& group_id,
       scoped_refptr<ClientSocketPool::SocketParams> socket_params,
-      const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+      const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
       RequestPriority priority,
       const SocketTag& socket_tag,
       RespectLimits respect_limits,
diff --git a/net/socket/socks_connect_job.cc b/net/socket/socks_connect_job.cc
index 92c2a71..b920c28 100644
--- a/net/socket/socks_connect_job.cc
+++ b/net/socket/socks_connect_job.cc
@@ -203,7 +203,7 @@
     return result;
   }
 
-  SetSocket(std::move(socket_), absl::nullopt /* dns_aliases */);
+  SetSocket(std::move(socket_), std::nullopt /* dns_aliases */);
   return result;
 }
 
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc
index eeb2723..236de0c 100644
--- a/net/socket/ssl_client_socket_impl.cc
+++ b/net/socket/ssl_client_socket_impl.cc
@@ -547,10 +547,10 @@
   return negotiated_protocol_;
 }
 
-absl::optional<base::StringPiece>
+std::optional<base::StringPiece>
 SSLClientSocketImpl::GetPeerApplicationSettings() const {
   if (!SSL_has_application_settings(ssl_.get())) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   const uint8_t* out_data;
@@ -751,7 +751,7 @@
   if (IsCachingEnabled()) {
     bssl::UniquePtr<SSL_SESSION> session =
         context_->ssl_client_session_cache()->Lookup(
-            GetSessionCacheKey(/*dest_ip_addr=*/absl::nullopt));
+            GetSessionCacheKey(/*dest_ip_addr=*/std::nullopt));
     if (!session) {
       // If a previous session negotiated an RSA cipher suite then it may have
       // been inserted into the cache keyed by both hostname and resolved IP
@@ -1531,7 +1531,7 @@
     if (err == ERR_EARLY_DATA_REJECTED ||
         err == ERR_WRONG_VERSION_ON_EARLY_DATA) {
       context_->ssl_client_session_cache()->ClearEarlyData(
-          GetSessionCacheKey(absl::nullopt));
+          GetSessionCacheKey(std::nullopt));
     }
 
     handled_early_data_result_ = true;
@@ -1654,7 +1654,7 @@
   if (!IsCachingEnabled())
     return 0;
 
-  absl::optional<IPAddress> ip_addr;
+  std::optional<IPAddress> ip_addr;
   if (SSL_CIPHER_get_kx_nid(SSL_SESSION_get0_cipher(session)) == NID_kx_rsa) {
     // If RSA key exchange was used, additionally key the cache with the
     // destination IP address. Of course, if a proxy is being used, the
@@ -1675,7 +1675,7 @@
 }
 
 SSLClientSessionCache::Key SSLClientSocketImpl::GetSessionCacheKey(
-    absl::optional<IPAddress> dest_ip_addr) const {
+    std::optional<IPAddress> dest_ip_addr) const {
   SSLClientSessionCache::Key key;
   key.server = host_and_port_;
   key.dest_ip_addr = dest_ip_addr;
diff --git a/net/socket/ssl_client_socket_impl.h b/net/socket/ssl_client_socket_impl.h
index f2ddb4b9..d67ef97 100644
--- a/net/socket/ssl_client_socket_impl.h
+++ b/net/socket/ssl_client_socket_impl.h
@@ -9,6 +9,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -31,7 +32,6 @@
 #include "net/ssl/ssl_client_session_cache.h"
 #include "net/ssl/ssl_config.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/include/openssl/base.h"
 #include "third_party/boringssl/src/include/openssl/ssl.h"
 
@@ -91,7 +91,7 @@
   const NetLogWithSource& NetLog() const override;
   bool WasEverUsed() const override;
   NextProto GetNegotiatedProtocol() const override;
-  absl::optional<base::StringPiece> GetPeerApplicationSettings() const override;
+  std::optional<base::StringPiece> GetPeerApplicationSettings() const override;
   bool GetSSLInfo(SSLInfo* ssl_info) override;
   int64_t GetTotalReceivedBytes() const override;
   void GetSSLCertRequestInfo(
@@ -162,7 +162,7 @@
 
   // Returns a session cache key for this socket.
   SSLClientSessionCache::Key GetSessionCacheKey(
-      absl::optional<IPAddress> dest_ip_addr) const;
+      std::optional<IPAddress> dest_ip_addr) const;
 
   // Returns true if renegotiations are allowed.
   bool IsRenegotiationAllowed() const;
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc
index 6de40f11..5f2dd44 100644
--- a/net/socket/ssl_client_socket_unittest.cc
+++ b/net/socket/ssl_client_socket_unittest.cc
@@ -9,6 +9,7 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 #include <tuple>
 #include <utility>
 
@@ -89,7 +90,6 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/include/openssl/bio.h"
 #include "third_party/boringssl/src/include/openssl/evp.h"
 #include "third_party/boringssl/src/include/openssl/hpke.h"
@@ -772,12 +772,12 @@
                                                    result);
   }
 
-  absl::optional<SSLInfo> LastSSLInfoFromServer() {
+  std::optional<SSLInfo> LastSSLInfoFromServer() {
     // EmbeddedTestServer callbacks run on another thread, so protect this
     // with a lock.
     base::AutoLock lock(server_ssl_info_lock_);
     auto result = server_ssl_info_;
-    server_ssl_info_ = absl::nullopt;
+    server_ssl_info_ = std::nullopt;
     return result;
   }
 
@@ -808,7 +808,7 @@
 
   std::unique_ptr<EmbeddedTestServer> embedded_test_server_;
   base::Lock server_ssl_info_lock_;
-  absl::optional<SSLInfo> server_ssl_info_ GUARDED_BY(server_ssl_info_lock_);
+  std::optional<SSLInfo> server_ssl_info_ GUARDED_BY(server_ssl_info_lock_);
   TestCompletionCallback callback_;
   AddressList addr_;
   HostPortPair host_port_pair_;
@@ -2372,7 +2372,7 @@
     ASSERT_TRUE(CreateAndConnectSSLClientSocket(config, &rv));
     EXPECT_THAT(rv, IsError(ERR_UNEXPECTED));
 
-    config.version_min_override = absl::nullopt;
+    config.version_min_override = std::nullopt;
     config.version_max_override = version;
     ASSERT_TRUE(CreateAndConnectSSLClientSocket(config, &rv));
     EXPECT_THAT(rv, IsError(ERR_UNEXPECTED));
@@ -5100,7 +5100,7 @@
   // Set up a TCP server.
   TCPServerSocket server_listener(nullptr, NetLogSource());
   ASSERT_THAT(server_listener.Listen(IPEndPoint(IPAddress::IPv4Localhost(), 0),
-                                     1, /*ipv6_only=*/absl::nullopt),
+                                     1, /*ipv6_only=*/std::nullopt),
               IsOk());
   IPEndPoint server_address;
   ASSERT_THAT(server_listener.GetLocalAddress(&server_address), IsOk());
@@ -5194,7 +5194,7 @@
   // Set up a TCP server.
   TCPServerSocket server_listener(nullptr, NetLogSource());
   ASSERT_THAT(server_listener.Listen(IPEndPoint(IPAddress::IPv4Localhost(), 0),
-                                     1, /*ipv6_only=*/absl::nullopt),
+                                     1, /*ipv6_only=*/std::nullopt),
               IsOk());
   IPEndPoint server_address;
   ASSERT_THAT(server_listener.GetLocalAddress(&server_address), IsOk());
@@ -5309,7 +5309,7 @@
   // TLS 1.3 causes the ticket to arrive later. Use the socket to ensure we have
   // a ticket. This also populates the SSLInfo from the server.
   EXPECT_THAT(MakeHTTPRequest(sock_.get(), "/ssl-info"), IsOk());
-  absl::optional<SSLInfo> server_ssl_info = LastSSLInfoFromServer();
+  std::optional<SSLInfo> server_ssl_info = LastSSLInfoFromServer();
   ASSERT_TRUE(server_ssl_info);
   EXPECT_TRUE(server_ssl_info->encrypted_client_hello);
 
@@ -5850,10 +5850,10 @@
 // Test that the server_name extension (SNI) is sent on DNS names, and not IP
 // literals.
 TEST_F(SSLClientSocketTest, ServerName) {
-  absl::optional<std::string> got_server_name;
+  std::optional<std::string> got_server_name;
   bool ran_callback = false;
   auto reset_callback_state = [&] {
-    got_server_name = absl::nullopt;
+    got_server_name = std::nullopt;
     ran_callback = false;
   };
 
@@ -5866,7 +5866,7 @@
         if (server_name) {
           got_server_name = server_name;
         } else {
-          got_server_name = absl::nullopt;
+          got_server_name = std::nullopt;
         }
         ran_callback = true;
         return true;
@@ -5890,21 +5890,21 @@
       SSLConfig(), HostPortPair("1.2.3.4", port), &rv));
   ASSERT_THAT(rv, IsOk());
   EXPECT_TRUE(ran_callback);
-  EXPECT_EQ(got_server_name, absl::nullopt);
+  EXPECT_EQ(got_server_name, std::nullopt);
 
   reset_callback_state();
   ASSERT_TRUE(CreateAndConnectSSLClientSocketWithHost(
       SSLConfig(), HostPortPair("::1", port), &rv));
   ASSERT_THAT(rv, IsOk());
   EXPECT_TRUE(ran_callback);
-  EXPECT_EQ(got_server_name, absl::nullopt);
+  EXPECT_EQ(got_server_name, std::nullopt);
 
   reset_callback_state();
   ASSERT_TRUE(CreateAndConnectSSLClientSocketWithHost(
       SSLConfig(), HostPortPair("2001:db8::42", port), &rv));
   ASSERT_THAT(rv, IsOk());
   EXPECT_TRUE(ran_callback);
-  EXPECT_EQ(got_server_name, absl::nullopt);
+  EXPECT_EQ(got_server_name, std::nullopt);
 }
 
 class SSLClientSocketAlpsTest
diff --git a/net/socket/ssl_connect_job.cc b/net/socket/ssl_connect_job.cc
index 87ff0dd..f80d60d32 100644
--- a/net/socket/ssl_connect_job.cc
+++ b/net/socket/ssl_connect_job.cc
@@ -274,7 +274,7 @@
 
   next_state_ = STATE_TRANSPORT_CONNECT_COMPLETE;
   // If this is an ECH retry, connect to the same server as before.
-  absl::optional<TransportConnectJob::EndpointResultOverride>
+  std::optional<TransportConnectJob::EndpointResultOverride>
       endpoint_result_override;
   if (ech_retry_configs_) {
     DCHECK(ssl_client_context()->config().ech_enabled);
diff --git a/net/socket/ssl_connect_job.h b/net/socket/ssl_connect_job.h
index 396202d5..fe308b3d 100644
--- a/net/socket/ssl_connect_job.h
+++ b/net/socket/ssl_connect_job.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
@@ -26,7 +27,6 @@
 #include "net/socket/ssl_client_socket.h"
 #include "net/ssl/ssl_cert_request_info.h"
 #include "net/ssl/ssl_config_service.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -211,11 +211,11 @@
 
   // The endpoint result used by `nested_connect_job_`. Stored because
   // `nested_connect_job_` has a limited lifetime.
-  absl::optional<HostResolverEndpointResult> endpoint_result_;
+  std::optional<HostResolverEndpointResult> endpoint_result_;
 
-  // If not `absl::nullopt`, the ECH retry configs to use in the ECH recovery
+  // If not `std::nullopt`, the ECH retry configs to use in the ECH recovery
   // flow. `endpoint_result_` will then contain the endpoint to reconnect to.
-  absl::optional<std::vector<uint8_t>> ech_retry_configs_;
+  std::optional<std::vector<uint8_t>> ech_retry_configs_;
 };
 
 }  // namespace net
diff --git a/net/socket/ssl_server_socket_impl.cc b/net/socket/ssl_server_socket_impl.cc
index 0c92e26..487800f 100644
--- a/net/socket/ssl_server_socket_impl.cc
+++ b/net/socket/ssl_server_socket_impl.cc
@@ -5,6 +5,7 @@
 #include "net/socket/ssl_server_socket_impl.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "base/functional/bind.h"
@@ -28,7 +29,6 @@
 #include "net/ssl/ssl_info.h"
 #include "net/ssl/ssl_private_key.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/include/openssl/bytestring.h"
 #include "third_party/boringssl/src/include/openssl/err.h"
 #include "third_party/boringssl/src/include/openssl/pool.h"
@@ -92,7 +92,7 @@
   const NetLogWithSource& NetLog() const override;
   bool WasEverUsed() const override;
   NextProto GetNegotiatedProtocol() const override;
-  absl::optional<base::StringPiece> GetPeerApplicationSettings() const override;
+  std::optional<base::StringPiece> GetPeerApplicationSettings() const override;
   bool GetSSLInfo(SSLInfo* ssl_info) override;
   int64_t GetTotalReceivedBytes() const override;
   void ApplySocketTag(const SocketTag& tag) override;
@@ -545,10 +545,10 @@
   return negotiated_protocol_;
 }
 
-absl::optional<base::StringPiece>
+std::optional<base::StringPiece>
 SSLServerContextImpl::SocketImpl::GetPeerApplicationSettings() const {
   if (!SSL_has_application_settings(ssl_.get())) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   const uint8_t* out_data;
diff --git a/net/socket/stream_socket.cc b/net/socket/stream_socket.cc
index a8cf99a..3b670bc 100644
--- a/net/socket/stream_socket.cc
+++ b/net/socket/stream_socket.cc
@@ -13,9 +13,9 @@
   NOTREACHED();
 }
 
-absl::optional<base::StringPiece> StreamSocket::GetPeerApplicationSettings()
+std::optional<base::StringPiece> StreamSocket::GetPeerApplicationSettings()
     const {
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void StreamSocket::GetSSLCertRequestInfo(
diff --git a/net/socket/stream_socket.h b/net/socket/stream_socket.h
index c0ffd657..d5c77c3a9 100644
--- a/net/socket/stream_socket.h
+++ b/net/socket/stream_socket.h
@@ -7,13 +7,14 @@
 
 #include <stdint.h>
 
+#include <optional>
+
 #include "base/functional/bind.h"
 #include "net/base/net_errors.h"
 #include "net/base/net_export.h"
 #include "net/dns/public/resolve_error_info.h"
 #include "net/socket/next_proto.h"
 #include "net/socket/socket.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -116,7 +117,7 @@
   // Get data received from peer in ALPS TLS extension.
   // Returns a (possibly empty) value if a TLS version supporting ALPS was used
   // and ALPS was negotiated, nullopt otherwise.
-  virtual absl::optional<base::StringPiece> GetPeerApplicationSettings() const;
+  virtual std::optional<base::StringPiece> GetPeerApplicationSettings() const;
 
   // Gets the SSL connection information of the socket.  Returns false if
   // SSL was not used by this socket.
diff --git a/net/socket/tcp_client_socket.cc b/net/socket/tcp_client_socket.cc
index 0f34cd5..ddae0a2 100644
--- a/net/socket/tcp_client_socket.cc
+++ b/net/socket/tcp_client_socket.cc
@@ -288,7 +288,7 @@
 int TCPClientSocket::DoConnectComplete(int result) {
   if (start_connect_attempt_) {
     EmitConnectAttemptHistograms(result);
-    start_connect_attempt_ = absl::nullopt;
+    start_connect_attempt_ = std::nullopt;
     connect_attempt_timer_.Stop();
   }
 
@@ -342,7 +342,7 @@
 void TCPClientSocket::DoDisconnect() {
   if (start_connect_attempt_) {
     EmitConnectAttemptHistograms(ERR_ABORTED);
-    start_connect_attempt_ = absl::nullopt;
+    start_connect_attempt_ = std::nullopt;
     connect_attempt_timer_.Stop();
   }
 
@@ -581,7 +581,7 @@
   if (!base::FeatureList::IsEnabled(features::kTimeoutTcpConnectAttempt))
     return base::TimeDelta::Max();
 
-  absl::optional<base::TimeDelta> transport_rtt = absl::nullopt;
+  std::optional<base::TimeDelta> transport_rtt = std::nullopt;
   if (network_quality_estimator_)
     transport_rtt = network_quality_estimator_->GetTransportRTT();
 
diff --git a/net/socket/tcp_client_socket.h b/net/socket/tcp_client_socket.h
index b5970bc..5af7de6 100644
--- a/net/socket/tcp_client_socket.h
+++ b/net/socket/tcp_client_socket.h
@@ -233,7 +233,7 @@
   bool was_disconnected_on_suspend_ = false;
 
   // The time when the latest connect attempt was started.
-  absl::optional<base::TimeTicks> start_connect_attempt_;
+  std::optional<base::TimeTicks> start_connect_attempt_;
 
   // The NetworkQualityEstimator for the context this socket is associated with.
   // Can be nullptr.
diff --git a/net/socket/tcp_client_socket_unittest.cc b/net/socket/tcp_client_socket_unittest.cc
index 9ee8727..38dbde6 100644
--- a/net/socket/tcp_client_socket_unittest.cc
+++ b/net/socket/tcp_client_socket_unittest.cc
@@ -74,7 +74,7 @@
     std::unique_ptr<TCPServerSocket> server_socket =
         std::make_unique<TCPServerSocket>(nullptr, NetLogSource());
     ASSERT_THAT(server_socket->Listen(IPEndPoint(local_address, 0), 1,
-                                      /*ipv6_only=*/absl::nullopt),
+                                      /*ipv6_only=*/std::nullopt),
                 IsOk());
     IPEndPoint server_address;
     ASSERT_THAT(server_socket->GetLocalAddress(&server_address), IsOk());
@@ -118,7 +118,7 @@
 
   TCPServerSocket server(nullptr, NetLogSource());
   ASSERT_THAT(server.Listen(IPEndPoint(lo_address, 0), 1,
-                            /*ipv6_only=*/absl::nullopt),
+                            /*ipv6_only=*/std::nullopt),
               IsOk());
   IPEndPoint server_address;
   ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
@@ -173,7 +173,7 @@
   TCPServerSocket server(nullptr, NetLogSource());
   int listen_result =
       server.Listen(IPEndPoint(IPAddress::IPv6Localhost(), 0), 1,
-                    /*ipv6_only=*/absl::nullopt);
+                    /*ipv6_only=*/std::nullopt);
   if (listen_result != OK) {
     LOG(ERROR) << "Failed to listen on ::1 - probably because IPv6 is disabled."
                   " Skipping the test";
@@ -197,7 +197,7 @@
   IPAddress lo_address = IPAddress::IPv4Localhost();
   TCPServerSocket server(nullptr, NetLogSource());
   ASSERT_THAT(
-      server.Listen(IPEndPoint(lo_address, 0), 1, /*ipv6_only=*/absl::nullopt),
+      server.Listen(IPEndPoint(lo_address, 0), 1, /*ipv6_only=*/std::nullopt),
       IsOk());
   IPEndPoint server_address;
   ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
@@ -247,7 +247,7 @@
   IPAddress lo_address = IPAddress::IPv4Localhost();
   TCPServerSocket server(nullptr, NetLogSource());
   ASSERT_THAT(
-      server.Listen(IPEndPoint(lo_address, 0), 1, /*ipv6_only=*/absl::nullopt),
+      server.Listen(IPEndPoint(lo_address, 0), 1, /*ipv6_only=*/std::nullopt),
       IsOk());
   IPEndPoint server_address;
   ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
@@ -506,7 +506,7 @@
 
   TCPServerSocket server(nullptr, NetLogSource());
   ASSERT_THAT(
-      server.Listen(IPEndPoint(lo_address, 0), 1, /*ipv6_only=*/absl::nullopt),
+      server.Listen(IPEndPoint(lo_address, 0), 1, /*ipv6_only=*/std::nullopt),
       IsOk());
   IPEndPoint server_address;
   ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
@@ -546,7 +546,7 @@
 
   TCPServerSocket server(nullptr, NetLogSource());
   ASSERT_THAT(
-      server.Listen(IPEndPoint(lo_address, 0), 1, /*ipv6_only=*/absl::nullopt),
+      server.Listen(IPEndPoint(lo_address, 0), 1, /*ipv6_only=*/std::nullopt),
       IsOk());
   IPEndPoint server_address;
   ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
@@ -573,7 +573,7 @@
 
   TCPServerSocket server(nullptr, NetLogSource());
   ASSERT_THAT(server.Listen(IPEndPoint(IPAddress(0, 0, 0, 0), 0), 1,
-                            /*ipv6_only=*/absl::nullopt),
+                            /*ipv6_only=*/std::nullopt),
               IsOk());
   IPEndPoint server_address;
   ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk());
diff --git a/net/socket/tcp_server_socket.cc b/net/socket/tcp_server_socket.cc
index ca80449..7154fd8e 100644
--- a/net/socket/tcp_server_socket.cc
+++ b/net/socket/tcp_server_socket.cc
@@ -35,7 +35,7 @@
 
 int TCPServerSocket::Listen(const IPEndPoint& address,
                             int backlog,
-                            absl::optional<bool> ipv6_only) {
+                            std::optional<bool> ipv6_only) {
   int result = OK;
   if (!adopted_opened_socket_) {
     result = socket_->Open(address.GetFamily());
diff --git a/net/socket/tcp_server_socket.h b/net/socket/tcp_server_socket.h
index 7fe17671..528248e5 100644
--- a/net/socket/tcp_server_socket.h
+++ b/net/socket/tcp_server_socket.h
@@ -41,7 +41,7 @@
   // net::ServerSocket implementation.
   int Listen(const IPEndPoint& address,
              int backlog,
-             absl::optional<bool> ipv6_only) override;
+             std::optional<bool> ipv6_only) override;
   int GetLocalAddress(IPEndPoint* address) const override;
   int Accept(std::unique_ptr<StreamSocket>* socket,
              CompletionOnceCallback callback) override;
diff --git a/net/socket/tcp_server_socket_unittest.cc b/net/socket/tcp_server_socket_unittest.cc
index f198e69..e4d5a04 100644
--- a/net/socket/tcp_server_socket_unittest.cc
+++ b/net/socket/tcp_server_socket_unittest.cc
@@ -40,7 +40,7 @@
   void SetUpIPv4() {
     IPEndPoint address(IPAddress::IPv4Localhost(), 0);
     ASSERT_THAT(
-        socket_.Listen(address, kListenBacklog, /*ipv6_only=*/absl::nullopt),
+        socket_.Listen(address, kListenBacklog, /*ipv6_only=*/std::nullopt),
         IsOk());
     ASSERT_THAT(socket_.GetLocalAddress(&local_address_), IsOk());
   }
@@ -48,7 +48,7 @@
   void SetUpIPv6(bool* success) {
     *success = false;
     IPEndPoint address(IPAddress::IPv6Localhost(), 0);
-    if (socket_.Listen(address, kListenBacklog, /*ipv6_only=*/absl::nullopt) !=
+    if (socket_.Listen(address, kListenBacklog, /*ipv6_only=*/std::nullopt) !=
         0) {
       LOG(ERROR) << "Failed to listen on ::1 - probably because IPv6 is "
           "disabled. Skipping the test";
diff --git a/net/socket/transport_client_socket_pool.cc b/net/socket/transport_client_socket_pool.cc
index 5b6bd412..8736f82 100644
--- a/net/socket/transport_client_socket_pool.cc
+++ b/net/socket/transport_client_socket_pool.cc
@@ -81,7 +81,7 @@
     RespectLimits respect_limits,
     Flags flags,
     scoped_refptr<SocketParams> socket_params,
-    const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+    const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
     const NetLogWithSource& net_log)
     : handle_(handle),
       callback_(std::move(callback)),
@@ -244,7 +244,7 @@
 int TransportClientSocketPool::RequestSocket(
     const GroupId& group_id,
     scoped_refptr<SocketParams> params,
-    const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+    const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
     RequestPriority priority,
     const SocketTag& socket_tag,
     RespectLimits respect_limits,
@@ -298,7 +298,7 @@
 int TransportClientSocketPool::RequestSockets(
     const GroupId& group_id,
     scoped_refptr<SocketParams> params,
-    const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+    const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
     int num_sockets,
     CompletionOnceCallback callback,
     const NetLogWithSource& net_log) {
@@ -1309,7 +1309,7 @@
 
   // Check if the ConnectJob is already bound to a Request. If so, result is
   // returned to that specific request.
-  absl::optional<Group::BoundRequest> bound_request =
+  std::optional<Group::BoundRequest> bound_request =
       group->FindAndRemoveBoundRequestForConnectJob(job);
   Request* request = nullptr;
   std::unique_ptr<Request> owned_request;
@@ -1834,7 +1834,7 @@
   return request;
 }
 
-absl::optional<TransportClientSocketPool::Group::BoundRequest>
+std::optional<TransportClientSocketPool::Group::BoundRequest>
 TransportClientSocketPool::Group::FindAndRemoveBoundRequestForConnectJob(
     ConnectJob* connect_job) {
   for (auto bound_pair = bound_requests_.begin();
@@ -1845,7 +1845,7 @@
     bound_requests_.erase(bound_pair);
     return std::move(ret);
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 std::unique_ptr<TransportClientSocketPool::Request>
diff --git a/net/socket/transport_client_socket_pool.h b/net/socket/transport_client_socket_pool.h
index bb218b3f..0294c8d 100644
--- a/net/socket/transport_client_socket_pool.h
+++ b/net/socket/transport_client_socket_pool.h
@@ -11,6 +11,7 @@
 #include <list>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
@@ -39,7 +40,6 @@
 #include "net/socket/socket_tag.h"
 #include "net/socket/ssl_client_socket.h"
 #include "net/socket/stream_socket.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -99,7 +99,7 @@
         RespectLimits respect_limits,
         Flags flags,
         scoped_refptr<SocketParams> socket_params,
-        const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+        const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
         const NetLogWithSource& net_log);
 
     Request(const Request&) = delete;
@@ -117,7 +117,7 @@
     RespectLimits respect_limits() const { return respect_limits_; }
     Flags flags() const { return flags_; }
     SocketParams* socket_params() const { return socket_params_.get(); }
-    const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag()
+    const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag()
         const {
       return proxy_annotation_tag_;
     }
@@ -141,7 +141,7 @@
     const RespectLimits respect_limits_;
     const Flags flags_;
     const scoped_refptr<SocketParams> socket_params_;
-    const absl::optional<NetworkTrafficAnnotationTag> proxy_annotation_tag_;
+    const std::optional<NetworkTrafficAnnotationTag> proxy_annotation_tag_;
     const NetLogWithSource net_log_;
     const SocketTag socket_tag_;
     raw_ptr<ConnectJob> job_ = nullptr;
@@ -191,7 +191,7 @@
   int RequestSocket(
       const GroupId& group_id,
       scoped_refptr<SocketParams> params,
-      const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+      const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
       RequestPriority priority,
       const SocketTag& socket_tag,
       RespectLimits respect_limits,
@@ -202,7 +202,7 @@
   int RequestSockets(
       const GroupId& group_id,
       scoped_refptr<SocketParams> params,
-      const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+      const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
       int num_sockets,
       CompletionOnceCallback callback,
       const NetLogWithSource& net_log) override;
@@ -429,8 +429,8 @@
     const Request* BindRequestToConnectJob(ConnectJob* connect_job);
 
     // Finds the request, if any, bound to |connect_job|, and returns the
-    // BoundRequest or absl::nullopt if there was none.
-    absl::optional<BoundRequest> FindAndRemoveBoundRequestForConnectJob(
+    // BoundRequest or std::nullopt if there was none.
+    std::optional<BoundRequest> FindAndRemoveBoundRequestForConnectJob(
         ConnectJob* connect_job);
 
     // Finds the bound request, if any, corresponding to |client_socket_handle|
diff --git a/net/socket/transport_client_socket_pool_test_util.cc b/net/socket/transport_client_socket_pool_test_util.cc
index c0ff3b0..5618150 100644
--- a/net/socket/transport_client_socket_pool_test_util.cc
+++ b/net/socket/transport_client_socket_pool_test_util.cc
@@ -342,7 +342,7 @@
 
 MockTransportClientSocketFactory::Rule::Rule(
     Type type,
-    absl::optional<std::vector<IPEndPoint>> expected_addresses,
+    std::optional<std::vector<IPEndPoint>> expected_addresses,
     Error connect_error)
     : type(type),
       expected_addresses(std::move(expected_addresses)),
diff --git a/net/socket/transport_client_socket_pool_test_util.h b/net/socket/transport_client_socket_pool_test_util.h
index 535f525..58295d3 100644
--- a/net/socket/transport_client_socket_pool_test_util.h
+++ b/net/socket/transport_client_socket_pool_test_util.h
@@ -10,6 +10,7 @@
 #define NET_SOCKET_TRANSPORT_CLIENT_SOCKET_POOL_TEST_UTIL_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "base/compiler_specific.h"
@@ -23,7 +24,6 @@
 #include "net/socket/client_socket_handle.h"
 #include "net/socket/socket_performance_watcher.h"
 #include "net/socket/stream_socket.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -76,8 +76,8 @@
   // A rule describing a mock `TransportClientSocket` to create.
   struct Rule {
     explicit Rule(Type type,
-                  absl::optional<std::vector<IPEndPoint>> expected_addresses =
-                      absl::nullopt,
+                  std::optional<std::vector<IPEndPoint>> expected_addresses =
+                      std::nullopt,
                   Error connect_error = ERR_CONNECTION_FAILED);
     ~Rule();
     Rule(const Rule&);
@@ -86,7 +86,7 @@
     Type type;
     // If specified, the addresses that should be passed into
     // `CreateTransportClientSocket`.
-    absl::optional<std::vector<IPEndPoint>> expected_addresses;
+    std::optional<std::vector<IPEndPoint>> expected_addresses;
     // The error to use if `type` specifies a failing connection. Ignored
     // otherwise.
     Error connect_error;
diff --git a/net/socket/transport_client_socket_pool_unittest.cc b/net/socket/transport_client_socket_pool_unittest.cc
index e4de5bd..5ba5592 100644
--- a/net/socket/transport_client_socket_pool_unittest.cc
+++ b/net/socket/transport_client_socket_pool_unittest.cc
@@ -5,6 +5,7 @@
 #include "net/socket/transport_client_socket_pool.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "base/functional/bind.h"
@@ -58,7 +59,6 @@
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/scheme_host_port.h"
 #include "url/url_constants.h"
@@ -230,7 +230,7 @@
   TestCompletionCallback callback;
   ClientSocketHandle handle;
   int rv =
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource());
@@ -254,9 +254,9 @@
     ClientSocketHandle handle;
     EXPECT_EQ(
         ERR_IO_PENDING,
-        handle.Init(group_id_, params_,
-                    absl::nullopt /* proxy_annotation_tag */, priority,
-                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
+        handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
+                    priority, SocketTag(),
+                    ClientSocketPool::RespectLimits::ENABLED,
                     callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource()));
     EXPECT_EQ(priority, session_deps_.host_resolver->last_request_priority());
@@ -274,7 +274,7 @@
         secure_dns_policy, /*disable_cert_network_fetches=*/false);
     EXPECT_EQ(
         ERR_IO_PENDING,
-        handle.Init(group_id, params_, absl::nullopt /* proxy_annotation_tag */,
+        handle.Init(group_id, params_, std::nullopt /* proxy_annotation_tag */,
                     LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                     callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                     pool_.get(), NetLogWithSource()));
@@ -289,7 +289,7 @@
   TestCompletionCallback callback1;
   ClientSocketHandle handle1;
   int rv1 =
-      handle1.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle1.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                    LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource());
@@ -298,7 +298,7 @@
   TestCompletionCallback callback2;
   ClientSocketHandle handle2;
   int rv2 = handle2.Init(
-      group_id_, params_, absl::nullopt /* proxy_annotation_tag */, HIGHEST,
+      group_id_, params_, std::nullopt /* proxy_annotation_tag */, HIGHEST,
       SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
       callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(),
       NetLogWithSource());
@@ -307,7 +307,7 @@
   TestCompletionCallback callback3;
   ClientSocketHandle handle3;
   int rv3 = handle3.Init(
-      group_id_, params_, absl::nullopt /* proxy_annotation_tag */, LOWEST,
+      group_id_, params_, std::nullopt /* proxy_annotation_tag */, LOWEST,
       SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
       callback3.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(),
       NetLogWithSource());
@@ -316,7 +316,7 @@
   TestCompletionCallback callback4;
   ClientSocketHandle handle4;
   int rv4 = handle4.Init(
-      group_id_, params_, absl::nullopt /* proxy_annotation_tag */, MEDIUM,
+      group_id_, params_, std::nullopt /* proxy_annotation_tag */, MEDIUM,
       SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
       callback4.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(),
       NetLogWithSource());
@@ -325,7 +325,7 @@
   TestCompletionCallback callback5;
   ClientSocketHandle handle5;
   int rv5 = handle5.Init(
-      group_id_, params_, absl::nullopt /* proxy_annotation_tag */, HIGHEST,
+      group_id_, params_, std::nullopt /* proxy_annotation_tag */, HIGHEST,
       SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
       callback5.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(),
       NetLogWithSource());
@@ -334,7 +334,7 @@
   TestCompletionCallback callback6;
   ClientSocketHandle handle6;
   int rv6 =
-      handle6.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle6.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                    LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback6.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource());
@@ -364,7 +364,7 @@
   TestCompletionCallback callback7;
   ClientSocketHandle handle7;
   int rv7 = handle7.Init(
-      group_id_, params_, absl::nullopt /* proxy_annotation_tag */, HIGHEST,
+      group_id_, params_, std::nullopt /* proxy_annotation_tag */, HIGHEST,
       SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
       callback7.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(),
       NetLogWithSource());
@@ -389,7 +389,7 @@
   TestCompletionCallback callback8;
   ClientSocketHandle handle8;
   int rv8 = handle8.Init(
-      group_id_, params_, absl::nullopt /* proxy_annotation_tag */, HIGHEST,
+      group_id_, params_, std::nullopt /* proxy_annotation_tag */, HIGHEST,
       SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
       callback8.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(),
       NetLogWithSource());
@@ -540,7 +540,7 @@
   TestCompletionCallback callback1;
   ClientSocketHandle handle1;
   int rv1 = handle1.Init(
-      group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      group_id_, params_, std::nullopt /* proxy_annotation_tag */,
       MAXIMUM_PRIORITY, SocketTag(), ClientSocketPool::RespectLimits::DISABLED,
       callback1.callback(), ClientSocketPool::ProxyAuthCallback(), &pool,
       NetLogWithSource());
@@ -551,7 +551,7 @@
   TestCompletionCallback callback2;
   ClientSocketHandle handle2;
   int rv2 =
-      handle2.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle2.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                    LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                    &pool, NetLogWithSource());
@@ -569,7 +569,7 @@
   ClientSocketHandle handle;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   kDefaultPriority, SocketTag(),
                   ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
                   ClientSocketPool::ProxyAuthCallback(), pool_.get(),
@@ -589,7 +589,7 @@
   ClientSocketHandle handle;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   kDefaultPriority, SocketTag(),
                   ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
                   ClientSocketPool::ProxyAuthCallback(), pool_.get(),
@@ -605,7 +605,7 @@
   session_deps_.host_resolver->set_synchronous_mode(true);
   EXPECT_EQ(
       ERR_CONNECTION_FAILED,
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   kDefaultPriority, SocketTag(),
                   ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
                   ClientSocketPool::ProxyAuthCallback(), pool_.get(),
@@ -721,7 +721,7 @@
   ClientSocketHandle handle;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   kDefaultPriority, SocketTag(),
                   ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
                   ClientSocketPool::ProxyAuthCallback(), pool_.get(),
@@ -737,14 +737,14 @@
 
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   kDefaultPriority, SocketTag(),
                   ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
                   ClientSocketPool::ProxyAuthCallback(), pool_.get(),
                   NetLogWithSource()));
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle2.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle2.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                    kDefaultPriority, SocketTag(),
                    ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
@@ -763,7 +763,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   kDefaultPriority, SocketTag(),
                   ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
                   ClientSocketPool::ProxyAuthCallback(), pool_.get(),
@@ -774,7 +774,7 @@
   TestCompletionCallback callback2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   kDefaultPriority, SocketTag(),
                   ClientSocketPool::RespectLimits::ENABLED,
                   callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
@@ -890,7 +890,7 @@
       base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
       within_callback_ = true;
       int rv = handle_->Init(
-          group_id_, socket_params_, absl::nullopt /* proxy_annotation_tag */,
+          group_id_, socket_params_, std::nullopt /* proxy_annotation_tag */,
           LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
           callback(), ClientSocketPool::ProxyAuthCallback(), pool_,
           NetLogWithSource());
@@ -909,7 +909,7 @@
   ClientSocketHandle handle;
   RequestSocketCallback callback(group_id_, params_, &handle, pool_.get());
   int rv =
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource());
@@ -976,7 +976,7 @@
   TestCompletionCallback callback;
   ClientSocketHandle handle;
   int rv =
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource());
@@ -996,7 +996,7 @@
   // Now we should have 1 idle socket.
   EXPECT_EQ(1, pool_->IdleSocketCount());
 
-  rv = handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+  rv = handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                    LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource());
@@ -1009,7 +1009,7 @@
   TestCompletionCallback callback;
   ClientSocketHandle handle;
   int rv =
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource());
@@ -1068,7 +1068,7 @@
   TestCompletionCallback callback;
   ClientSocketHandle handle;
   int rv =
-      handle.Init(group_id, params, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id, params, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool.get(), NetLogWithSource());
@@ -1113,7 +1113,7 @@
                       kEndpoint, PrivacyMode::PRIVACY_MODE_DISABLED,
                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
                       /*disable_cert_network_fetches=*/false),
-                  socket_params, absl::nullopt /* proxy_annotation_tag */,
+                  socket_params, std::nullopt /* proxy_annotation_tag */,
                   MEDIUM, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   tagging_pool_.get(), NetLogWithSource());
@@ -1172,7 +1172,7 @@
     TestCompletionCallback callback;
     ClientSocketHandle handle1;
     int rv =
-        handle1.Init(group_id_, params_, /*proxy_annotation_tag=*/absl::nullopt,
+        handle1.Init(group_id_, params_, /*proxy_annotation_tag=*/std::nullopt,
                      LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                      callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                      pool_.get(), NetLogWithSource());
@@ -1205,7 +1205,7 @@
         SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false);
     TestCompletionCallback callback;
     int rv =
-        handle2.Init(group_id2, params_, /*proxy_annotation_tag=*/absl::nullopt,
+        handle2.Init(group_id2, params_, /*proxy_annotation_tag=*/std::nullopt,
                      LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                      callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                      pool_.get(), NetLogWithSource());
@@ -1231,7 +1231,7 @@
   TestCompletionCallback callback3;
   ClientSocketHandle handle3;
   int rv =
-      handle3.Init(group_id3, params_, /*proxy_annotation_tag=*/absl::nullopt,
+      handle3.Init(group_id3, params_, /*proxy_annotation_tag=*/std::nullopt,
                    LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback3.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_.get(), NetLogWithSource());
@@ -1320,11 +1320,11 @@
 
     TestCompletionCallback callback;
     ClientSocketHandle handle;
-    int rv = handle.Init(
-        group_id_, params_, absl::nullopt /* proxy_annotation_tag */, LOW,
-        SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
-        callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(),
-        NetLogWithSource());
+    int rv =
+        handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
+                    LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
+                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
+                    pool_.get(), NetLogWithSource());
     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
     EXPECT_FALSE(handle.is_initialized());
     EXPECT_FALSE(handle.socket());
@@ -1365,11 +1365,11 @@
 
     TestCompletionCallback callback;
     ClientSocketHandle handle;
-    int rv = handle.Init(
-        group_id_, params_, absl::nullopt /* proxy_annotation_tag */, LOW,
-        SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
-        callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(),
-        NetLogWithSource());
+    int rv =
+        handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
+                    LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
+                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
+                    pool_.get(), NetLogWithSource());
     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
     EXPECT_FALSE(handle.is_initialized());
     EXPECT_FALSE(handle.socket());
@@ -1417,7 +1417,7 @@
   TestCompletionCallback callback;
   ClientSocketHandle handle;
   int rv =
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource());
@@ -1470,7 +1470,7 @@
   TestCompletionCallback callback;
   ClientSocketHandle handle;
   int rv =
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource());
@@ -2207,7 +2207,7 @@
 
   TestCompletionCallback callback1;
   int rv1 =
-      handle.Init(group_id1, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id1, params_, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource());
@@ -2237,7 +2237,7 @@
 
   TestCompletionCallback callback2;
   int rv2 =
-      handle.Init(group_id2, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id2, params_, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_.get(), NetLogWithSource());
@@ -2287,7 +2287,7 @@
       ClientSocketPool::SocketParams::CreateForHttpForTesting();
   TestCompletionCallback callback;
   int rv =
-      handle.Init(kGroupId, params, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(kGroupId, params, std::nullopt /* proxy_annotation_tag */,
                   LOW, tag1, ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   pool_for_real_sockets_.get(), NetLogWithSource());
@@ -2300,7 +2300,7 @@
   StreamSocket* socket = handle.socket();
   handle.Reset();
   old_traffic = GetTaggedBytes(tag_val2);
-  rv = handle.Init(kGroupId, params, absl::nullopt /* proxy_annotation_tag */,
+  rv = handle.Init(kGroupId, params, std::nullopt /* proxy_annotation_tag */,
                    LOW, tag2, ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_for_real_sockets_.get(), NetLogWithSource());
@@ -2323,14 +2323,14 @@
   // Test connect jobs that are orphaned and then adopted, appropriately apply
   // new tag. Request socket with |tag1|.
   TestCompletionCallback callback2;
-  rv = handle.Init(kGroupId, params, absl::nullopt /* proxy_annotation_tag */,
+  rv = handle.Init(kGroupId, params, std::nullopt /* proxy_annotation_tag */,
                    LOW, tag1, ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_for_real_sockets_.get(), NetLogWithSource());
   EXPECT_TRUE(rv == OK || rv == ERR_IO_PENDING) << "Result: " << rv;
   // Abort and request socket with |tag2|.
   handle.Reset();
-  rv = handle.Init(kGroupId, params, absl::nullopt /* proxy_annotation_tag */,
+  rv = handle.Init(kGroupId, params, std::nullopt /* proxy_annotation_tag */,
                    LOW, tag2, ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_for_real_sockets_.get(), NetLogWithSource());
@@ -2349,7 +2349,7 @@
   handle.Reset();
   // Eat the left over connect job from the second request.
   // TODO(pauljensen): remove when crbug.com/800731 fixed.
-  rv = handle.Init(kGroupId, params, absl::nullopt /* proxy_annotation_tag */,
+  rv = handle.Init(kGroupId, params, std::nullopt /* proxy_annotation_tag */,
                    LOW, tag1, ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_for_real_sockets_.get(), NetLogWithSource());
@@ -2362,13 +2362,13 @@
   // first but expect its socket to get vended to the higher priority request.
   ClientSocketHandle handle_high_pri;
   TestCompletionCallback callback_high_pri;
-  rv = handle.Init(kGroupId, params, absl::nullopt /* proxy_annotation_tag */,
+  rv = handle.Init(kGroupId, params, std::nullopt /* proxy_annotation_tag */,
                    LOW, tag1, ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_for_real_sockets_.get(), NetLogWithSource());
   EXPECT_TRUE(rv == OK || rv == ERR_IO_PENDING) << "Result: " << rv;
   int rv_high_pri = handle_high_pri.Init(
-      kGroupId, params, absl::nullopt /* proxy_annotation_tag */, HIGHEST, tag2,
+      kGroupId, params, std::nullopt /* proxy_annotation_tag */, HIGHEST, tag2,
       ClientSocketPool::RespectLimits::ENABLED, callback_high_pri.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_for_real_sockets_.get(),
       NetLogWithSource());
@@ -2510,7 +2510,7 @@
   // Test socket is tagged before connected.
   uint64_t old_traffic = GetTaggedBytes(tag_val1);
   int rv = handle.Init(
-      kGroupId, socket_params, absl::nullopt /* proxy_annotation_tag */, LOW,
+      kGroupId, socket_params, std::nullopt /* proxy_annotation_tag */, LOW,
       tag1, ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_for_real_sockets_.get(),
       NetLogWithSource());
@@ -2525,7 +2525,7 @@
   old_traffic = GetTaggedBytes(tag_val2);
   TestCompletionCallback callback2;
   rv = handle.Init(kGroupId, socket_params,
-                   absl::nullopt /* proxy_annotation_tag */, LOW, tag2,
+                   std::nullopt /* proxy_annotation_tag */, LOW, tag2,
                    ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_for_real_sockets_.get(), NetLogWithSource());
@@ -2580,7 +2580,7 @@
   // new tag. Request socket with |tag1|.
   TestCompletionCallback callback;
   int rv = handle.Init(
-      kGroupId, socket_params, absl::nullopt /* proxy_annotation_tag */, LOW,
+      kGroupId, socket_params, std::nullopt /* proxy_annotation_tag */, LOW,
       tag1, ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_for_real_sockets_.get(),
       NetLogWithSource());
@@ -2589,7 +2589,7 @@
   handle.Reset();
   TestCompletionCallback callback2;
   rv = handle.Init(kGroupId, socket_params,
-                   absl::nullopt /* proxy_annotation_tag */, LOW, tag2,
+                   std::nullopt /* proxy_annotation_tag */, LOW, tag2,
                    ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_for_real_sockets_.get(), NetLogWithSource());
@@ -2646,7 +2646,7 @@
   int rv;
   for (auto& tcp_handle : tcp_handles) {
     rv = tcp_handle.Init(
-        kGroupId, socket_params, absl::nullopt /* proxy_annotation_tag */, LOW,
+        kGroupId, socket_params, std::nullopt /* proxy_annotation_tag */, LOW,
         tag1, ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
         ClientSocketPool::ProxyAuthCallback(), pool_for_real_sockets_.get(),
         NetLogWithSource());
@@ -2657,13 +2657,13 @@
   // Request two SSL sockets.
   ClientSocketHandle handle_to_be_canceled;
   rv = handle_to_be_canceled.Init(
-      kGroupId, socket_params, absl::nullopt /* proxy_annotation_tag */, LOW,
+      kGroupId, socket_params, std::nullopt /* proxy_annotation_tag */, LOW,
       tag1, ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
       ClientSocketPool::ProxyAuthCallback(), pool_for_real_sockets_.get(),
       NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
   rv = handle.Init(kGroupId, socket_params,
-                   absl::nullopt /* proxy_annotation_tag */, LOW, tag2,
+                   std::nullopt /* proxy_annotation_tag */, LOW, tag2,
                    ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    pool_for_real_sockets_.get(), NetLogWithSource());
@@ -2910,7 +2910,7 @@
               NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
               /*disable_cert_network_fetches=*/false),
           ClientSocketPool::SocketParams::CreateForHttpForTesting(),
-          /*proxy_annotation_tag=*/absl::nullopt, MEDIUM, SocketTag(),
+          /*proxy_annotation_tag=*/std::nullopt, MEDIUM, SocketTag(),
           ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
           ClientSocketPool::ProxyAuthCallback(),
           session->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
@@ -2956,7 +2956,7 @@
               kSchemeHostPort2, PrivacyMode::PRIVACY_MODE_DISABLED,
               NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
               /*disable_cert_network_fetches=*/false),
-          socket_params, /*proxy_annotation_tag=*/absl::nullopt, MEDIUM,
+          socket_params, /*proxy_annotation_tag=*/std::nullopt, MEDIUM,
           SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
           callback.callback(), ClientSocketPool::ProxyAuthCallback(),
           session->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
diff --git a/net/socket/transport_client_socket_unittest.cc b/net/socket/transport_client_socket_unittest.cc
index 9feb0dd..ed0caef 100644
--- a/net/socket/transport_client_socket_unittest.cc
+++ b/net/socket/transport_client_socket_unittest.cc
@@ -82,7 +82,7 @@
   listen_sock_ = std::make_unique<TCPServerSocket>(nullptr, NetLogSource());
   IPEndPoint local_address(IPAddress::IPv4Localhost(), 0);
   ASSERT_THAT(
-      listen_sock_->Listen(local_address, 1, /*ipv6_only=*/absl::nullopt),
+      listen_sock_->Listen(local_address, 1, /*ipv6_only=*/std::nullopt),
       IsOk());
   // Get the server's address (including the actual port number).
   ASSERT_THAT(listen_sock_->GetLocalAddress(&local_address), IsOk());
diff --git a/net/socket/transport_connect_job.cc b/net/socket/transport_connect_job.cc
index 501eaa0..648cc65 100644
--- a/net/socket/transport_connect_job.cc
+++ b/net/socket/transport_connect_job.cc
@@ -119,7 +119,7 @@
     const scoped_refptr<TransportSocketParams>& params,
     Delegate* delegate,
     const NetLogWithSource* net_log,
-    absl::optional<EndpointResultOverride> endpoint_result_override)
+    std::optional<EndpointResultOverride> endpoint_result_override)
     : ConnectJob(priority,
                  socket_tag,
                  ConnectionTimeout(),
@@ -183,7 +183,7 @@
   return resolve_error_info_;
 }
 
-absl::optional<HostResolverEndpointResult>
+std::optional<HostResolverEndpointResult>
 TransportConnectJob::GetHostResolverEndpointResult() const {
   CHECK_LT(current_endpoint_result_, endpoint_results_.size());
   return endpoint_results_[current_endpoint_result_];
diff --git a/net/socket/transport_connect_job.h b/net/socket/transport_connect_job.h
index 06000c9..7e091d3a 100644
--- a/net/socket/transport_connect_job.h
+++ b/net/socket/transport_connect_job.h
@@ -6,6 +6,7 @@
 #define NET_SOCKET_TRANSPORT_CONNECT_JOB_H_
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
@@ -25,7 +26,6 @@
 #include "net/dns/public/secure_dns_policy.h"
 #include "net/socket/connect_job.h"
 #include "net/socket/connection_attempts.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
 #include "url/scheme_host_port.h"
 
@@ -135,8 +135,8 @@
                       const scoped_refptr<TransportSocketParams>& params,
                       Delegate* delegate,
                       const NetLogWithSource* net_log,
-                      absl::optional<EndpointResultOverride>
-                          endpoint_result_override = absl::nullopt);
+                      std::optional<EndpointResultOverride>
+                          endpoint_result_override = std::nullopt);
 
   TransportConnectJob(const TransportConnectJob&) = delete;
   TransportConnectJob& operator=(const TransportConnectJob&) = delete;
@@ -148,7 +148,7 @@
   bool HasEstablishedConnection() const override;
   ConnectionAttempts GetConnectionAttempts() const override;
   ResolveErrorInfo GetResolveErrorInfo() const override;
-  absl::optional<HostResolverEndpointResult> GetHostResolverEndpointResult()
+  std::optional<HostResolverEndpointResult> GetHostResolverEndpointResult()
       const override;
 
   static base::TimeDelta ConnectionTimeout();
diff --git a/net/socket/unix_domain_server_socket_posix.cc b/net/socket/unix_domain_server_socket_posix.cc
index 10ff174b..e27a6cb 100644
--- a/net/socket/unix_domain_server_socket_posix.cc
+++ b/net/socket/unix_domain_server_socket_posix.cc
@@ -52,7 +52,7 @@
 
 int UnixDomainServerSocket::Listen(const IPEndPoint& address,
                                    int backlog,
-                                   absl::optional<bool> ipv6_only) {
+                                   std::optional<bool> ipv6_only) {
   NOTIMPLEMENTED();
   return ERR_NOT_IMPLEMENTED;
 }
diff --git a/net/socket/unix_domain_server_socket_posix.h b/net/socket/unix_domain_server_socket_posix.h
index b24e3775..2f3ef754 100644
--- a/net/socket/unix_domain_server_socket_posix.h
+++ b/net/socket/unix_domain_server_socket_posix.h
@@ -60,7 +60,7 @@
   // ServerSocket implementation.
   int Listen(const IPEndPoint& address,
              int backlog,
-             absl::optional<bool> ipv6_only) override;
+             std::optional<bool> ipv6_only) override;
   int ListenWithAddressAndPort(const std::string& address_string,
                                uint16_t port,
                                int backlog) override;
diff --git a/net/socket/unix_domain_server_socket_posix_unittest.cc b/net/socket/unix_domain_server_socket_posix_unittest.cc
index 4e27407..0b631364 100644
--- a/net/socket/unix_domain_server_socket_posix_unittest.cc
+++ b/net/socket/unix_domain_server_socket_posix_unittest.cc
@@ -135,7 +135,7 @@
                                        kUseAbstractNamespace);
 
   IPEndPoint ep;
-  EXPECT_THAT(server_socket.Listen(ep, 0, /*ipv6_only=*/absl::nullopt),
+  EXPECT_THAT(server_socket.Listen(ep, 0, /*ipv6_only=*/std::nullopt),
               IsError(ERR_NOT_IMPLEMENTED));
   EXPECT_EQ(ERR_NOT_IMPLEMENTED,
       server_socket.ListenWithAddressAndPort(kInvalidSocketPath,
diff --git a/net/socket/websocket_transport_client_socket_pool.cc b/net/socket/websocket_transport_client_socket_pool.cc
index 56fbcad..0d233e7 100644
--- a/net/socket/websocket_transport_client_socket_pool.cc
+++ b/net/socket/websocket_transport_client_socket_pool.cc
@@ -64,7 +64,7 @@
 int WebSocketTransportClientSocketPool::RequestSocket(
     const GroupId& group_id,
     scoped_refptr<SocketParams> params,
-    const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+    const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
     RequestPriority priority,
     const SocketTag& socket_tag,
     RespectLimits respect_limits,
@@ -129,7 +129,7 @@
 int WebSocketTransportClientSocketPool::RequestSockets(
     const GroupId& group_id,
     scoped_refptr<SocketParams> params,
-    const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+    const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
     int num_sockets,
     CompletionOnceCallback callback,
     const NetLogWithSource& net_log) {
@@ -506,7 +506,7 @@
 WebSocketTransportClientSocketPool::StalledRequest::StalledRequest(
     const GroupId& group_id,
     const scoped_refptr<SocketParams>& params,
-    const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+    const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
     RequestPriority priority,
     ClientSocketHandle* handle,
     CompletionOnceCallback callback,
diff --git a/net/socket/websocket_transport_client_socket_pool.h b/net/socket/websocket_transport_client_socket_pool.h
index c32983e..8c8bb17 100644
--- a/net/socket/websocket_transport_client_socket_pool.h
+++ b/net/socket/websocket_transport_client_socket_pool.h
@@ -8,6 +8,7 @@
 #include <list>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
@@ -22,7 +23,6 @@
 #include "net/socket/client_socket_pool.h"
 #include "net/socket/connect_job.h"
 #include "net/socket/ssl_client_socket.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -65,7 +65,7 @@
   int RequestSocket(
       const GroupId& group_id,
       scoped_refptr<SocketParams> params,
-      const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+      const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
       RequestPriority priority,
       const SocketTag& socket_tag,
       RespectLimits respect_limits,
@@ -76,7 +76,7 @@
   int RequestSockets(
       const GroupId& group_id,
       scoped_refptr<SocketParams> params,
-      const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+      const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
       int num_sockets,
       CompletionOnceCallback callback,
       const NetLogWithSource& net_log) override;
@@ -152,7 +152,7 @@
     StalledRequest(
         const GroupId& group_id,
         const scoped_refptr<SocketParams>& params,
-        const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
+        const std::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
         RequestPriority priority,
         ClientSocketHandle* handle,
         CompletionOnceCallback callback,
@@ -163,7 +163,7 @@
 
     const GroupId group_id;
     const scoped_refptr<SocketParams> params;
-    const absl::optional<NetworkTrafficAnnotationTag> proxy_annotation_tag;
+    const std::optional<NetworkTrafficAnnotationTag> proxy_annotation_tag;
     const RequestPriority priority;
     const raw_ptr<ClientSocketHandle> handle;
     CompletionOnceCallback callback;
diff --git a/net/socket/websocket_transport_client_socket_pool_unittest.cc b/net/socket/websocket_transport_client_socket_pool_unittest.cc
index 87bdf1d..560903e 100644
--- a/net/socket/websocket_transport_client_socket_pool_unittest.cc
+++ b/net/socket/websocket_transport_client_socket_pool_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -45,7 +46,6 @@
 #include "net/test/test_with_task_environment.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/scheme_host_port.h"
 #include "url/url_constants.h"
@@ -173,7 +173,7 @@
   TestCompletionCallback callback;
   ClientSocketHandle handle;
   int rv =
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   &pool_, NetLogWithSource());
@@ -196,9 +196,9 @@
     ClientSocketHandle handle;
     EXPECT_EQ(
         ERR_IO_PENDING,
-        handle.Init(group_id_, params_,
-                    absl::nullopt /* proxy_annotation_tag */, priority,
-                    SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
+        handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
+                    priority, SocketTag(),
+                    ClientSocketPool::RespectLimits::ENABLED,
                     callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                     &pool_, NetLogWithSource()));
     EXPECT_EQ(priority, host_resolver_->last_request_priority());
@@ -217,7 +217,7 @@
                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
                       /*disable_cert_network_fetches=*/false),
                   ClientSocketPool::SocketParams::CreateForHttpForTesting(),
-                  absl::nullopt /* proxy_annotation_tag */, kDefaultPriority,
+                  std::nullopt /* proxy_annotation_tag */, kDefaultPriority,
                   SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   &pool_, NetLogWithSource()));
@@ -235,7 +235,7 @@
   ClientSocketHandle handle;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   kDefaultPriority, SocketTag(),
                   ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
                   ClientSocketPool::ProxyAuthCallback(), &pool_,
@@ -250,7 +250,7 @@
   host_resolver_->set_synchronous_mode(true);
   EXPECT_EQ(
       ERR_CONNECTION_FAILED,
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   kDefaultPriority, SocketTag(),
                   ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
                   ClientSocketPool::ProxyAuthCallback(), &pool_,
@@ -334,7 +334,7 @@
   ClientSocketHandle handle;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   kDefaultPriority, SocketTag(),
                   ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
                   ClientSocketPool::ProxyAuthCallback(), &pool_,
@@ -350,14 +350,14 @@
 
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   kDefaultPriority, SocketTag(),
                   ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
                   ClientSocketPool::ProxyAuthCallback(), &pool_,
                   NetLogWithSource()));
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle2.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle2.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                    kDefaultPriority, SocketTag(),
                    ClientSocketPool::RespectLimits::ENABLED,
                    callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
@@ -376,7 +376,7 @@
   TestCompletionCallback callback;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   kDefaultPriority, SocketTag(),
                   ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
                   ClientSocketPool::ProxyAuthCallback(), &pool_,
@@ -387,7 +387,7 @@
   TestCompletionCallback callback2;
   EXPECT_EQ(
       ERR_IO_PENDING,
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   kDefaultPriority, SocketTag(),
                   ClientSocketPool::RespectLimits::ENABLED,
                   callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
@@ -463,7 +463,7 @@
 
   int rv = handle->Init(
       group_id, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
-      absl::nullopt /* proxy_annotation_tag */, LOWEST, SocketTag(),
+      std::nullopt /* proxy_annotation_tag */, LOWEST, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED, nested_callback->callback(),
       ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
@@ -480,7 +480,7 @@
   TestCompletionCallback second_result_callback;
   int rv = handle.Init(
       group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
-      absl::nullopt /* proxy_annotation_tag */, LOWEST, SocketTag(),
+      std::nullopt /* proxy_annotation_tag */, LOWEST, SocketTag(),
       ClientSocketPool::RespectLimits::ENABLED,
       base::BindOnce(&RequestSocketOnComplete, group_id_, &handle, &pool_,
                      &second_result_callback),
@@ -559,7 +559,7 @@
   TestCompletionCallback callback;
   auto handle = std::make_unique<ClientSocketHandle>();
   int rv =
-      handle->Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle->Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                    LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                    callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                    &pool_, NetLogWithSource());
@@ -628,7 +628,7 @@
   TestCompletionCallback callback;
   ClientSocketHandle handle;
   int rv =
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   &pool_, NetLogWithSource());
@@ -669,7 +669,7 @@
   TestCompletionCallback callback;
   ClientSocketHandle handle;
   int rv =
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   &pool_, NetLogWithSource());
@@ -698,7 +698,7 @@
   TestCompletionCallback callback;
   ClientSocketHandle handle;
   int rv =
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   &pool_, NetLogWithSource());
@@ -725,7 +725,7 @@
   TestCompletionCallback callback;
   ClientSocketHandle handle;
   int rv =
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   &pool_, NetLogWithSource());
@@ -765,7 +765,7 @@
   TestCompletionCallback callback;
   ClientSocketHandle handle;
   int rv =
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   &pool_, NetLogWithSource());
@@ -800,7 +800,7 @@
   TestCompletionCallback callback;
   ClientSocketHandle handle;
   int rv =
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   &pool_, NetLogWithSource());
@@ -832,7 +832,7 @@
   TestCompletionCallback callback;
   ClientSocketHandle handle;
   int rv =
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   &pool_, NetLogWithSource());
@@ -880,7 +880,7 @@
   ClientSocketHandle handle;
   base::TimeTicks start(base::TimeTicks::Now());
   int rv =
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   &pool_, NetLogWithSource());
@@ -928,7 +928,7 @@
   TestCompletionCallback callback;
   ClientSocketHandle handle;
   int rv =
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   &pool_, NetLogWithSource());
@@ -959,7 +959,7 @@
   TestCompletionCallback callback;
   ClientSocketHandle handle;
   int rv =
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   &pool_, NetLogWithSource());
@@ -994,7 +994,7 @@
   ClientSocketHandle handle;
 
   int rv =
-      handle.Init(group_id_, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
                   LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), ClientSocketPool::ProxyAuthCallback(),
                   &pool_, NetLogWithSource());
@@ -1274,7 +1274,7 @@
       PrivacyMode::PRIVACY_MODE_DISABLED, kNetworkAnonymizationKey,
       SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false);
   EXPECT_THAT(
-      handle.Init(group_id, params_, absl::nullopt /* proxy_annotation_tag */,
+      handle.Init(group_id, params_, std::nullopt /* proxy_annotation_tag */,
                   kDefaultPriority, SocketTag(),
                   ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
                   ClientSocketPool::ProxyAuthCallback(), &pool_,
diff --git a/net/spdy/bidirectional_stream_spdy_impl.cc b/net/spdy/bidirectional_stream_spdy_impl.cc
index e2f58b8..243f6a5 100644
--- a/net/spdy/bidirectional_stream_spdy_impl.cc
+++ b/net/spdy/bidirectional_stream_spdy_impl.cc
@@ -291,7 +291,7 @@
   http_request_info.method = request_info_->method;
   http_request_info.extra_headers = request_info_->extra_headers;
 
-  CreateSpdyHeadersFromHttpRequest(http_request_info, absl::nullopt,
+  CreateSpdyHeadersFromHttpRequest(http_request_info, std::nullopt,
                                    http_request_info.extra_headers, &headers);
   written_end_of_stream_ = request_info_->end_stream_on_headers;
   return stream_->SendRequestHeaders(std::move(headers),
diff --git a/net/spdy/spdy_http_utils.cc b/net/spdy/spdy_http_utils.cc
index bbe56302..7d19bef 100644
--- a/net/spdy/spdy_http_utils.cc
+++ b/net/spdy/spdy_http_utils.cc
@@ -161,7 +161,7 @@
     //    Set-Cookie: bar\0
     size_t start = 0;
     size_t end = 0;
-    absl::optional<base::StringPiece> location_value;
+    std::optional<base::StringPiece> location_value;
     do {
       end = value.find('\0', start);
       base::StringPiece tval;
@@ -194,7 +194,7 @@
 }
 
 void CreateSpdyHeadersFromHttpRequest(const HttpRequestInfo& info,
-                                      absl::optional<RequestPriority> priority,
+                                      std::optional<RequestPriority> priority,
                                       const HttpRequestHeaders& request_headers,
                                       spdy::Http2HeaderBlock* headers) {
   headers->insert({spdy::kHttp2MethodHeader, info.method});
diff --git a/net/spdy/spdy_http_utils.h b/net/spdy/spdy_http_utils.h
index 743740e5..4702f45 100644
--- a/net/spdy/spdy_http_utils.h
+++ b/net/spdy/spdy_http_utils.h
@@ -5,6 +5,8 @@
 #ifndef NET_SPDY_SPDY_HTTP_UTILS_H_
 #define NET_SPDY_SPDY_HTTP_UTILS_H_
 
+#include <optional>
+
 #include "base/memory/ref_counted.h"
 #include "base/types/expected.h"
 #include "net/base/net_export.h"
@@ -12,7 +14,6 @@
 #include "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.h"
 #include "net/third_party/quiche/src/quiche/spdy/core/spdy_framer.h"
 #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace net {
@@ -57,7 +58,7 @@
 // HttpRequestHeaders.
 NET_EXPORT void CreateSpdyHeadersFromHttpRequest(
     const HttpRequestInfo& info,
-    absl::optional<RequestPriority> priority,
+    std::optional<RequestPriority> priority,
     const HttpRequestHeaders& request_headers,
     spdy::Http2HeaderBlock* headers);
 
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc
index 5d8aa92..998bd3b 100644
--- a/net/spdy/spdy_network_transaction_unittest.cc
+++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -2388,8 +2388,8 @@
 
   EXPECT_EQ(1, delegate.received_redirect_count());
 
-  request->FollowDeferredRedirect(absl::nullopt /* removed_headers */,
-                                  absl::nullopt /* modified_headers */);
+  request->FollowDeferredRedirect(std::nullopt /* removed_headers */,
+                                  std::nullopt /* modified_headers */);
   delegate.RunUntilComplete();
 
   EXPECT_EQ(1, delegate.response_started_count());
@@ -3518,7 +3518,7 @@
                                    NetLogEventPhase::NONE);
   ASSERT_TRUE(entries[pos].HasParams());
   // END_STREAM is not set on the HEADERS frame, so `fin` is false.
-  absl::optional<bool> fin = entries[pos].params.FindBool("fin");
+  std::optional<bool> fin = entries[pos].params.FindBool("fin");
   ASSERT_TRUE(fin.has_value());
   EXPECT_FALSE(*fin);
 
@@ -3527,7 +3527,7 @@
                                    NetLogEventType::HTTP2_SESSION_RECV_DATA,
                                    NetLogEventPhase::NONE);
   ASSERT_TRUE(entries[pos].HasParams());
-  absl::optional<int> size = entries[pos].params.FindInt("size");
+  std::optional<int> size = entries[pos].params.FindInt("size");
   ASSERT_TRUE(size.has_value());
   EXPECT_EQ(static_cast<int>(strlen("hello!")), *size);
   // END_STREAM is set on the DATA frame, so `fin` is true.
@@ -3567,7 +3567,7 @@
       NetLogEventPhase::NONE);
   ASSERT_TRUE(entries[pos].HasParams());
   // END_STREAM is set on the HEADERS frame, so `fin` is true.
-  absl::optional<bool> fin = entries[pos].params.FindBool("fin");
+  std::optional<bool> fin = entries[pos].params.FindBool("fin");
   ASSERT_TRUE(fin.has_value());
   EXPECT_TRUE(*fin);
 
@@ -5233,7 +5233,7 @@
   ASSERT_TRUE(response_start->headers);
   EXPECT_EQ(401, response_start->headers->response_code());
   EXPECT_TRUE(response_start->was_fetched_via_spdy);
-  const absl::optional<AuthChallengeInfo>& auth_challenge =
+  const std::optional<AuthChallengeInfo>& auth_challenge =
       response_start->auth_challenge;
   ASSERT_TRUE(auth_challenge);
   EXPECT_FALSE(auth_challenge->is_proxy);
@@ -8553,7 +8553,7 @@
   const uint8_t flags = 0xcc;
   const std::string payload("foo");
   session_deps->greased_http2_frame =
-      absl::optional<net::SpdySessionPool::GreasedHttp2Frame>(
+      std::optional<net::SpdySessionPool::GreasedHttp2Frame>(
           {type, flags, payload});
   session_deps->http2_end_stream_with_data_frame = false;
 
@@ -8596,7 +8596,7 @@
   const uint8_t flags = 0xcc;
   const std::string payload("foo");
   session_deps->greased_http2_frame =
-      absl::optional<net::SpdySessionPool::GreasedHttp2Frame>(
+      std::optional<net::SpdySessionPool::GreasedHttp2Frame>(
           {type, flags, payload});
   session_deps->http2_end_stream_with_data_frame = true;
 
@@ -8658,7 +8658,7 @@
   const uint8_t flags = 0xcc;
   const std::string payload("foo");
   session_deps->greased_http2_frame =
-      absl::optional<net::SpdySessionPool::GreasedHttp2Frame>(
+      std::optional<net::SpdySessionPool::GreasedHttp2Frame>(
           {type, flags, payload});
   session_deps->http2_end_stream_with_data_frame = true;
 
@@ -8718,7 +8718,7 @@
   const uint8_t flags = 0xcc;
   const std::string payload("foo");
   session_deps->greased_http2_frame =
-      absl::optional<net::SpdySessionPool::GreasedHttp2Frame>(
+      std::optional<net::SpdySessionPool::GreasedHttp2Frame>(
           {type, flags, payload});
   session_deps->http2_end_stream_with_data_frame = true;
 
@@ -8779,7 +8779,7 @@
   const uint8_t flags = 0xcc;
   const std::string payload("foo");
   session_deps->greased_http2_frame =
-      absl::optional<net::SpdySessionPool::GreasedHttp2Frame>(
+      std::optional<net::SpdySessionPool::GreasedHttp2Frame>(
           {type, flags, payload});
   session_deps->http2_end_stream_with_data_frame = true;
 
@@ -8860,7 +8860,7 @@
   const uint8_t flags = 0xcc;
   const std::string payload("foo");
   session_deps->greased_http2_frame =
-      absl::optional<net::SpdySessionPool::GreasedHttp2Frame>(
+      std::optional<net::SpdySessionPool::GreasedHttp2Frame>(
           {type, flags, payload});
   session_deps->http2_end_stream_with_data_frame = true;
 
diff --git a/net/spdy/spdy_proxy_client_socket.cc b/net/spdy/spdy_proxy_client_socket.cc
index a2f8ccd..09769af 100644
--- a/net/spdy/spdy_proxy_client_socket.cc
+++ b/net/spdy/spdy_proxy_client_socket.cc
@@ -386,7 +386,7 @@
                        request_line, &request_.extra_headers);
 
   spdy::Http2HeaderBlock headers;
-  CreateSpdyHeadersFromHttpRequest(request_, absl::nullopt,
+  CreateSpdyHeadersFromHttpRequest(request_, std::nullopt,
                                    request_.extra_headers, &headers);
 
   return spdy_stream_->SendRequestHeaders(std::move(headers),
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index c8b3691..6092564 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -786,7 +786,7 @@
     int session_max_queued_capped_frames,
     const spdy::SettingsMap& initial_settings,
     bool enable_http2_settings_grease,
-    const absl::optional<SpdySessionPool::GreasedHttp2Frame>&
+    const std::optional<SpdySessionPool::GreasedHttp2Frame>&
         greased_http2_frame,
     bool http2_end_stream_with_data_frame,
     bool enable_priority_update,
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h
index 0637fd9..b350117 100644
--- a/net/spdy/spdy_session.h
+++ b/net/spdy/spdy_session.h
@@ -10,6 +10,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
@@ -53,7 +54,6 @@
 #include "net/third_party/quiche/src/quiche/spdy/core/spdy_framer.h"
 #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 #include "url/scheme_host_port.h"
@@ -338,7 +338,7 @@
               int session_max_queued_capped_frames,
               const spdy::SettingsMap& initial_settings,
               bool enable_http2_settings_grease,
-              const absl::optional<SpdySessionPool::GreasedHttp2Frame>&
+              const std::optional<SpdySessionPool::GreasedHttp2Frame>&
                   greased_http2_frame,
               bool http2_end_stream_with_data_frame,
               bool enable_priority_update,
@@ -1109,7 +1109,7 @@
   // If set, an HTTP/2 frame with a reserved frame type will be sent after
   // every HTTP/2 SETTINGS frame and before every HTTP/2 DATA frame. See
   // https://tools.ietf.org/html/draft-bishop-httpbis-grease-00.
-  const absl::optional<SpdySessionPool::GreasedHttp2Frame> greased_http2_frame_;
+  const std::optional<SpdySessionPool::GreasedHttp2Frame> greased_http2_frame_;
 
   // If set, the HEADERS frame carrying a request without body will not have the
   // END_STREAM flag set.  The stream will be closed by a subsequent empty DATA
diff --git a/net/spdy/spdy_session_key.cc b/net/spdy/spdy_session_key.cc
index 3caed08..b5e205d 100644
--- a/net/spdy/spdy_session_key.cc
+++ b/net/spdy/spdy_session_key.cc
@@ -4,6 +4,7 @@
 
 #include "net/spdy/spdy_session_key.h"
 
+#include <optional>
 #include <tuple>
 
 #include "base/feature_list.h"
@@ -15,7 +16,6 @@
 #include "net/base/proxy_string_util.h"
 #include "net/base/session_usage.h"
 #include "net/dns/public/secure_dns_policy.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
diff --git a/net/spdy/spdy_session_key.h b/net/spdy/spdy_session_key.h
index 1ff2c2a..b66cf40 100644
--- a/net/spdy/spdy_session_key.h
+++ b/net/spdy/spdy_session_key.h
@@ -5,6 +5,8 @@
 #ifndef NET_SPDY_SPDY_SESSION_KEY_H_
 #define NET_SPDY_SPDY_SESSION_KEY_H_
 
+#include <optional>
+
 #include "net/base/net_export.h"
 #include "net/base/network_anonymization_key.h"
 #include "net/base/network_isolation_key.h"
@@ -13,7 +15,6 @@
 #include "net/base/session_usage.h"
 #include "net/dns/public/secure_dns_policy.h"
 #include "net/socket/socket_tag.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 namespace net {
 
 // SpdySessionKey is used as unique index for SpdySessionPool.
diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc
index af61f7f..89cec77 100644
--- a/net/spdy/spdy_session_pool.cc
+++ b/net/spdy/spdy_session_pool.cc
@@ -85,7 +85,7 @@
     int session_max_queued_capped_frames,
     const spdy::SettingsMap& initial_settings,
     bool enable_http2_settings_grease,
-    const absl::optional<GreasedHttp2Frame>& greased_http2_frame,
+    const std::optional<GreasedHttp2Frame>& greased_http2_frame,
     bool http2_end_stream_with_data_frame,
     bool enable_priority_update,
     bool go_away_on_ip_change,
diff --git a/net/spdy/spdy_session_pool.h b/net/spdy/spdy_session_pool.h
index 546109c1..3e98247 100644
--- a/net/spdy/spdy_session_pool.h
+++ b/net/spdy/spdy_session_pool.h
@@ -10,6 +10,7 @@
 #include <list>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
@@ -32,7 +33,6 @@
 #include "net/ssl/ssl_config_service.h"
 #include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
 #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -138,7 +138,7 @@
                   int session_max_queued_capped_frames,
                   const spdy::SettingsMap& initial_settings,
                   bool enable_http2_settings_grease,
-                  const absl::optional<GreasedHttp2Frame>& greased_http2_frame,
+                  const std::optional<GreasedHttp2Frame>& greased_http2_frame,
                   bool http2_end_stream_with_data_frame,
                   bool enable_priority_update,
                   bool go_away_on_ip_change,
@@ -464,7 +464,7 @@
   // If set, an HTTP/2 frame with a reserved frame type will be sent after
   // every HTTP/2 SETTINGS frame and before every HTTP/2 DATA frame. See
   // https://tools.ietf.org/html/draft-bishop-httpbis-grease-00.
-  const absl::optional<GreasedHttp2Frame> greased_http2_frame_;
+  const std::optional<GreasedHttp2Frame> greased_http2_frame_;
 
   // If set, the HEADERS frame carrying a request without body will not have the
   // END_STREAM flag set.  The stream will be closed by a subsequent empty DATA
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc
index c2f7234f..dfc1d02 100644
--- a/net/spdy/spdy_session_unittest.cc
+++ b/net/spdy/spdy_session_unittest.cc
@@ -5,6 +5,7 @@
 #include "net/spdy/spdy_session.h"
 
 #include <algorithm>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <utility>
@@ -67,7 +68,6 @@
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/platform_test.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/scheme_host_port.h"
 #include "url/url_constants.h"
@@ -1930,7 +1930,7 @@
     *source = NetLogSource();
     return false;
   }
-  absl::optional<int> opt_int;
+  std::optional<int> opt_int;
   opt_int = source_dict->FindInt("id");
   if (!opt_int) {
     *source = NetLogSource();
@@ -3355,7 +3355,7 @@
               PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
               SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
           ClientSocketPool::SocketParams::CreateForHttpForTesting(),
-          absl::nullopt /* proxy_annotation_tag */, DEFAULT_PRIORITY,
+          std::nullopt /* proxy_annotation_tag */, DEFAULT_PRIORITY,
           SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
           callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool,
           NetLogWithSource()));
@@ -3447,7 +3447,7 @@
               PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
               SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
           ClientSocketPool::SocketParams::CreateForHttpForTesting(),
-          absl::nullopt /* proxy_annotation_tag */, DEFAULT_PRIORITY,
+          std::nullopt /* proxy_annotation_tag */, DEFAULT_PRIORITY,
           SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
           callback3.callback(), ClientSocketPool::ProxyAuthCallback(), pool,
           NetLogWithSource()));
@@ -3528,7 +3528,7 @@
               PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
               SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
           ClientSocketPool::SocketParams::CreateForHttpForTesting(),
-          absl::nullopt /* proxy_annotation_tag */, DEFAULT_PRIORITY,
+          std::nullopt /* proxy_annotation_tag */, DEFAULT_PRIORITY,
           SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
           callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool,
           NetLogWithSource()));
@@ -5414,7 +5414,7 @@
   const uint8_t flags = 0xcc;
   const std::string payload("foo");
   session_deps_.greased_http2_frame =
-      absl::optional<net::SpdySessionPool::GreasedHttp2Frame>(
+      std::optional<net::SpdySessionPool::GreasedHttp2Frame>(
           {type, flags, payload});
 
   // Connection preface.
diff --git a/net/spdy/spdy_test_util_common.cc b/net/spdy/spdy_test_util_common.cc
index 8eac1fd..6c04ee4 100644
--- a/net/spdy/spdy_test_util_common.cc
+++ b/net/spdy/spdy_test_util_common.cc
@@ -5,6 +5,7 @@
 #include "net/spdy/spdy_test_util_common.h"
 
 #include <cstddef>
+#include <optional>
 #include <utility>
 
 #include "base/base64.h"
@@ -52,7 +53,6 @@
 #include "net/url_request/url_request_job_factory.h"
 #include "net/url_request/url_request_test_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/scheme_host_port.h"
 #include "url/url_constants.h"
 
@@ -451,7 +451,7 @@
                               key.host_port_pair().port()),
           key.privacy_mode(), NetworkAnonymizationKey(),
           SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
-      socket_params, /*proxy_annotation_tag=*/absl::nullopt, MEDIUM,
+      socket_params, /*proxy_annotation_tag=*/std::nullopt, MEDIUM,
       key.socket_tag(), ClientSocketPool::RespectLimits::ENABLED,
       callback.callback(), ClientSocketPool::ProxyAuthCallback(),
       http_session->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
@@ -739,7 +739,7 @@
     spdy::SpdyStreamId stream_id,
     RequestPriority request_priority,
     bool priority_incremental,
-    absl::optional<RequestPriority> header_request_priority) {
+    std::optional<RequestPriority> header_request_priority) {
   spdy::Http2HeaderBlock block(ConstructGetHeaderBlock(url));
   return ConstructSpdyHeaders(stream_id, std::move(block), request_priority,
                               true, priority_incremental,
@@ -752,7 +752,7 @@
     int stream_id,
     RequestPriority request_priority,
     bool priority_incremental,
-    absl::optional<RequestPriority> header_request_priority) {
+    std::optional<RequestPriority> header_request_priority) {
   spdy::Http2HeaderBlock block;
   block[spdy::kHttp2MethodHeader] = "GET";
   AddUrlToHeaderBlock(default_url_.spec(), &block);
@@ -801,7 +801,7 @@
     RequestPriority priority,
     bool fin,
     bool priority_incremental,
-    absl::optional<RequestPriority> header_request_priority) {
+    std::optional<RequestPriority> header_request_priority) {
   // Get the stream id of the next highest priority request
   // (most recent request of the same priority, or last request of
   // an earlier priority).
diff --git a/net/spdy/spdy_test_util_common.h b/net/spdy/spdy_test_util_common.h
index 80f1e271..1c8db60 100644
--- a/net/spdy/spdy_test_util_common.h
+++ b/net/spdy/spdy_test_util_common.h
@@ -206,7 +206,7 @@
   SpdySession::TimeFunc time_func;
   bool enable_http2_alternative_service = false;
   bool enable_http2_settings_grease = false;
-  absl::optional<SpdySessionPool::GreasedHttp2Frame> greased_http2_frame;
+  std::optional<SpdySessionPool::GreasedHttp2Frame> greased_http2_frame;
   bool http2_end_stream_with_data_frame = false;
   raw_ptr<NetLog> net_log = nullptr;
   bool disable_idle_sockets_close_on_memory_pressure = false;
@@ -344,7 +344,7 @@
       spdy::SpdyStreamId stream_id,
       RequestPriority request_priority,
       bool priority_incremental = kDefaultPriorityIncremental,
-      absl::optional<RequestPriority> header_request_priority = absl::nullopt);
+      std::optional<RequestPriority> header_request_priority = std::nullopt);
 
   // Constructs a standard SPDY GET HEADERS frame with header compression.
   // |extra_headers| are the extra header-value pairs, which typically
@@ -356,7 +356,7 @@
       int stream_id,
       RequestPriority request_priority,
       bool priority_incremental = kDefaultPriorityIncremental,
-      absl::optional<RequestPriority> header_request_priority = absl::nullopt);
+      std::optional<RequestPriority> header_request_priority = std::nullopt);
 
   // Constructs a SPDY HEADERS frame for a CONNECT request.
   spdy::SpdySerializedFrame ConstructSpdyConnect(
@@ -386,7 +386,7 @@
       RequestPriority priority,
       bool fin,
       bool priority_incremental = kDefaultPriorityIncremental,
-      absl::optional<RequestPriority> header_request_priority = absl::nullopt);
+      std::optional<RequestPriority> header_request_priority = std::nullopt);
 
   // Construct a reply HEADERS frame carrying exactly the given headers and the
   // default priority.
diff --git a/net/ssl/ssl_client_session_cache.h b/net/ssl/ssl_client_session_cache.h
index 0ff0054..f8444ac 100644
--- a/net/ssl/ssl_client_session_cache.h
+++ b/net/ssl/ssl_client_session_cache.h
@@ -9,6 +9,7 @@
 #include <time.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "base/containers/flat_set.h"
@@ -21,7 +22,6 @@
 #include "net/base/net_export.h"
 #include "net/base/network_anonymization_key.h"
 #include "net/base/privacy_mode.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/include/openssl/base.h"
 
 namespace base {
@@ -51,7 +51,7 @@
     bool operator<(const Key& other) const;
 
     HostPortPair server;
-    absl::optional<IPAddress> dest_ip_addr;
+    std::optional<IPAddress> dest_ip_addr;
     NetworkAnonymizationKey network_anonymization_key;
     PrivacyMode privacy_mode = PRIVACY_MODE_DISABLED;
     bool disable_legacy_crypto = false;
diff --git a/net/ssl/ssl_config.h b/net/ssl/ssl_config.h
index eb06bde..62563d9 100644
--- a/net/ssl/ssl_config.h
+++ b/net/ssl/ssl_config.h
@@ -7,6 +7,8 @@
 
 #include <stdint.h>
 
+#include <optional>
+
 #include "base/containers/flat_map.h"
 #include "base/memory/scoped_refptr.h"
 #include "net/base/net_export.h"
@@ -15,7 +17,6 @@
 #include "net/cert/cert_status_flags.h"
 #include "net/cert/x509_certificate.h"
 #include "net/socket/next_proto.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -53,8 +54,8 @@
   // If specified, the minimum and maximum protocol versions that are enabled.
   // (Use the SSL_PROTOCOL_VERSION_xxx enumerators defined above.) If
   // unspecified, values from the SSLConfigService are used.
-  absl::optional<uint16_t> version_min_override;
-  absl::optional<uint16_t> version_max_override;
+  std::optional<uint16_t> version_min_override;
+  std::optional<uint16_t> version_max_override;
 
   // Whether early data is enabled on this connection. Note that early data has
   // weaker security properties than normal data and changes the
diff --git a/net/ssl/ssl_config_service.h b/net/ssl/ssl_config_service.h
index 44f3709a..ea39ea6 100644
--- a/net/ssl/ssl_config_service.h
+++ b/net/ssl/ssl_config_service.h
@@ -5,12 +5,12 @@
 #ifndef NET_SSL_SSL_CONFIG_SERVICE_H_
 #define NET_SSL_SSL_CONFIG_SERVICE_H_
 
+#include <optional>
 #include <vector>
 
 #include "base/observer_list.h"
 #include "net/base/net_export.h"
 #include "net/ssl/ssl_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -48,27 +48,27 @@
   std::vector<uint16_t> disabled_cipher_suites;
 
   // If specified, controls whether post-quantum key agreement in TLS
-  // connections is allowed. If `absl::nullopt`, this is determined by feature
+  // connections is allowed. If `std::nullopt`, this is determined by feature
   // flags.
-  absl::optional<bool> post_quantum_override;
+  std::optional<bool> post_quantum_override;
 
   // Controls whether ECH is enabled.
   bool ech_enabled = true;
 
   // If specified, controls whether insecure hashes are allowed in TLS
-  // handshakes. If `absl::nullopt`, this is determined by feature flags.
-  absl::optional<bool> insecure_hash_override;
+  // handshakes. If `std::nullopt`, this is determined by feature flags.
+  std::optional<bool> insecure_hash_override;
 
   // If specified, controls whether the X.509 keyUsage extension is checked in
   // TLS 1.2 for RSA certificates that chain to a local trust anchor. If
-  // `absl::nullopt`, this is determined by feature flags.
+  // `std::nullopt`, this is determined by feature flags.
   //
   // Independent of the setting of this value, keyUsage is always checked at TLS
   // 1.3, for ECDSA certificates, and for all certificates that chain to a known
   // root.
   //
   // TODO(crbug.com/795089): Enable this unconditionally.
-  absl::optional<bool> rsa_key_usage_for_local_anchors_override;
+  std::optional<bool> rsa_key_usage_for_local_anchors_override;
 };
 
 // The interface for retrieving global SSL configuration.  This interface
diff --git a/net/ssl/ssl_platform_key_android.cc b/net/ssl/ssl_platform_key_android.cc
index 0fd42ac..cb7347d1 100644
--- a/net/ssl/ssl_platform_key_android.cc
+++ b/net/ssl/ssl_platform_key_android.cc
@@ -7,6 +7,7 @@
 #include <strings.h>
 
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -17,7 +18,6 @@
 #include "net/base/net_errors.h"
 #include "net/ssl/ssl_platform_key_util.h"
 #include "net/ssl/threaded_ssl_private_key.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/include/openssl/ecdsa.h"
 #include "third_party/boringssl/src/include/openssl/evp.h"
 #include "third_party/boringssl/src/include/openssl/mem.h"
@@ -73,7 +73,7 @@
         provider_name_(android::GetPrivateKeyClassName(key)) {
     key_.Reset(key);
 
-    absl::optional<bool> supports_rsa_no_padding;
+    std::optional<bool> supports_rsa_no_padding;
     for (uint16_t algorithm : SSLPrivateKey::DefaultAlgorithmPreferences(
              EVP_PKEY_id(pubkey_.get()), true /* include PSS */)) {
       const char* java_algorithm = GetJavaAlgorithm(algorithm);
@@ -136,7 +136,7 @@
       return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
     }
 
-    absl::optional<std::vector<uint8_t>> padded =
+    std::optional<std::vector<uint8_t>> padded =
         AddPSSPadding(pubkey_.get(), md, base::make_span(digest, digest_len));
     if (!padded) {
       return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
diff --git a/net/ssl/ssl_platform_key_mac.cc b/net/ssl/ssl_platform_key_mac.cc
index d35a1b0..3bf95ef 100644
--- a/net/ssl/ssl_platform_key_mac.cc
+++ b/net/ssl/ssl_platform_key_mac.cc
@@ -11,6 +11,7 @@
 #include <Security/SecKey.h>
 
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -29,7 +30,6 @@
 #include "net/ssl/ssl_platform_key_util.h"
 #include "net/ssl/ssl_private_key.h"
 #include "net/ssl/threaded_ssl_private_key.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/include/openssl/evp.h"
 #include "third_party/boringssl/src/include/openssl/mem.h"
 #include "third_party/boringssl/src/include/openssl/nid.h"
@@ -123,7 +123,7 @@
     }
     base::span<const uint8_t> digest = base::make_span(digest_buf, digest_len);
 
-    absl::optional<std::vector<uint8_t>> pss_storage;
+    std::optional<std::vector<uint8_t>> pss_storage;
     if (pss_fallback) {
       // Implement RSA-PSS by adding the padding manually and then using
       // kSecKeyAlgorithmRSASignatureRaw.
diff --git a/net/ssl/ssl_platform_key_util.cc b/net/ssl/ssl_platform_key_util.cc
index 7c86967..1081224 100644
--- a/net/ssl/ssl_platform_key_util.cc
+++ b/net/ssl/ssl_platform_key_util.cc
@@ -88,19 +88,19 @@
   return true;
 }
 
-absl::optional<std::vector<uint8_t>> AddPSSPadding(
+std::optional<std::vector<uint8_t>> AddPSSPadding(
     EVP_PKEY* pubkey,
     const EVP_MD* md,
     base::span<const uint8_t> digest) {
   RSA* rsa = EVP_PKEY_get0_RSA(pubkey);
   if (!rsa) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   std::vector<uint8_t> ret(RSA_size(rsa));
   if (digest.size() != EVP_MD_size(md) ||
       !RSA_padding_add_PKCS1_PSS_mgf1(rsa, ret.data(), digest.data(), md, md,
                                       -1 /* salt length is digest length */)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return ret;
 }
diff --git a/net/ssl/ssl_platform_key_util.h b/net/ssl/ssl_platform_key_util.h
index 5e26c931..2c19588 100644
--- a/net/ssl/ssl_platform_key_util.h
+++ b/net/ssl/ssl_platform_key_util.h
@@ -8,13 +8,13 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
 #include "base/containers/span.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/task/single_thread_task_runner.h"
 #include "net/base/net_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/include/openssl/base.h"
 
 namespace net {
@@ -42,7 +42,7 @@
 // Returns the encoded form of |digest| for use with RSA-PSS with |pubkey|,
 // using |md| as the hash function and MGF-1 function, and the digest size of
 // |md| as the salt length.
-absl::optional<std::vector<uint8_t>> AddPSSPadding(
+std::optional<std::vector<uint8_t>> AddPSSPadding(
     EVP_PKEY* pubkey,
     const EVP_MD* md,
     base::span<const uint8_t> digest);
diff --git a/net/ssl/ssl_server_config.h b/net/ssl/ssl_server_config.h
index a7ae034..b96fc61 100644
--- a/net/ssl/ssl_server_config.h
+++ b/net/ssl/ssl_server_config.h
@@ -7,6 +7,7 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -16,7 +17,6 @@
 #include "net/base/net_export.h"
 #include "net/socket/next_proto.h"
 #include "net/ssl/ssl_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/include/openssl/base.h"
 
 namespace net {
@@ -63,12 +63,12 @@
   // cipher_suite_for_testing, if set, causes the server to only support the
   // specified cipher suite in TLS 1.2 and below. This should only be used in
   // unit tests.
-  absl::optional<uint16_t> cipher_suite_for_testing;
+  std::optional<uint16_t> cipher_suite_for_testing;
 
   // signature_algorithm_for_testing, if set, causes the server to only support
   // the specified signature algorithm in TLS 1.2 and below. This should only be
   // used in unit tests.
-  absl::optional<uint16_t> signature_algorithm_for_testing;
+  std::optional<uint16_t> signature_algorithm_for_testing;
 
   // curves_for_testing, if not empty, specifies the list of NID values (e.g.
   // NID_X25519) to configure as supported curves for the TLS connection.
@@ -114,7 +114,7 @@
 
   // If specified, causes the specified alert to be sent immediately after the
   // handshake.
-  absl::optional<uint8_t> alert_after_handshake_for_testing;
+  std::optional<uint8_t> alert_after_handshake_for_testing;
 
   // This is a workaround for BoringSSL's scopers not being copyable. See
   // https://crbug.com/boringssl/431.
diff --git a/net/test/cert_builder.cc b/net/test/cert_builder.cc
index f6dee4e..54496709 100644
--- a/net/test/cert_builder.cc
+++ b/net/test/cert_builder.cc
@@ -6,6 +6,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -32,7 +33,6 @@
 #include "net/test/key_util.h"
 #include "net/test/test_data_directory.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/include/openssl/evp.h"
 #include "third_party/boringssl/src/include/openssl/mem.h"
 #include "third_party/boringssl/src/pki/certificate_policies.h"
@@ -260,13 +260,13 @@
 }
 
 // static
-absl::optional<bssl::SignatureAlgorithm>
+std::optional<bssl::SignatureAlgorithm>
 CertBuilder::DefaultSignatureAlgorithmForKey(EVP_PKEY* key) {
   if (EVP_PKEY_id(key) == EVP_PKEY_RSA)
     return bssl::SignatureAlgorithm::kRsaPkcs1Sha256;
   if (EVP_PKEY_id(key) == EVP_PKEY_EC)
     return bssl::SignatureAlgorithm::kEcdsaSha256;
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 // static
@@ -592,7 +592,7 @@
 
 void CertBuilder::SetIssuerTLV(base::span<const uint8_t> issuer_tlv) {
   if (issuer_tlv.empty())
-    issuer_tlv_ = absl::nullopt;
+    issuer_tlv_ = std::nullopt;
   else
     issuer_tlv_ = std::string(issuer_tlv.begin(), issuer_tlv.end());
   Invalidate();
@@ -795,8 +795,8 @@
 }
 
 void CertBuilder::SetPolicyConstraints(
-    absl::optional<uint64_t> require_explicit_policy,
-    absl::optional<uint64_t> inhibit_policy_mapping) {
+    std::optional<uint64_t> require_explicit_policy,
+    std::optional<uint64_t> inhibit_policy_mapping) {
   if (!require_explicit_policy.has_value() &&
       !inhibit_policy_mapping.has_value()) {
     EraseExtension(bssl::der::Input(bssl::kPolicyConstraintsOid));
@@ -1222,7 +1222,7 @@
       bssl::der::ContextSpecificPrimitive(2), &unused));
 
   // extensions
-  absl::optional<bssl::der::Input> extensions_tlv;
+  std::optional<bssl::der::Input> extensions_tlv;
   ASSERT_TRUE(tbs_certificate.ReadOptionalTag(
       bssl::der::ContextSpecificConstructed(3), &extensions_tlv));
   if (extensions_tlv) {
@@ -1362,7 +1362,7 @@
 void CertBuilder::GenerateCertificate() {
   ASSERT_FALSE(cert_);
 
-  absl::optional<bssl::SignatureAlgorithm> signature_algorithm =
+  std::optional<bssl::SignatureAlgorithm> signature_algorithm =
       signature_algorithm_;
   if (!signature_algorithm)
     signature_algorithm = DefaultSignatureAlgorithmForKey(issuer_->GetKey());
diff --git a/net/test/cert_builder.h b/net/test/cert_builder.h
index 594f185..1aad6e6 100644
--- a/net/test/cert_builder.h
+++ b/net/test/cert_builder.h
@@ -114,7 +114,7 @@
   static std::array<std::unique_ptr<CertBuilder>, 2> CreateSimpleChain2();
 
   // Returns a compatible signature algorithm for |key|.
-  static absl::optional<bssl::SignatureAlgorithm>
+  static std::optional<bssl::SignatureAlgorithm>
   DefaultSignatureAlgorithmForKey(EVP_PKEY* key);
 
   // Signs |tbs_data| with |key| using |signature_algorithm| appending the
@@ -231,8 +231,8 @@
   // Sets the PolicyConstraints extension. If both |require_explicit_policy|
   // and |inhibit_policy_mapping| are nullopt, the PolicyConstraints extension
   // will removed.
-  void SetPolicyConstraints(absl::optional<uint64_t> require_explicit_policy,
-                            absl::optional<uint64_t> inhibit_policy_mapping);
+  void SetPolicyConstraints(std::optional<uint64_t> require_explicit_policy,
+                            std::optional<uint64_t> inhibit_policy_mapping);
 
   // Sets the inhibitAnyPolicy extension.
   void SetInhibitAnyPolicy(uint64_t skip_certs);
@@ -418,9 +418,9 @@
 
   bssl::CertificateVersion version_ = bssl::CertificateVersion::V3;
   std::string validity_tlv_;
-  absl::optional<std::string> issuer_tlv_;
+  std::optional<std::string> issuer_tlv_;
   std::string subject_tlv_;
-  absl::optional<bssl::SignatureAlgorithm> signature_algorithm_;
+  std::optional<bssl::SignatureAlgorithm> signature_algorithm_;
   std::string outer_signature_algorithm_tlv_;
   std::string tbs_signature_algorithm_tlv_;
   uint64_t serial_number_ = 0;
diff --git a/net/test/embedded_test_server/embedded_test_server.cc b/net/test/embedded_test_server/embedded_test_server.cc
index 3167953..0f50e1f 100644
--- a/net/test/embedded_test_server/embedded_test_server.cc
+++ b/net/test/embedded_test_server/embedded_test_server.cc
@@ -7,6 +7,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "base/files/file_path.h"
@@ -52,7 +53,6 @@
 #include "net/test/revocation_builder.h"
 #include "net/test/test_data_directory.h"
 #include "net/third_party/quiche/src/quiche/spdy/core/spdy_frame_builder.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/pki/extended_key_usage.h"
 #include "url/origin.h"
 
@@ -718,7 +718,7 @@
 }
 
 url::Origin EmbeddedTestServer::GetOrigin(
-    const absl::optional<std::string>& hostname) const {
+    const std::optional<std::string>& hostname) const {
   if (hostname)
     return url::Origin::Create(GetURL(*hostname, "/"));
   return url::Origin::Create(base_url_);
diff --git a/net/test/embedded_test_server/embedded_test_server.h b/net/test/embedded_test_server/embedded_test_server.h
index da5d1ae..f73f17c 100644
--- a/net/test/embedded_test_server/embedded_test_server.h
+++ b/net/test/embedded_test_server/embedded_test_server.h
@@ -9,6 +9,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -31,7 +32,6 @@
 #include "net/ssl/ssl_server_config.h"
 #include "net/test/cert_builder.h"
 #include "net/test/embedded_test_server/http_connection.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/pki/ocsp_revocation_status.h"
 #include "third_party/boringssl/src/pki/parse_certificate.h"
 #include "url/gurl.h"
@@ -426,7 +426,7 @@
   // Will use the GetURL() variant that takes a hostname as the base URL, if
   // `hostname` is non-null.
   url::Origin GetOrigin(
-      const absl::optional<std::string>& hostname = absl::nullopt) const;
+      const std::optional<std::string>& hostname = std::nullopt) const;
 
   // Returns the address list needed to connect to the server.
   [[nodiscard]] bool GetAddressList(AddressList* address_list) const;
diff --git a/net/test/embedded_test_server/http_request.h b/net/test/embedded_test_server/http_request.h
index de14212..c35fb58 100644
--- a/net/test/embedded_test_server/http_request.h
+++ b/net/test/embedded_test_server/http_request.h
@@ -9,12 +9,12 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "net/ssl/ssl_info.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace net {
@@ -73,7 +73,7 @@
   HeaderMap headers;
   std::string content;
   bool has_content = false;
-  absl::optional<SSLInfo> ssl_info;
+  std::optional<SSLInfo> ssl_info;
 };
 
 // Parses the input data and produces a valid HttpRequest object. If there is
diff --git a/net/test/embedded_test_server/http_response.h b/net/test/embedded_test_server/http_response.h
index faa1af2..3ebfa88 100644
--- a/net/test/embedded_test_server/http_response.h
+++ b/net/test/embedded_test_server/http_response.h
@@ -5,6 +5,7 @@
 #ifndef NET_TEST_EMBEDDED_TEST_SERVER_HTTP_RESPONSE_H_
 #define NET_TEST_EMBEDDED_TEST_SERVER_HTTP_RESPONSE_H_
 
+#include <optional>
 #include <string>
 
 #include "base/compiler_specific.h"
@@ -17,7 +18,6 @@
 #include "base/strings/string_split.h"
 #include "base/time/time.h"
 #include "net/http/http_status_code.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net::test_server {
 
@@ -96,7 +96,7 @@
   std::string reason() const {
     return reason_.value_or(GetHttpReasonPhrase(code_));
   }
-  void set_reason(absl::optional<std::string> reason) {
+  void set_reason(std::optional<std::string> reason) {
     reason_ = std::move(reason);
   }
 
@@ -126,7 +126,7 @@
 
  private:
   HttpStatusCode code_ = HTTP_OK;
-  absl::optional<std::string> reason_;
+  std::optional<std::string> reason_;
   std::string content_;
   std::string content_type_;
   base::StringPairs custom_headers_;
diff --git a/net/test/revocation_builder.cc b/net/test/revocation_builder.cc
index 99d23b5..7426b1b 100644
--- a/net/test/revocation_builder.cc
+++ b/net/test/revocation_builder.cc
@@ -326,7 +326,7 @@
 std::string BuildOCSPResponseWithResponseData(
     EVP_PKEY* responder_key,
     const std::string& tbs_response_data,
-    absl::optional<bssl::SignatureAlgorithm> signature_algorithm) {
+    std::optional<bssl::SignatureAlgorithm> signature_algorithm) {
   //    For a basic OCSP responder, responseType will be id-pkix-ocsp-basic.
   //
   //    id-pkix-ocsp           OBJECT IDENTIFIER ::= { id-ad-ocsp }
@@ -468,7 +468,7 @@
     const std::string& crl_issuer_subject,
     EVP_PKEY* crl_issuer_key,
     const std::vector<uint64_t>& revoked_serials,
-    absl::optional<bssl::SignatureAlgorithm> signature_algorithm) {
+    std::optional<bssl::SignatureAlgorithm> signature_algorithm) {
   if (!signature_algorithm) {
     signature_algorithm =
         CertBuilder::DefaultSignatureAlgorithmForKey(crl_issuer_key);
diff --git a/net/test/revocation_builder.h b/net/test/revocation_builder.h
index 28bfc15f..f4a6a8b 100644
--- a/net/test/revocation_builder.h
+++ b/net/test/revocation_builder.h
@@ -5,11 +5,11 @@
 #ifndef NET_TEST_REVOCATION_BUILDER_H_
 #define NET_TEST_REVOCATION_BUILDER_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "base/time/time.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/include/openssl/evp.h"
 #include "third_party/boringssl/src/pki/ocsp.h"
 #include "third_party/boringssl/src/pki/ocsp_revocation_status.h"
@@ -54,18 +54,17 @@
 std::string BuildOCSPResponseWithResponseData(
     EVP_PKEY* responder_key,
     const std::string& response_data,
-    absl::optional<bssl::SignatureAlgorithm> signature_algorithm =
-        absl::nullopt);
+    std::optional<bssl::SignatureAlgorithm> signature_algorithm = std::nullopt);
 
 // Creates a CRL issued by |crl_issuer_subject| and signed by |crl_issuer_key|,
 // marking |revoked_serials| as revoked. If |signature_algorithm| is nullopt, a
 // default algorithm will be chosen based on the key type.
 // Returns the DER-encoded CRL.
-std::string BuildCrl(const std::string& crl_issuer_subject,
-                     EVP_PKEY* crl_issuer_key,
-                     const std::vector<uint64_t>& revoked_serials,
-                     absl::optional<bssl::SignatureAlgorithm>
-                         signature_algorithm = absl::nullopt);
+std::string BuildCrl(
+    const std::string& crl_issuer_subject,
+    EVP_PKEY* crl_issuer_key,
+    const std::vector<uint64_t>& revoked_serials,
+    std::optional<bssl::SignatureAlgorithm> signature_algorithm = std::nullopt);
 
 std::string BuildCrlWithAlgorithmTlvAndDigest(
     const std::string& crl_issuer_subject,
diff --git a/net/test/spawned_test_server/base_test_server.cc b/net/test/spawned_test_server/base_test_server.cc
index 3c0937204..878f161 100644
--- a/net/test/spawned_test_server/base_test_server.cc
+++ b/net/test/spawned_test_server/base_test_server.cc
@@ -284,7 +284,7 @@
     return false;
   }
 
-  absl::optional<int> port_value = parsed_json->GetDict().FindInt("port");
+  std::optional<int> port_value = parsed_json->GetDict().FindInt("port");
   if (!port_value) {
     LOG(ERROR) << "Could not find port value";
     return false;
@@ -320,7 +320,7 @@
   started_ = false;
 }
 
-absl::optional<base::Value::Dict> BaseTestServer::GenerateArguments() const {
+std::optional<base::Value::Dict> BaseTestServer::GenerateArguments() const {
   base::Value::Dict arguments;
   arguments.Set("host", host_port_pair_.host());
   arguments.Set("port", host_port_pair_.port());
@@ -349,7 +349,7 @@
           !base::PathExists(certificate_path)) {
         LOG(ERROR) << "Certificate path " << certificate_path.value()
                    << " doesn't exist. Can't launch https server.";
-        return absl::nullopt;
+        return std::nullopt;
       }
       arguments.Set("cert-and-key-file", certificate_path.AsUTF8Unsafe());
     }
@@ -366,7 +366,7 @@
       if (it->IsAbsolute() && !base::PathExists(*it)) {
         LOG(ERROR) << "Client authority path " << it->value()
                    << " doesn't exist. Can't launch https server.";
-        return absl::nullopt;
+        return std::nullopt;
       }
       ssl_client_certs.Append(it->AsUTF8Unsafe());
     }
@@ -376,7 +376,7 @@
     }
   }
 
-  return absl::make_optional(std::move(arguments));
+  return std::make_optional(std::move(arguments));
 }
 
 }  // namespace net
diff --git a/net/test/spawned_test_server/base_test_server.h b/net/test/spawned_test_server/base_test_server.h
index 195c68d..589f3f7 100644
--- a/net/test/spawned_test_server/base_test_server.h
+++ b/net/test/spawned_test_server/base_test_server.h
@@ -11,6 +11,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -20,7 +21,6 @@
 #include "base/values.h"
 #include "net/base/host_port_pair.h"
 #include "net/cert/test_root_certs.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class GURL;
 
@@ -223,7 +223,7 @@
   // { argument-name: argument-value, ... }
   //
   // Returns nullopt if an invalid configuration is specified.
-  absl::optional<base::Value::Dict> GenerateArguments() const;
+  std::optional<base::Value::Dict> GenerateArguments() const;
 
  private:
   void Init(const std::string& host);
diff --git a/net/test/spawned_test_server/local_test_server.cc b/net/test/spawned_test_server/local_test_server.cc
index affc9c59..491d8a7 100644
--- a/net/test/spawned_test_server/local_test_server.cc
+++ b/net/test/spawned_test_server/local_test_server.cc
@@ -100,7 +100,7 @@
     return false;
   }
 
-  absl::optional<std::vector<base::FilePath>> python_path = GetPythonPath();
+  std::optional<std::vector<base::FilePath>> python_path = GetPythonPath();
   if (!python_path) {
     LOG(ERROR) << "Could not get Python path.";
     return false;
@@ -166,12 +166,12 @@
   return true;
 }
 
-absl::optional<std::vector<base::FilePath>> LocalTestServer::GetPythonPath()
+std::optional<std::vector<base::FilePath>> LocalTestServer::GetPythonPath()
     const {
   base::FilePath third_party_dir;
   if (!base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &third_party_dir)) {
     LOG(ERROR) << "Failed to get DIR_SRC_TEST_DATA_ROOT";
-    return absl::nullopt;
+    return std::nullopt;
   }
   third_party_dir = third_party_dir.AppendASCII("third_party");
 
@@ -184,7 +184,7 @@
 
 bool LocalTestServer::AddCommandLineArguments(
     base::CommandLine* command_line) const {
-  absl::optional<base::Value::Dict> arguments_dict = GenerateArguments();
+  std::optional<base::Value::Dict> arguments_dict = GenerateArguments();
   if (!arguments_dict)
     return false;
 
diff --git a/net/test/spawned_test_server/local_test_server.h b/net/test/spawned_test_server/local_test_server.h
index 0ca80b0..4a39362 100644
--- a/net/test/spawned_test_server/local_test_server.h
+++ b/net/test/spawned_test_server/local_test_server.h
@@ -5,6 +5,7 @@
 #ifndef NET_TEST_SPAWNED_TEST_SERVER_LOCAL_TEST_SERVER_H_
 #define NET_TEST_SPAWNED_TEST_SERVER_LOCAL_TEST_SERVER_H_
 
+#include <optional>
 #include <vector>
 
 #include "base/files/file_util.h"
@@ -12,7 +13,6 @@
 #include "base/process/process.h"
 #include "build/build_config.h"
 #include "net/test/spawned_test_server/base_test_server.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_WIN)
 #include "base/win/scoped_handle.h"
@@ -51,7 +51,7 @@
   bool Stop();
 
   // Returns the directories to use as the PYTHONPATH, or nullopt on error.
-  virtual absl::optional<std::vector<base::FilePath>> GetPythonPath() const;
+  virtual std::optional<std::vector<base::FilePath>> GetPythonPath() const;
 
   // Returns true if the base::FilePath for the testserver python script is
   // successfully stored  in |*testserver_path|.
diff --git a/net/test/spawned_test_server/remote_test_server.cc b/net/test/spawned_test_server/remote_test_server.cc
index 38c7573..9eccc12 100644
--- a/net/test/spawned_test_server/remote_test_server.cc
+++ b/net/test/spawned_test_server/remote_test_server.cc
@@ -81,7 +81,7 @@
   if (!ReadFileToString(config_path, &config_json))
     LOG(FATAL) << "Failed to read " << config_path.value();
 
-  absl::optional<base::Value> config = base::JSONReader::Read(config_json);
+  std::optional<base::Value> config = base::JSONReader::Read(config_json);
   if (!config)
     LOG(FATAL) << "Failed to parse " << config_path.value();
 
@@ -119,7 +119,7 @@
   DCHECK(!started());
   DCHECK(!start_request_);
 
-  absl::optional<base::Value::Dict> arguments_dict = GenerateArguments();
+  std::optional<base::Value::Dict> arguments_dict = GenerateArguments();
   if (!arguments_dict)
     return false;
 
diff --git a/net/test/test_doh_server.cc b/net/test/test_doh_server.cc
index 64006056..c9f215c 100644
--- a/net/test/test_doh_server.cc
+++ b/net/test/test_doh_server.cc
@@ -190,7 +190,7 @@
     return MakeHttpErrorResponse(HTTP_BAD_REQUEST, "invalid DNS query");
   }
 
-  absl::optional<std::string> name = dns_names_util::NetworkToDottedName(
+  std::optional<std::string> name = dns_names_util::NetworkToDottedName(
       dns_query.qname(), /*require_complete=*/true);
   if (!name) {
     DnsResponse response(dns_query.id(), /*is_authoritative=*/false,
diff --git a/net/test/test_doh_server.h b/net/test/test_doh_server.h
index e6a49c30..4f4cf1b 100644
--- a/net/test/test_doh_server.h
+++ b/net/test/test_doh_server.h
@@ -90,7 +90,7 @@
   std::unique_ptr<test_server::HttpResponse> HandleRequest(
       const test_server::HttpRequest& request);
 
-  absl::optional<std::string> hostname_;
+  std::optional<std::string> hostname_;
   base::Lock lock_;
   // The following fields are accessed from a background thread and protected by
   // `lock_`.
diff --git a/net/test/url_request/url_request_mock_data_job.h b/net/test/url_request/url_request_mock_data_job.h
index d0d1620..bed67ae 100644
--- a/net/test/url_request/url_request_mock_data_job.h
+++ b/net/test/url_request/url_request_mock_data_job.h
@@ -7,11 +7,11 @@
 
 #include <stddef.h>
 
+#include <optional>
 #include <string>
 
 #include "base/memory/weak_ptr.h"
 #include "net/url_request/url_request_job.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -66,7 +66,7 @@
 
   void StartAsync();
 
-  absl::optional<std::string> headers_;
+  std::optional<std::string> headers_;
   std::string data_;
   size_t data_offset_ = 0;
   bool request_client_certificate_;
diff --git a/net/third_party/quiche/overrides/quiche_platform_impl/quiche_command_line_flags_impl.h b/net/third_party/quiche/overrides/quiche_platform_impl/quiche_command_line_flags_impl.h
index 809c9d6..2548d44 100644
--- a/net/third_party/quiche/overrides/quiche_platform_impl/quiche_command_line_flags_impl.h
+++ b/net/third_party/quiche/overrides/quiche_platform_impl/quiche_command_line_flags_impl.h
@@ -5,6 +5,7 @@
 #ifndef NET_THIRD_PARTY_QUICHE_OVERRIDES_QUICHE_PLATFORM_IMPL_QUICHE_COMMAND_LINE_FLAGS_IMPL_H_
 #define NET_THIRD_PARTY_QUICHE_OVERRIDES_QUICHE_PLATFORM_IMPL_QUICHE_COMMAND_LINE_FLAGS_IMPL_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -14,7 +15,6 @@
 #include "base/no_destructor.h"
 #include "net/third_party/quiche/src/quiche/common/platform/api/quiche_export.h"
 #include "net/third_party/quiche/src/quiche/common/platform/api/quiche_flags.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace quiche {
 
@@ -135,7 +135,7 @@
   ~QuicheParseCommandLineFlagsResult();
 
   std::vector<std::string> non_flag_args;
-  absl::optional<int> exit_status;
+  std::optional<int> exit_status;
 };
 
 QuicheParseCommandLineFlagsResult QuicheParseCommandLineFlagsHelper(
diff --git a/net/third_party/quiche/overrides/quiche_platform_impl/quiche_time_utils_impl.cc b/net/third_party/quiche/overrides/quiche_platform_impl/quiche_time_utils_impl.cc
index 5435d4f..d2131bf 100644
--- a/net/third_party/quiche/overrides/quiche_platform_impl/quiche_time_utils_impl.cc
+++ b/net/third_party/quiche/overrides/quiche_platform_impl/quiche_time_utils_impl.cc
@@ -10,12 +10,12 @@
 
 namespace quiche {
 
-absl::optional<int64_t> QuicheUtcDateTimeToUnixSecondsImpl(int year,
-                                                           int month,
-                                                           int day,
-                                                           int hour,
-                                                           int minute,
-                                                           int second) {
+std::optional<int64_t> QuicheUtcDateTimeToUnixSecondsImpl(int year,
+                                                          int month,
+                                                          int day,
+                                                          int hour,
+                                                          int minute,
+                                                          int second) {
   struct tm tmp_tm;
   tmp_tm.tm_year = year - 1900;
   tmp_tm.tm_mon = month - 1;
@@ -31,13 +31,13 @@
   }
   int64_t result;
   if (!OPENSSL_tm_to_posix(&tmp_tm, &result)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   // Our desired behaviour is to return the following second for a leap second
   // assuming it is a valid time.
   if (leap_second) {
     if (!OPENSSL_posix_to_tm(result + 1, &tmp_tm)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     result++;
   }
diff --git a/net/third_party/quiche/overrides/quiche_platform_impl/quiche_time_utils_impl.h b/net/third_party/quiche/overrides/quiche_platform_impl/quiche_time_utils_impl.h
index 0ab8c884..b90ff2b 100644
--- a/net/third_party/quiche/overrides/quiche_platform_impl/quiche_time_utils_impl.h
+++ b/net/third_party/quiche/overrides/quiche_platform_impl/quiche_time_utils_impl.h
@@ -6,13 +6,13 @@
 #define NET_THIRD_PARTY_QUICHE_OVERRIDES_QUICHE_PLATFORM_IMPL_QUICHE_TIME_UTILS_IMPL_H_
 
 #include <cstdint>
+#include <optional>
 
 #include "quiche/common/platform/api/quiche_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace quiche {
 
-QUICHE_EXPORT absl::optional<int64_t> QuicheUtcDateTimeToUnixSecondsImpl(
+QUICHE_EXPORT std::optional<int64_t> QuicheUtcDateTimeToUnixSecondsImpl(
     int year,
     int month,
     int day,
diff --git a/net/third_party/quiche/overrides/quiche_platform_impl/quiche_url_utils_impl.cc b/net/third_party/quiche/overrides/quiche_platform_impl/quiche_url_utils_impl.cc
index c18b1af..09a476e 100644
--- a/net/third_party/quiche/overrides/quiche_platform_impl/quiche_url_utils_impl.cc
+++ b/net/third_party/quiche/overrides/quiche_platform_impl/quiche_url_utils_impl.cc
@@ -6,6 +6,7 @@
 
 #include <cstdint>
 #include <limits>
+#include <optional>
 #include <string>
 #include <string_view>
 
@@ -14,7 +15,6 @@
 #include "third_party/abseil-cpp/absl/container/flat_hash_set.h"
 #include "third_party/abseil-cpp/absl/strings/str_cat.h"
 #include "third_party/abseil-cpp/absl/strings/str_replace.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/url_canon.h"
 #include "url/url_util.h"
 
@@ -41,7 +41,7 @@
   return result;
 }
 
-absl::optional<std::string> AsciiUrlDecodeImpl(std::string_view input) {
+std::optional<std::string> AsciiUrlDecodeImpl(std::string_view input) {
   url::RawCanonOutputW<1024> canon_output;
   url::DecodeURLEscapeSequences(input, url::DecodeURLMode::kUTF8,
                                 &canon_output);
@@ -49,7 +49,7 @@
   output.reserve(canon_output.length());
   for (uint16_t c : canon_output.view()) {
     if (c > std::numeric_limits<signed char>::max()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     output += static_cast<char>(c);
   }
diff --git a/net/third_party/quiche/overrides/quiche_platform_impl/quiche_url_utils_impl.h b/net/third_party/quiche/overrides/quiche_platform_impl/quiche_url_utils_impl.h
index 3a625b2..54cd92b 100644
--- a/net/third_party/quiche/overrides/quiche_platform_impl/quiche_url_utils_impl.h
+++ b/net/third_party/quiche/overrides/quiche_platform_impl/quiche_url_utils_impl.h
@@ -5,13 +5,13 @@
 #ifndef NET_THIRD_PARTY_QUICHE_OVERRIDES_QUICHE_PLATFORM_IMPL_QUICHE_URL_UTILS_IMPL_H_
 #define NET_THIRD_PARTY_QUICHE_OVERRIDES_QUICHE_PLATFORM_IMPL_QUICHE_URL_UTILS_IMPL_H_
 
+#include <optional>
 #include <string>
 #include <string_view>
 
 #include "quiche/common/platform/api/quiche_export.h"
 #include "third_party/abseil-cpp/absl/container/flat_hash_map.h"
 #include "third_party/abseil-cpp/absl/container/flat_hash_set.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace quiche {
 
@@ -27,8 +27,8 @@
     absl::flat_hash_set<std::string>* vars_found = nullptr);
 
 // Decodes a URL-encoded string and converts it to ASCII. If the decoded input
-// contains non-ASCII characters, decoding fails and absl::nullopt is returned.
-QUICHE_EXPORT absl::optional<std::string> AsciiUrlDecodeImpl(
+// contains non-ASCII characters, decoding fails and std::nullopt is returned.
+QUICHE_EXPORT std::optional<std::string> AsciiUrlDecodeImpl(
     std::string_view input);
 
 }  // namespace quiche
diff --git a/net/tools/cert_verify_tool/cert_verify_tool.cc b/net/tools/cert_verify_tool/cert_verify_tool.cc
index a2d60bf0..66c7c5b 100644
--- a/net/tools/cert_verify_tool/cert_verify_tool.cc
+++ b/net/tools/cert_verify_tool/cert_verify_tool.cc
@@ -506,7 +506,7 @@
     bssl::CertificateTrust trust = bssl::CertificateTrust::ForTrustedLeaf();
     std::string trust_str = command_line.GetSwitchValueASCII("trust-leaf-cert");
     if (!trust_str.empty()) {
-      absl::optional<bssl::CertificateTrust> parsed_trust =
+      std::optional<bssl::CertificateTrust> parsed_trust =
           bssl::CertificateTrust::FromDebugString(trust_str);
       if (!parsed_trust) {
         std::cerr << "ERROR: invalid leaf trust string " << trust_str << "\n";
@@ -523,7 +523,7 @@
 
   if (command_line.HasSwitch("root-trust")) {
     std::string trust_str = command_line.GetSwitchValueASCII("root-trust");
-    absl::optional<bssl::CertificateTrust> parsed_trust =
+    std::optional<bssl::CertificateTrust> parsed_trust =
         bssl::CertificateTrust::FromDebugString(trust_str);
     if (!parsed_trust) {
       std::cerr << "ERROR: invalid root trust string " << trust_str << "\n";
diff --git a/net/tools/quic/quic_simple_server_packet_writer.cc b/net/tools/quic/quic_simple_server_packet_writer.cc
index 90d00b01..1ca7ccbf 100644
--- a/net/tools/quic/quic_simple_server_packet_writer.cc
+++ b/net/tools/quic/quic_simple_server_packet_writer.cc
@@ -41,7 +41,7 @@
   write_blocked_ = false;
 }
 
-absl::optional<int> QuicSimpleServerPacketWriter::MessageTooBigErrorCode()
+std::optional<int> QuicSimpleServerPacketWriter::MessageTooBigErrorCode()
     const {
   return ERR_MSG_TOO_BIG;
 }
diff --git a/net/tools/quic/quic_simple_server_packet_writer.h b/net/tools/quic/quic_simple_server_packet_writer.h
index 5685784d..00ed499 100644
--- a/net/tools/quic/quic_simple_server_packet_writer.h
+++ b/net/tools/quic/quic_simple_server_packet_writer.h
@@ -50,7 +50,7 @@
   // quic::QuicPacketWriter implementation:
   bool IsWriteBlocked() const override;
   void SetWritable() override;
-  absl::optional<int> MessageTooBigErrorCode() const override;
+  std::optional<int> MessageTooBigErrorCode() const override;
   quic::QuicByteCount GetMaxPacketSize(
       const quic::QuicSocketAddress& peer_address) const override;
   bool SupportsReleaseTime() const override;
diff --git a/net/tools/quic/synchronous_host_resolver.cc b/net/tools/quic/synchronous_host_resolver.cc
index a09c04c..dfb89e3 100644
--- a/net/tools/quic/synchronous_host_resolver.cc
+++ b/net/tools/quic/synchronous_host_resolver.cc
@@ -5,6 +5,7 @@
 #include "net/tools/quic/synchronous_host_resolver.h"
 
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "base/at_exit.h"
@@ -22,7 +23,6 @@
 #include "net/dns/host_resolver.h"
 #include "net/log/net_log.h"
 #include "net/log/net_log_with_source.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/scheme_host_port.h"
 
 namespace net {
@@ -70,7 +70,7 @@
   // tool not used by net/ consumers.
   std::unique_ptr<net::HostResolver::ResolveHostRequest> request =
       resolver->CreateRequest(scheme_host_port_, NetworkAnonymizationKey(),
-                              NetLogWithSource(), absl::nullopt);
+                              NetLogWithSource(), std::nullopt);
 
   base::RunLoop run_loop;
   rv_ = request->Start(base::BindOnce(&ResolverThread::OnResolutionComplete,
diff --git a/net/tools/root_store_tool/root_store_tool.cc b/net/tools/root_store_tool/root_store_tool.cc
index 14bcdc6..811f9f8 100644
--- a/net/tools/root_store_tool/root_store_tool.cc
+++ b/net/tools/root_store_tool/root_store_tool.cc
@@ -6,6 +6,7 @@
 
 #include <iostream>
 #include <map>
+#include <optional>
 #include <set>
 #include <string>
 
@@ -27,7 +28,6 @@
 #include "crypto/openssl_util.h"
 #include "crypto/sha2.h"
 #include "net/cert/root_store_proto_full/root_store.pb.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/include/openssl/bio.h"
 #include "third_party/boringssl/src/include/openssl/err.h"
 #include "third_party/boringssl/src/include/openssl/pem.h"
@@ -38,8 +38,8 @@
 namespace {
 
 // Returns a map from hex-encoded SHA-256 hash to DER certificate, or
-// `absl::nullopt` if not found.
-absl::optional<std::map<std::string, std::string>> DecodeCerts(
+// `std::nullopt` if not found.
+std::optional<std::map<std::string, std::string>> DecodeCerts(
     base::StringPiece in) {
   // TODO(https://crbug.com/1216547): net/cert/pem.h has a much nicer API, but
   // it would require some build refactoring to avoid a circular dependency.
@@ -47,7 +47,7 @@
   // net/cert/internal, which it may not.
   bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(in.data(), in.size()));
   if (!bio) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   std::map<std::string, std::string> certs;
   for (;;) {
@@ -63,7 +63,7 @@
         break;
       }
       LOG(ERROR) << "Error reading PEM.";
-      return absl::nullopt;
+      return std::nullopt;
     }
     bssl::UniquePtr<char> scoped_name(name);
     bssl::UniquePtr<char> scoped_header(header);
@@ -71,7 +71,7 @@
     if (strcmp(name, "CERTIFICATE") != 0) {
       LOG(ERROR) << "Found PEM block of type " << name
                  << " instead of CERTIFICATE";
-      return absl::nullopt;
+      return std::nullopt;
     }
     std::string sha256_hex =
         base::ToLowerASCII(base::HexEncode(crypto::SHA256Hash(
@@ -81,21 +81,21 @@
   return std::move(certs);
 }
 
-absl::optional<RootStore> ReadTextRootStore(
+std::optional<RootStore> ReadTextRootStore(
     const base::FilePath& root_store_path,
     const base::FilePath& certs_path) {
   std::string root_store_text;
   if (!base::ReadFileToString(base::MakeAbsoluteFilePath(root_store_path),
                               &root_store_text)) {
     LOG(ERROR) << "Could not read " << root_store_path;
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   RootStore root_store;
   if (!google::protobuf::TextFormat::ParseFromString(root_store_text,
                                                      &root_store)) {
     LOG(ERROR) << "Could not parse " << root_store_path;
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::map<std::string, std::string> certs;
@@ -104,12 +104,12 @@
     if (!base::ReadFileToString(base::MakeAbsoluteFilePath(certs_path),
                                 &certs_data)) {
       LOG(ERROR) << "Could not read " << certs_path;
-      return absl::nullopt;
+      return std::nullopt;
     }
     auto certs_opt = DecodeCerts(certs_data);
     if (!certs_opt) {
       LOG(ERROR) << "Could not decode " << certs_path;
-      return absl::nullopt;
+      return std::nullopt;
     }
     certs = std::move(*certs_opt);
   }
@@ -124,7 +124,7 @@
     auto iter = certs.find(anchor.sha256_hex());
     if (iter == certs.end()) {
       LOG(ERROR) << "Could not find certificate " << anchor.sha256_hex();
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     // Remove the certificate from `certs`. This both checks for duplicate
@@ -136,7 +136,7 @@
   if (!certs.empty()) {
     LOG(ERROR) << "Unused certificate (SHA-256 hash " << certs.begin()->first
                << ") in " << certs_path;
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return std::move(root_store);
@@ -300,7 +300,7 @@
     return 1;
   }
 
-  absl::optional<RootStore> root_store =
+  std::optional<RootStore> root_store =
       ReadTextRootStore(root_store_path, certs_path);
   if (!root_store) {
     return 1;
diff --git a/net/tools/testserver/run_testserver.cc b/net/tools/testserver/run_testserver.cc
index d110d2d..774c8f01 100644
--- a/net/tools/testserver/run_testserver.cc
+++ b/net/tools/testserver/run_testserver.cc
@@ -52,7 +52,7 @@
   }
 
   // If populated, EmbeddedTestServer is used instead of the SpawnedTestServer.
-  absl::optional<net::EmbeddedTestServer::Type> embedded_test_server_type;
+  std::optional<net::EmbeddedTestServer::Type> embedded_test_server_type;
 
   net::SpawnedTestServer::Type server_type;
   if (command_line->HasSwitch("http")) {
diff --git a/net/tools/transport_security_state_generator/input_file_parsers.cc b/net/tools/transport_security_state_generator/input_file_parsers.cc
index a21516c..5c0eb56c 100644
--- a/net/tools/transport_security_state_generator/input_file_parsers.cc
+++ b/net/tools/transport_security_state_generator/input_file_parsers.cc
@@ -339,13 +339,13 @@
       "test",        "public-suffix", "google",      "custom",
       "bulk-legacy", "bulk-18-weeks", "bulk-1-year", "public-suffix-requested"};
 
-  absl::optional<base::Value> hsts_value = base::JSONReader::Read(hsts_json);
+  std::optional<base::Value> hsts_value = base::JSONReader::Read(hsts_json);
   if (!hsts_value.has_value() || !hsts_value->is_dict()) {
     LOG(ERROR) << "Could not parse the input HSTS JSON file";
     return false;
   }
 
-  absl::optional<base::Value> pins_value = base::JSONReader::Read(pins_json);
+  std::optional<base::Value> pins_value = base::JSONReader::Read(pins_json);
   if (!pins_value.has_value()) {
     LOG(ERROR) << "Could not parse the input pins JSON file";
     return false;
diff --git a/net/url_request/redirect_info.cc b/net/url_request/redirect_info.cc
index 4042f02..07e0cc4 100644
--- a/net/url_request/redirect_info.cc
+++ b/net/url_request/redirect_info.cc
@@ -37,7 +37,7 @@
 // policy that should be used for the request.
 ReferrerPolicy ProcessReferrerPolicyHeaderOnRedirect(
     ReferrerPolicy original_referrer_policy,
-    const absl::optional<std::string>& referrer_policy_header) {
+    const std::optional<std::string>& referrer_policy_header) {
   ReferrerPolicy new_policy = original_referrer_policy;
   std::vector<base::StringPiece> policy_tokens;
   if (referrer_policy_header) {
@@ -114,7 +114,7 @@
     const std::string& original_referrer,
     int http_status_code,
     const GURL& new_location,
-    const absl::optional<std::string>& referrer_policy_header,
+    const std::optional<std::string>& referrer_policy_header,
     bool insecure_scheme_was_upgraded,
     bool copy_fragment,
     bool is_signed_exchange_fallback_redirect) {
diff --git a/net/url_request/redirect_info.h b/net/url_request/redirect_info.h
index 5b4dae0..810eaf97 100644
--- a/net/url_request/redirect_info.h
+++ b/net/url_request/redirect_info.h
@@ -5,13 +5,13 @@
 #ifndef NET_URL_REQUEST_REDIRECT_INFO_H_
 #define NET_URL_REQUEST_REDIRECT_INFO_H_
 
+#include <optional>
 #include <string>
 
 #include "base/time/time.h"
 #include "net/base/net_export.h"
 #include "net/cookies/site_for_cookies.h"
 #include "net/url_request/referrer_policy.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace net {
@@ -47,7 +47,7 @@
       // The new location URL of the redirect response.
       const GURL& new_location,
       // Referrer-Policy header of the redirect response.
-      const absl::optional<std::string>& referrer_policy_header,
+      const std::optional<std::string>& referrer_policy_header,
       // Whether the URL was upgraded to HTTPS due to upgrade-insecure-requests.
       bool insecure_scheme_was_upgraded,
       // This method copies the URL fragment of the original URL to the new URL
diff --git a/net/url_request/redirect_info_unittest.cc b/net/url_request/redirect_info_unittest.cc
index a4b5d14e..ce10b7a3 100644
--- a/net/url_request/redirect_info_unittest.cc
+++ b/net/url_request/redirect_info_unittest.cc
@@ -53,7 +53,7 @@
         test.original_method, kOriginalUrl, kOriginalSiteForCookies,
         kOriginalFirstPartyUrlPolicy, kOriginalReferrerPolicy,
         kOriginalReferrer, test.http_status_code, kNewLocation,
-        absl::nullopt /* referrer_policy_header */, kInsecureSchemeWasUpgraded,
+        std::nullopt /* referrer_policy_header */, kInsecureSchemeWasUpgraded,
         kCopyFragment);
 
     EXPECT_EQ(test.expected_new_method, redirect_info.new_method);
@@ -104,7 +104,7 @@
         kOriginalMethod, GURL(test.original_url), kOriginalSiteForCookies,
         kOriginalFirstPartyUrlPolicy, kOriginalReferrerPolicy,
         kOriginalReferrer, kHttpStatusCode, GURL(test.new_location),
-        absl::nullopt /* referrer_policy_header */, kInsecureSchemeWasUpgraded,
+        std::nullopt /* referrer_policy_header */, kInsecureSchemeWasUpgraded,
         test.copy_fragment);
 
     EXPECT_EQ(GURL(test.expected_new_url), redirect_info.new_url);
@@ -143,7 +143,7 @@
         kOriginalMethod, kOriginalUrl, kOriginalSiteForCookies,
         test.original_first_party_url_policy, kOriginalReferrerPolicy,
         kOriginalReferrer, kHttpStatusCode, kNewLocation,
-        absl::nullopt /* referrer_policy_header */, kInsecureSchemeWasUpgraded,
+        std::nullopt /* referrer_policy_header */, kInsecureSchemeWasUpgraded,
         kCopyFragment);
 
     EXPECT_TRUE(redirect_info.new_site_for_cookies.IsEquivalent(
diff --git a/net/url_request/redirect_util.cc b/net/url_request/redirect_util.cc
index 63f2e68..acbd43a 100644
--- a/net/url_request/redirect_util.cc
+++ b/net/url_request/redirect_util.cc
@@ -21,8 +21,8 @@
     const GURL& original_url,
     const std::string& original_method,
     const RedirectInfo& redirect_info,
-    const absl::optional<std::vector<std::string>>& removed_headers,
-    const absl::optional<net::HttpRequestHeaders>& modified_headers,
+    const std::optional<std::vector<std::string>>& removed_headers,
+    const std::optional<net::HttpRequestHeaders>& modified_headers,
     HttpRequestHeaders* request_headers,
     bool* should_clear_upload) {
   DCHECK(request_headers);
@@ -89,14 +89,14 @@
 }
 
 // static
-absl::optional<std::string> RedirectUtil::GetReferrerPolicyHeader(
+std::optional<std::string> RedirectUtil::GetReferrerPolicyHeader(
     const HttpResponseHeaders* response_headers) {
   if (!response_headers)
-    return absl::nullopt;
+    return std::nullopt;
   std::string referrer_policy_header;
   if (!response_headers->GetNormalizedHeader("Referrer-Policy",
                                              &referrer_policy_header)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return referrer_policy_header;
 }
diff --git a/net/url_request/redirect_util.h b/net/url_request/redirect_util.h
index 3594f10..4d538d80 100644
--- a/net/url_request/redirect_util.h
+++ b/net/url_request/redirect_util.h
@@ -5,12 +5,12 @@
 #ifndef NET_URL_REQUEST_REDIRECT_UTIL_H_
 #define NET_URL_REQUEST_REDIRECT_UTIL_H_
 
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "base/memory/scoped_refptr.h"
 #include "net/base/net_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class GURL;
 
@@ -40,14 +40,14 @@
       const GURL& original_url,
       const std::string& original_method,
       const RedirectInfo& redirect_info,
-      const absl::optional<std::vector<std::string>>& removed_headers,
-      const absl::optional<net::HttpRequestHeaders>& modified_headers,
+      const std::optional<std::vector<std::string>>& removed_headers,
+      const std::optional<net::HttpRequestHeaders>& modified_headers,
       HttpRequestHeaders* request_headers,
       bool* should_clear_upload);
 
   // Returns the the "normalized" value of Referrer-Policy header if available.
-  // Otherwise returns absl::nullopt.
-  NET_EXPORT static absl::optional<std::string> GetReferrerPolicyHeader(
+  // Otherwise returns std::nullopt.
+  NET_EXPORT static std::optional<std::string> GetReferrerPolicyHeader(
       const HttpResponseHeaders* response_headers);
 
   NET_EXPORT static scoped_refptr<HttpResponseHeaders>
diff --git a/net/url_request/redirect_util_unittest.cc b/net/url_request/redirect_util_unittest.cc
index e0056598..93b08e2 100644
--- a/net/url_request/redirect_util_unittest.cc
+++ b/net/url_request/redirect_util_unittest.cc
@@ -125,7 +125,7 @@
 
     RedirectUtil::UpdateHttpRequest(
         original_url, test.original_method, redirect_info,
-        absl::nullopt /* removed_headers */, modified_headers, &request_headers,
+        std::nullopt /* removed_headers */, modified_headers, &request_headers,
         &should_clear_upload);
     EXPECT_EQ(test.expected_should_clear_upload, should_clear_upload);
 
@@ -258,13 +258,13 @@
   }
 }
 
-// Test with removed_headers = absl::nullopt.
+// Test with removed_headers = std::nullopt.
 TEST(RedirectUtilTest, RemovedHeadersNullOpt) {
   HttpRequestHeaders initial_headers, final_headers;
   initial_headers.SetHeader("A", "0");
   final_headers.SetHeader("A", "0");
-  absl::optional<std::vector<std::string>> removed_headers(absl::nullopt);
-  absl::optional<HttpRequestHeaders> modified_headers(absl::in_place);
+  std::optional<std::vector<std::string>> removed_headers(std::nullopt);
+  std::optional<HttpRequestHeaders> modified_headers(std::in_place);
   bool should_clear_upload(false);  // unused.
 
   RedirectUtil::UpdateHttpRequest(GURL(),         // original_url
@@ -278,13 +278,13 @@
   EXPECT_EQ(initial_headers.ToString(), final_headers.ToString());
 }
 
-// Test with modified_headers = absl::nullopt.
+// Test with modified_headers = std::nullopt.
 TEST(RedirectUtilTest, ModifyHeadersNullopt) {
   HttpRequestHeaders initial_headers, final_headers;
   initial_headers.SetHeader("A", "0");
   final_headers.SetHeader("A", "0");
-  absl::optional<std::vector<std::string>> removed_headers(absl::in_place);
-  absl::optional<HttpRequestHeaders> modified_headers(absl::nullopt);
+  std::optional<std::vector<std::string>> removed_headers(std::in_place);
+  std::optional<HttpRequestHeaders> modified_headers(std::nullopt);
   bool should_clear_upload(false);  // unused.
 
   RedirectUtil::UpdateHttpRequest(GURL(),         // original_url
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc
index 1bd70e77..1091a9f 100644
--- a/net/url_request/url_request.cc
+++ b/net/url_request/url_request.cc
@@ -131,7 +131,7 @@
 
 NetLogWithSource CreateNetLogWithSource(
     NetLog* net_log,
-    absl::optional<net::NetLogSource> net_log_source) {
+    std::optional<net::NetLogSource> net_log_source) {
   if (net_log_source) {
     return NetLogWithSource::Make(net_log, net_log_source.value());
   }
@@ -378,7 +378,7 @@
   return response_info_.headers.get();
 }
 
-const absl::optional<AuthChallengeInfo>& URLRequest::auth_challenge_info()
+const std::optional<AuthChallengeInfo>& URLRequest::auth_challenge_info()
     const {
   return response_info_.auth_challenge;
 }
@@ -484,7 +484,7 @@
   first_party_url_policy_ = first_party_url_policy;
 }
 
-void URLRequest::set_initiator(const absl::optional<url::Origin>& initiator) {
+void URLRequest::set_initiator(const std::optional<url::Origin>& initiator) {
   DCHECK(!is_pending_);
   DCHECK(!initiator.has_value() || initiator.value().opaque() ||
          initiator.value().GetURL().is_valid());
@@ -577,7 +577,7 @@
                        const URLRequestContext* context,
                        NetworkTrafficAnnotationTag traffic_annotation,
                        bool is_for_websockets,
-                       absl::optional<net::NetLogSource> net_log_source)
+                       std::optional<net::NetLogSource> net_log_source)
     : context_(context),
       net_log_(CreateNetLogWithSource(context->net_log(), net_log_source)),
       url_chain_(1, url),
@@ -861,8 +861,8 @@
 }
 
 void URLRequest::FollowDeferredRedirect(
-    const absl::optional<std::vector<std::string>>& removed_headers,
-    const absl::optional<net::HttpRequestHeaders>& modified_headers) {
+    const std::optional<std::vector<std::string>>& removed_headers,
+    const std::optional<net::HttpRequestHeaders>& modified_headers) {
   DCHECK(job_.get());
   DCHECK_EQ(OK, status_);
 
@@ -946,8 +946,8 @@
 
 void URLRequest::Redirect(
     const RedirectInfo& redirect_info,
-    const absl::optional<std::vector<std::string>>& removed_headers,
-    const absl::optional<net::HttpRequestHeaders>& modified_headers) {
+    const std::optional<std::vector<std::string>>& removed_headers,
+    const std::optional<net::HttpRequestHeaders>& modified_headers) {
   // This method always succeeds. Whether |job_| is allowed to redirect to
   // |redirect_info| is checked in URLRequestJob::CanFollowRedirect, before
   // NotifyReceivedRedirect. This means the delegate can assume that, if it
@@ -1197,7 +1197,7 @@
   url::Origin top_frame_origin =
       network_anonymization_key.GetTopFrameSite()->site_as_origin_;
 
-  absl::optional<url::Origin> frame_origin;
+  std::optional<url::Origin> frame_origin;
   if (network_anonymization_key.IsCrossSite()) {
     // If we know that the origin is cross site to the top level site, create an
     // empty origin to use as the frame origin for the isolation info. This
diff --git a/net/url_request/url_request.h b/net/url_request/url_request.h
index ce7074e0..859dcb00 100644
--- a/net/url_request/url_request.h
+++ b/net/url_request/url_request.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -54,7 +55,6 @@
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "net/url_request/redirect_info.h"
 #include "net/url_request/referrer_policy.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -218,7 +218,7 @@
              const URLRequestContext* context,
              NetworkTrafficAnnotationTag traffic_annotation,
              bool is_for_websockets,
-             absl::optional<net::NetLogSource> net_log_source);
+             std::optional<net::NetLogSource> net_log_source);
 
   URLRequest(const URLRequest&) = delete;
   URLRequest& operator=(const URLRequest&) = delete;
@@ -302,7 +302,7 @@
 
   const IsolationInfo& isolation_info() const { return isolation_info_; }
 
-  const absl::optional<CookiePartitionKey>& cookie_partition_key() const {
+  const std::optional<CookiePartitionKey>& cookie_partition_key() const {
     return cookie_partition_key_;
   }
 
@@ -362,9 +362,9 @@
   // Note: the initiator can be null for browser-initiated top level
   // navigations. This is different from a unique Origin (e.g. in sandboxed
   // iframes).
-  const absl::optional<url::Origin>& initiator() const { return initiator_; }
+  const std::optional<url::Origin>& initiator() const { return initiator_; }
   // This method may only be called before Start().
-  void set_initiator(const absl::optional<url::Origin>& initiator);
+  void set_initiator(const std::optional<url::Origin>& initiator);
 
   // The request method.  "GET" is the default value. The request method may
   // only be changed before Start() is called. Request methods are
@@ -525,7 +525,7 @@
   // Get the SSL connection info.
   const SSLInfo& ssl_info() const { return response_info_.ssl_info; }
 
-  const absl::optional<AuthChallengeInfo>& auth_challenge_info() const;
+  const std::optional<AuthChallengeInfo>& auth_challenge_info() const;
 
   // Gets timing information related to the request.  Events that have not yet
   // occurred are left uninitialized.  After a second request starts, due to
@@ -663,8 +663,8 @@
   // |modified_headers| are changes applied to the request headers after
   // updating them for the redirect.
   void FollowDeferredRedirect(
-      const absl::optional<std::vector<std::string>>& removed_headers,
-      const absl::optional<net::HttpRequestHeaders>& modified_headers);
+      const std::optional<std::vector<std::string>>& removed_headers,
+      const std::optional<net::HttpRequestHeaders>& modified_headers);
 
   // One of the following two methods should be called in response to an
   // OnAuthRequired() callback (and only then).
@@ -750,13 +750,13 @@
     return traffic_annotation_;
   }
 
-  const absl::optional<base::flat_set<net::SourceStream::SourceType>>&
+  const std::optional<base::flat_set<net::SourceStream::SourceType>>&
   accepted_stream_types() const {
     return accepted_stream_types_;
   }
 
   void set_accepted_stream_types(
-      const absl::optional<base::flat_set<net::SourceStream::SourceType>>&
+      const std::optional<base::flat_set<net::SourceStream::SourceType>>&
           types) {
     if (types) {
       DCHECK(!types->contains(net::SourceStream::SourceType::TYPE_NONE));
@@ -860,10 +860,9 @@
   // Allow the URLRequestJob to redirect this request. If non-null,
   // |removed_headers| and |modified_headers| are changes
   // applied to the request headers after updating them for the redirect.
-  void Redirect(
-      const RedirectInfo& redirect_info,
-      const absl::optional<std::vector<std::string>>& removed_headers,
-      const absl::optional<net::HttpRequestHeaders>& modified_headers);
+  void Redirect(const RedirectInfo& redirect_info,
+                const std::optional<std::vector<std::string>>& removed_headers,
+                const std::optional<net::HttpRequestHeaders>& modified_headers);
 
   // Called by URLRequestJob to allow interception when a redirect occurs.
   void NotifyReceivedRedirect(const RedirectInfo& redirect_info,
@@ -968,13 +967,13 @@
   // partitioning is not enabled, or if the NIK has no top-frame site.
   //
   // Unpartitioned cookies are unaffected by this field.
-  absl::optional<CookiePartitionKey> cookie_partition_key_ = absl::nullopt;
+  std::optional<CookiePartitionKey> cookie_partition_key_ = std::nullopt;
 
   bool force_ignore_site_for_cookies_ = false;
   bool force_main_frame_for_same_site_cookies_ = false;
   CookieSettingOverrides cookie_setting_overrides_;
 
-  absl::optional<url::Origin> initiator_;
+  std::optional<url::Origin> initiator_;
   GURL delegate_redirect_url_;
   std::string method_;  // "GET", "POST", etc. Case-sensitive.
   std::string referrer_;
@@ -1087,7 +1086,7 @@
   // If not null, the network service will not advertise any stream types
   // (via Accept-Encoding) that are not listed. Also, it will not attempt
   // decoding any non-listed stream types.
-  absl::optional<base::flat_set<net::SourceStream::SourceType>>
+  std::optional<base::flat_set<net::SourceStream::SourceType>>
       accepted_stream_types_;
 
   const NetworkTrafficAnnotationTag traffic_annotation_;
diff --git a/net/url_request/url_request_context.cc b/net/url_request/url_request_context.cc
index 9864694a..5b3fa2e3 100644
--- a/net/url_request/url_request_context.cc
+++ b/net/url_request/url_request_context.cc
@@ -133,7 +133,7 @@
     URLRequest::Delegate* delegate,
     NetworkTrafficAnnotationTag traffic_annotation,
     bool is_for_websockets,
-    const absl::optional<net::NetLogSource> net_log_source) const {
+    const std::optional<net::NetLogSource> net_log_source) const {
   return std::make_unique<URLRequest>(
       base::PassKey<URLRequestContext>(), url, priority, delegate, this,
       traffic_annotation, is_for_websockets, net_log_source);
diff --git a/net/url_request/url_request_context.h b/net/url_request/url_request_context.h
index 6b4f3a5..61c7da8f 100644
--- a/net/url_request/url_request_context.h
+++ b/net/url_request/url_request_context.h
@@ -9,7 +9,9 @@
 #define NET_URL_REQUEST_URL_REQUEST_CONTEXT_H_
 
 #include <stdint.h>
+
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 
@@ -26,7 +28,6 @@
 #include "net/net_buildflags.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "net/url_request/url_request.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 class CertVerifier;
@@ -120,8 +121,8 @@
       URLRequest::Delegate* delegate,
       NetworkTrafficAnnotationTag traffic_annotation,
       bool is_for_websockets = false,
-      const absl::optional<net::NetLogSource> net_log_source =
-          absl::nullopt) const;
+      const std::optional<net::NetLogSource> net_log_source =
+          std::nullopt) const;
 
   NetLog* net_log() const { return net_log_; }
 
@@ -236,11 +237,11 @@
     job_factory_ = job_factory;
   }
 
-  const absl::optional<std::string>& cookie_deprecation_label() const {
+  const std::optional<std::string>& cookie_deprecation_label() const {
     return cookie_deprecation_label_;
   }
 
-  void set_cookie_deprecation_label(const absl::optional<std::string>& label) {
+  void set_cookie_deprecation_label(const std::optional<std::string>& label) {
     cookie_deprecation_label_ = label;
   }
 
@@ -368,7 +369,7 @@
   // provided to a request when true.
   bool require_network_anonymization_key_ = false;
 
-  absl::optional<std::string> cookie_deprecation_label_;
+  std::optional<std::string> cookie_deprecation_label_;
 
   handles::NetworkHandle bound_network_;
 
diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc
index 30a861d..ca4293c 100644
--- a/net/url_request/url_request_context_builder.cc
+++ b/net/url_request/url_request_context_builder.cc
@@ -5,6 +5,7 @@
 #include "net/url_request/url_request_context_builder.h"
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -50,7 +51,6 @@
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_job_factory.h"
 #include "net/url_request/url_request_throttler_manager.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/url_constants.h"
 
 #if BUILDFLAG(ENABLE_REPORTING)
@@ -246,7 +246,7 @@
 
 void URLRequestContextBuilder::BindToNetwork(
     handles::NetworkHandle network,
-    absl::optional<HostResolver::ManagerOptions> options) {
+    std::optional<HostResolver::ManagerOptions> options) {
 #if BUILDFLAG(IS_ANDROID)
   DCHECK(NetworkChangeNotifier::AreNetworkHandlesSupported());
   // DNS lookups for this context will need to target `network`. NDK to do that
diff --git a/net/url_request/url_request_context_builder.h b/net/url_request/url_request_context_builder.h
index e65bf66..270b0b29 100644
--- a/net/url_request/url_request_context_builder.h
+++ b/net/url_request/url_request_context_builder.h
@@ -18,6 +18,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -44,7 +45,6 @@
 #include "net/ssl/ssl_config_service.h"
 #include "net/third_party/quiche/src/quiche/quic/core/quic_packets.h"
 #include "net/url_request/url_request_job_factory.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -358,7 +358,7 @@
   // Only implemented for Android (API level > 23).
   void BindToNetwork(
       handles::NetworkHandle network,
-      absl::optional<HostResolver::ManagerOptions> options = absl::nullopt);
+      std::optional<HostResolver::ManagerOptions> options = std::nullopt);
 
   // Creates a mostly self-contained URLRequestContext. May only be called once
   // per URLRequestContextBuilder. After this is called, the Builder can be
@@ -410,7 +410,7 @@
   std::string user_agent_;
   std::unique_ptr<HttpUserAgentSettings> http_user_agent_settings_;
 
-  absl::optional<std::string> cookie_deprecation_label_;
+  std::optional<std::string> cookie_deprecation_label_;
 
   bool http_cache_enabled_ = true;
   bool throttling_enabled_ = false;
diff --git a/net/url_request/url_request_context_builder_unittest.cc b/net/url_request/url_request_context_builder_unittest.cc
index b3726c6..c404075 100644
--- a/net/url_request/url_request_context_builder_unittest.cc
+++ b/net/url_request/url_request_context_builder_unittest.cc
@@ -293,9 +293,9 @@
   std::unique_ptr<URLRequestContext> context(builder_.Build());
 
   std::unique_ptr<HostResolver::ResolveHostRequest> request =
-      context->host_resolver()->CreateRequest(
-          HostPortPair("example.com", 1234), NetworkAnonymizationKey(),
-          NetLogWithSource(), absl::nullopt);
+      context->host_resolver()->CreateRequest(HostPortPair("example.com", 1234),
+                                              NetworkAnonymizationKey(),
+                                              NetLogWithSource(), std::nullopt);
   TestCompletionCallback callback;
   int rv = request->Start(callback.callback());
   ASSERT_TRUE(state->has_pending_requests());
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index 8db2e65..cc8a485 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <iterator>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -95,7 +96,6 @@
 #include "net/url_request/url_request_redirect_job.h"
 #include "net/url_request/url_request_throttler_manager.h"
 #include "net/url_request/websocket_handshake_userdata_key.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 #include "url/url_constants.h"
@@ -125,7 +125,7 @@
     const int64_t* const fps_cache_filter) {
   base::Value::Dict dict;
   auto entry_or_empty =
-      [](const absl::optional<net::FirstPartySetEntry>& entry) -> std::string {
+      [](const std::optional<net::FirstPartySetEntry>& entry) -> std::string {
     return entry.has_value() ? entry->GetDebugString() : "none";
   };
 
@@ -389,7 +389,7 @@
 
   request_->net_log().BeginEvent(NetLogEventType::FIRST_PARTY_SETS_METADATA);
 
-  absl::optional<
+  std::optional<
       std::pair<FirstPartySetMetadata, FirstPartySetsCacheFilter::MatchInfo>>
       maybe_metadata = cookie_util::ComputeFirstPartySetMetadataMaybeAsync(
           SchemefulSite(request()->url()), request()->isolation_info(),
@@ -589,7 +589,7 @@
 
 void URLRequestHttpJob::NotifyBeforeStartTransactionCallback(
     int result,
-    const absl::optional<HttpRequestHeaders>& headers) {
+    const std::optional<HttpRequestHeaders>& headers) {
   // The request should not have been cancelled or have already completed.
   DCHECK(!is_done());
 
@@ -942,9 +942,9 @@
   }
 
   base::Time response_date;
-  absl::optional<base::Time> server_time = absl::nullopt;
+  std::optional<base::Time> server_time = std::nullopt;
   if (GetResponseHeaders()->GetDateValue(&response_date))
-    server_time = absl::make_optional(response_date);
+    server_time = std::make_optional(response_date);
 
   bool force_ignore_site_for_cookies =
       request_->force_ignore_site_for_cookies();
@@ -998,7 +998,7 @@
         request_->cookie_partition_key(), /*block_truncated=*/true,
         &returned_status);
 
-    absl::optional<CanonicalCookie> cookie_to_return = absl::nullopt;
+    std::optional<CanonicalCookie> cookie_to_return = std::nullopt;
     if (returned_status.IsInclude()) {
       DCHECK(cookie);
       // Make a copy of the cookie if we successfully made one.
@@ -1041,11 +1041,10 @@
     NotifyHeadersComplete();
 }
 
-void URLRequestHttpJob::OnSetCookieResult(
-    const CookieOptions& options,
-    absl::optional<CanonicalCookie> cookie,
-    std::string cookie_string,
-    CookieAccessResult access_result) {
+void URLRequestHttpJob::OnSetCookieResult(const CookieOptions& options,
+                                          std::optional<CanonicalCookie> cookie,
+                                          std::string cookie_string,
+                                          CookieAccessResult access_result) {
   if (request_->net_log().IsCapturing()) {
     request_->net_log().AddEvent(NetLogEventType::COOKIE_INCLUSION_STATUS,
                                  [&](NetLogCaptureMode capture_mode) {
@@ -1131,7 +1130,7 @@
       // |URLRequestHttpJob::OnHeadersReceivedCallback()| or
       // |NetworkDelegate::URLRequestDestroyed()| has been called.
       OnCallToDelegate(NetLogEventType::NETWORK_DELEGATE_HEADERS_RECEIVED);
-      preserve_fragment_on_redirect_url_ = absl::nullopt;
+      preserve_fragment_on_redirect_url_ = std::nullopt;
       IPEndPoint endpoint;
       if (transaction_)
         transaction_->GetRemoteEndpoint(&endpoint);
diff --git a/net/url_request/url_request_http_job.h b/net/url_request/url_request_http_job.h
index 943ed021..095a3b7 100644
--- a/net/url_request/url_request_http_job.h
+++ b/net/url_request/url_request_http_job.h
@@ -9,6 +9,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -29,7 +30,6 @@
 #include "net/socket/connection_attempts.h"
 #include "net/url_request/url_request_job.h"
 #include "net/url_request/url_request_throttler_entry_interface.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -135,7 +135,7 @@
   void OnReadCompleted(int result);
   void NotifyBeforeStartTransactionCallback(
       int result,
-      const absl::optional<HttpRequestHeaders>& headers);
+      const std::optional<HttpRequestHeaders>& headers);
   // This just forwards the call to URLRequestJob::NotifyConnected().
   // We need it because that method is protected and cannot be bound in a
   // callback in this class.
@@ -195,7 +195,7 @@
 
   // Another Cookie Monster callback
   void OnSetCookieResult(const CookieOptions& options,
-                         absl::optional<CanonicalCookie> cookie,
+                         std::optional<CanonicalCookie> cookie,
                          std::string cookie_string,
                          CookieAccessResult access_result);
   int num_cookie_lines_left_ = 0;
@@ -274,12 +274,12 @@
   // Ordinarily the original URL's fragment is copied during redirects, unless
   // the destination URL already has one. However, the NetworkDelegate can
   // override this behavior by setting |preserve_fragment_on_redirect_url_|:
-  // * If set to absl::nullopt, the default behavior is used.
+  // * If set to std::nullopt, the default behavior is used.
   // * If the final URL in the redirect chain matches
   //     |preserve_fragment_on_redirect_url_|, its fragment unchanged. So this
   //     is basically a way for the embedder to force a redirect not to copy the
   //     original URL's fragment when the original URL had one.
-  absl::optional<GURL> preserve_fragment_on_redirect_url_;
+  std::optional<GURL> preserve_fragment_on_redirect_url_;
 
   // Flag used to verify that |this| is not deleted while we are awaiting
   // a callback from the NetworkDelegate. Used as a fail-fast mechanism.
diff --git a/net/url_request/url_request_http_job_unittest.cc b/net/url_request/url_request_http_job_unittest.cc
index fd0a072..b425b37 100644
--- a/net/url_request/url_request_http_job_unittest.cc
+++ b/net/url_request/url_request_http_job_unittest.cc
@@ -1268,8 +1268,8 @@
     EXPECT_TRUE(delegate.redirect_info().new_url.SchemeIs("https"));
     EXPECT_THAT(delegate.request_status(), net::ERR_IO_PENDING);
 
-    req->FollowDeferredRedirect(absl::nullopt /* removed_headers */,
-                                absl::nullopt /* modified_headers */);
+    req->FollowDeferredRedirect(std::nullopt /* removed_headers */,
+                                std::nullopt /* modified_headers */);
     delegate.RunUntilComplete();
     EXPECT_EQ(kSecureContent, delegate.data_received());
     EXPECT_FALSE(req->was_cached());
@@ -1317,8 +1317,8 @@
 
     raw_req_headers = HttpRawRequestHeaders();
 
-    r->FollowDeferredRedirect(absl::nullopt /* removed_headers */,
-                              absl::nullopt /* modified_headers */);
+    r->FollowDeferredRedirect(std::nullopt /* removed_headers */,
+                              std::nullopt /* modified_headers */);
     delegate.RunUntilComplete();
 
     EXPECT_FALSE(raw_req_headers.headers().empty());
@@ -1665,8 +1665,8 @@
                         const GURL& url,
                         const std::string& cookie_line) {
   auto cookie = CanonicalCookie::Create(
-      url, cookie_line, base::Time::Now(), absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */);
+      url, cookie_line, base::Time::Now(), std::nullopt /* server_time */,
+      std::nullopt /* cookie_partition_key */);
   if (!cookie)
     return false;
   DCHECK(cs);
@@ -1717,8 +1717,7 @@
   // would normally only happen during an existing cookie DB version upgrade.
   std::unique_ptr<CanonicalCookie> unset_cookie1 = CanonicalCookie::Create(
       secure_url_for_unset1, "NoSourceSchemeHttps=val", base::Time::Now(),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */);
   unset_cookie1->SetSourceScheme(net::CookieSourceScheme::kUnset);
 
   CookieList list1 = {*unset_cookie1};
@@ -1738,8 +1737,7 @@
 
   std::unique_ptr<CanonicalCookie> unset_cookie2 = CanonicalCookie::Create(
       nonsecure_url_for_unset2, "NoSourceSchemeHttp=val", base::Time::Now(),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */);
   unset_cookie2->SetSourceScheme(net::CookieSourceScheme::kUnset);
 
   CookieList list2 = {*unset_cookie2};
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc
index dc6605d..e221b9dc 100644
--- a/net/url_request/url_request_job.cc
+++ b/net/url_request/url_request_job.cc
@@ -88,9 +88,9 @@
 URLRequestJob::URLRequestJob(URLRequest* request)
     : request_(request),
       request_initiator_site_(request->initiator().has_value()
-                                  ? absl::make_optional(net::SchemefulSite(
+                                  ? std::make_optional(net::SchemefulSite(
                                         request->initiator().value()))
-                                  : absl::nullopt) {}
+                                  : std::nullopt) {}
 
 URLRequestJob::~URLRequestJob() = default;
 
@@ -236,14 +236,14 @@
 }
 
 void URLRequestJob::FollowDeferredRedirect(
-    const absl::optional<std::vector<std::string>>& removed_headers,
-    const absl::optional<net::HttpRequestHeaders>& modified_headers) {
+    const std::optional<std::vector<std::string>>& removed_headers,
+    const std::optional<net::HttpRequestHeaders>& modified_headers) {
   // OnReceivedRedirect must have been called.
   DCHECK(deferred_redirect_info_);
 
   // It is possible that FollowRedirect will delete |this|, so it is not safe to
   // pass along a reference to |deferred_redirect_info_|.
-  absl::optional<RedirectInfo> redirect_info =
+  std::optional<RedirectInfo> redirect_info =
       std::move(deferred_redirect_info_);
   FollowRedirect(*redirect_info, removed_headers, modified_headers);
 }
@@ -469,8 +469,8 @@
     if (defer_redirect) {
       deferred_redirect_info_ = std::move(redirect_info);
     } else {
-      FollowRedirect(redirect_info, absl::nullopt, /*  removed_headers */
-                     absl::nullopt /* modified_headers */);
+      FollowRedirect(redirect_info, std::nullopt, /*  removed_headers */
+                     std::nullopt /* modified_headers */);
     }
     return;
   }
@@ -728,8 +728,8 @@
 
 void URLRequestJob::FollowRedirect(
     const RedirectInfo& redirect_info,
-    const absl::optional<std::vector<std::string>>& removed_headers,
-    const absl::optional<net::HttpRequestHeaders>& modified_headers) {
+    const std::optional<std::vector<std::string>>& removed_headers,
+    const std::optional<net::HttpRequestHeaders>& modified_headers) {
   request_->Redirect(redirect_info, removed_headers, modified_headers);
 }
 
diff --git a/net/url_request/url_request_job.h b/net/url_request/url_request_job.h
index 4fd5998..d70c299 100644
--- a/net/url_request/url_request_job.h
+++ b/net/url_request/url_request_job.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -30,7 +31,6 @@
 #include "net/url_request/redirect_info.h"
 #include "net/url_request/referrer_policy.h"
 #include "net/url_request/url_request.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace net {
@@ -196,8 +196,8 @@
   virtual void ContinueDespiteLastError();
 
   void FollowDeferredRedirect(
-      const absl::optional<std::vector<std::string>>& removed_headers,
-      const absl::optional<net::HttpRequestHeaders>& modified_headers);
+      const std::optional<std::vector<std::string>>& removed_headers,
+      const std::optional<net::HttpRequestHeaders>& modified_headers);
 
   // Returns true if the Job is done producing response data and has called
   // NotifyDone on the request.
@@ -360,7 +360,7 @@
   // On return, |this| may be deleted.
   void ReadRawDataComplete(int bytes_read);
 
-  const absl::optional<net::SchemefulSite>& request_initiator_site() const {
+  const std::optional<net::SchemefulSite>& request_initiator_site() const {
     return request_initiator_site_;
   }
 
@@ -390,8 +390,8 @@
   // given redirect destination.
   void FollowRedirect(
       const RedirectInfo& redirect_info,
-      const absl::optional<std::vector<std::string>>& removed_headers,
-      const absl::optional<net::HttpRequestHeaders>& modified_headers);
+      const std::optional<std::vector<std::string>>& removed_headers,
+      const std::optional<net::HttpRequestHeaders>& modified_headers);
 
   // Called after every raw read. If |bytes_read| is > 0, this indicates
   // a successful read of |bytes_read| unfiltered bytes. If |bytes_read|
@@ -448,12 +448,12 @@
 
   // Set when a redirect is deferred. Redirects are deferred after validity
   // checks are performed, so this field must not be modified.
-  absl::optional<RedirectInfo> deferred_redirect_info_;
+  std::optional<RedirectInfo> deferred_redirect_info_;
 
   // The request's initiator never changes, so we store it in format of
   // SchemefulSite so that we don't recompute (including looking up the
   // registrable domain) it during every redirect.
-  absl::optional<net::SchemefulSite> request_initiator_site_;
+  std::optional<net::SchemefulSite> request_initiator_site_;
 
   // Non-null if ReadRawData() returned ERR_IO_PENDING, and the read has not
   // completed.
diff --git a/net/url_request/url_request_job_unittest.cc b/net/url_request/url_request_job_unittest.cc
index 09c7385..e75f9bc 100644
--- a/net/url_request/url_request_job_unittest.cc
+++ b/net/url_request/url_request_job_unittest.cc
@@ -5,6 +5,7 @@
 #include "net/url_request/url_request_job.h"
 
 #include <memory>
+#include <optional>
 
 #include "base/functional/bind.h"
 #include "base/run_loop.h"
@@ -25,7 +26,6 @@
 #include "net/url_request/url_request_test_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/url_util.h"
 
 using net::test::IsError;
@@ -120,8 +120,8 @@
     base::Time(),
     "hello",
     {},
-    absl::nullopt,
-    absl::nullopt,
+    std::nullopt,
+    std::nullopt,
     TEST_MODE_NORMAL,
     MockTransactionHandler(),
     MockTransactionReadHandler(),
@@ -144,8 +144,8 @@
     base::Time(),
     "hello",
     {},
-    absl::nullopt,
-    absl::nullopt,
+    std::nullopt,
+    std::nullopt,
     TEST_MODE_NORMAL,
     MockTransactionHandler(),
     MockTransactionReadHandler(),
@@ -169,8 +169,8 @@
     base::Time(),
     "",
     {},
-    absl::nullopt,
-    absl::nullopt,
+    std::nullopt,
+    std::nullopt,
     TEST_MODE_NORMAL,
     base::BindRepeating(&GZipServer),
     MockTransactionReadHandler(),
@@ -194,8 +194,8 @@
     base::Time(),
     "",
     {},
-    absl::nullopt,
-    absl::nullopt,
+    std::nullopt,
+    std::nullopt,
     TEST_MODE_SLOW_READ,
     base::BindRepeating(&GZipHelloServer),
     MockTransactionReadHandler(),
@@ -220,8 +220,8 @@
     base::Time(),
     "hello",
     {},
-    absl::nullopt,
-    absl::nullopt,
+    std::nullopt,
+    std::nullopt,
     TEST_MODE_NORMAL,
     MockTransactionHandler(),
     MockTransactionReadHandler(),
@@ -244,8 +244,8 @@
     base::Time(),
     "",
     {},
-    absl::nullopt,
-    absl::nullopt,
+    std::nullopt,
+    std::nullopt,
     TEST_MODE_NORMAL,
     MockTransactionHandler(),
     MockTransactionReadHandler(),
@@ -269,8 +269,8 @@
     base::Time(),
     "not a valid gzip body",
     {},
-    absl::nullopt,
-    absl::nullopt,
+    std::nullopt,
+    std::nullopt,
     TEST_MODE_NORMAL,
     MockTransactionHandler(),
     MockTransactionReadHandler(),
@@ -295,8 +295,8 @@
     base::Time(),
     "",
     {},
-    absl::nullopt,
-    absl::nullopt,
+    std::nullopt,
+    std::nullopt,
     TEST_MODE_SLOW_READ,
     base::BindRepeating(&BrotliHelloServer),
     MockTransactionReadHandler(),
diff --git a/net/url_request/url_request_netlog_params.cc b/net/url_request/url_request_netlog_params.cc
index 323b62f..6299134 100644
--- a/net/url_request/url_request_netlog_params.cc
+++ b/net/url_request/url_request_netlog_params.cc
@@ -33,7 +33,7 @@
     int load_flags,
     const IsolationInfo& isolation_info,
     const SiteForCookies& site_for_cookies,
-    const absl::optional<url::Origin>& initiator,
+    const std::optional<url::Origin>& initiator,
     int64_t upload_id) {
   base::Value::Dict dict;
   dict.Set("url", url.possibly_invalid_spec());
diff --git a/net/url_request/url_request_netlog_params.h b/net/url_request/url_request_netlog_params.h
index dfb13f4..c11a068 100644
--- a/net/url_request/url_request_netlog_params.h
+++ b/net/url_request/url_request_netlog_params.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "base/values.h"
@@ -17,7 +18,6 @@
 #include "net/base/request_priority.h"
 #include "net/log/net_log_capture_mode.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class GURL;
 
@@ -42,7 +42,7 @@
     int load_flags,
     const IsolationInfo& isolation_info,
     const SiteForCookies& site_for_cookies,
-    const absl::optional<url::Origin>& initiator,
+    const std::optional<url::Origin>& initiator,
     int64_t upload_id);
 
 }  // namespace net
diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc
index 297905b..e025824 100644
--- a/net/url_request/url_request_test_util.cc
+++ b/net/url_request/url_request_test_util.cc
@@ -357,7 +357,7 @@
     const HttpResponseHeaders* original_response_headers,
     scoped_refptr<HttpResponseHeaders>* override_response_headers,
     const IPEndPoint& endpoint,
-    absl::optional<GURL>* preserve_fragment_on_redirect_url) {
+    std::optional<GURL>* preserve_fragment_on_redirect_url) {
   EXPECT_FALSE(preserve_fragment_on_redirect_url->has_value());
   int req_id = GetRequestId(request);
   bool is_first_response =
@@ -385,7 +385,7 @@
 
     redirect_on_headers_received_url_ = GURL();
 
-    // Since both values are absl::optionals, can just copy this over.
+    // Since both values are std::optionals, can just copy this over.
     *preserve_fragment_on_redirect_url = preserve_fragment_on_redirect_url_;
   } else if (add_header_to_first_response_ && is_first_response) {
     *override_response_headers = base::MakeRefCounted<HttpResponseHeaders>(
diff --git a/net/url_request/url_request_test_util.h b/net/url_request/url_request_test_util.h
index 0fdcd605..575a510 100644
--- a/net/url_request/url_request_test_util.h
+++ b/net/url_request/url_request_test_util.h
@@ -10,6 +10,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -47,7 +48,6 @@
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "net/url_request/url_request_interceptor.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/url_util.h"
 
 namespace net {
@@ -251,7 +251,7 @@
   }
 
   void set_preserve_fragment_on_redirect_url(
-      const absl::optional<GURL>& preserve_fragment_on_redirect_url) {
+      const std::optional<GURL>& preserve_fragment_on_redirect_url) {
     preserve_fragment_on_redirect_url_ = preserve_fragment_on_redirect_url;
   }
 
@@ -303,7 +303,7 @@
       const HttpResponseHeaders* original_response_headers,
       scoped_refptr<HttpResponseHeaders>* override_response_headers,
       const IPEndPoint& endpoint,
-      absl::optional<GURL>* preserve_fragment_on_redirect_url) override;
+      std::optional<GURL>* preserve_fragment_on_redirect_url) override;
   void OnBeforeRedirect(URLRequest* request, const GURL& new_location) override;
   void OnResponseStarted(URLRequest* request, int net_error) override;
   void OnCompleted(URLRequest* request, bool started, int net_error) override;
@@ -339,7 +339,7 @@
   GURL redirect_on_headers_received_url_;
   // URL to mark as retaining its fragment if redirected to at the
   // OnHeadersReceived() stage.
-  absl::optional<GURL> preserve_fragment_on_redirect_url_;
+  std::optional<GURL> preserve_fragment_on_redirect_url_;
 
   int last_error_ = 0;
   int error_count_ = 0;
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index fa39f0d..562ef14 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -2,12 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "net/url_request/url_request.h"
+
 #include <stdint.h>
 
 #include <algorithm>
 #include <iterator>
 #include <limits>
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "base/base64url.h"
@@ -134,7 +137,6 @@
 #include "net/url_request/redirect_util.h"
 #include "net/url_request/referrer_policy.h"
 #include "net/url_request/static_http_user_agent_settings.h"
-#include "net/url_request/url_request.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_builder.h"
 #include "net/url_request/url_request_filter.h"
@@ -148,7 +150,6 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/boringssl/src/include/openssl/ssl.h"
 #include "url/url_constants.h"
 #include "url/url_util.h"
@@ -427,7 +428,7 @@
       const HttpResponseHeaders* original_response_headers,
       scoped_refptr<HttpResponseHeaders>* override_response_headers,
       const IPEndPoint& endpoint,
-      absl::optional<GURL>* preserve_fragment_on_redirect_url) override;
+      std::optional<GURL>* preserve_fragment_on_redirect_url) override;
 
   // Resets the callbacks and |stage_blocked_for_callback_|.
   void Reset();
@@ -523,7 +524,7 @@
       ON_BEFORE_SEND_HEADERS,
       base::BindOnce(
           [](OnBeforeStartTransactionCallback callback, int result) {
-            std::move(callback).Run(result, absl::nullopt);
+            std::move(callback).Run(result, std::nullopt);
           },
           std::move(callback)));
 }
@@ -534,7 +535,7 @@
     const HttpResponseHeaders* original_response_headers,
     scoped_refptr<HttpResponseHeaders>* override_response_headers,
     const IPEndPoint& endpoint,
-    absl::optional<GURL>* preserve_fragment_on_redirect_url) {
+    std::optional<GURL>* preserve_fragment_on_redirect_url) {
   // TestNetworkDelegate always completes synchronously.
   CHECK_NE(ERR_IO_PENDING,
            TestNetworkDelegate::OnHeadersReceived(
@@ -867,8 +868,8 @@
       static_cast<int>(
           ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE),
       1);
-  req->FollowDeferredRedirect(/*removed_headers=*/absl::nullopt,
-                              /*modified_headers=*/absl::nullopt);
+  req->FollowDeferredRedirect(/*removed_headers=*/std::nullopt,
+                              /*modified_headers=*/std::nullopt);
   d.RunUntilComplete();
   histograms.ExpectUniqueSample(
       "Net.URLRequest.ReferrerPolicyForRequest.CrossOrigin",
@@ -903,8 +904,8 @@
       "Net.URLRequest.ReferrerHasInformativePath.SameOrigin",
       /* Check the count of the "true" bucket in the boolean histogram. */ true,
       1);
-  req->FollowDeferredRedirect(/*removed_headers=*/absl::nullopt,
-                              /*modified_headers=*/absl::nullopt);
+  req->FollowDeferredRedirect(/*removed_headers=*/std::nullopt,
+                              /*modified_headers=*/std::nullopt);
   d.RunUntilComplete();
   histograms.ExpectUniqueSample(
       "Net.URLRequest.ReferrerHasInformativePath.CrossOrigin", true, 1);
@@ -936,8 +937,8 @@
       "Net.URLRequest.ReferrerHasInformativePath.SameOrigin",
       /* Check the count of the "true" bucket in the boolean histogram. */ true,
       1);
-  req->FollowDeferredRedirect(/*removed_headers=*/absl::nullopt,
-                              /*modified_headers=*/absl::nullopt);
+  req->FollowDeferredRedirect(/*removed_headers=*/std::nullopt,
+                              /*modified_headers=*/std::nullopt);
   d.RunUntilComplete();
   histograms.ExpectUniqueSample(
       "Net.URLRequest.ReferrerHasInformativePath.CrossOrigin", true, 1);
@@ -967,8 +968,8 @@
   d.RunUntilRedirect();
   histograms.ExpectUniqueSample(
       "Net.URLRequest.ReferrerHasInformativePath.CrossOrigin", false, 1);
-  req->FollowDeferredRedirect(/*removed_headers=*/absl::nullopt,
-                              /*modified_headers=*/absl::nullopt);
+  req->FollowDeferredRedirect(/*removed_headers=*/std::nullopt,
+                              /*modified_headers=*/std::nullopt);
   d.RunUntilComplete();
   histograms.ExpectUniqueSample(
       "Net.URLRequest.ReferrerHasInformativePath.SameOrigin", false, 1);
@@ -1430,8 +1431,8 @@
 
   EXPECT_EQ(d.received_redirect_count(), 1);
 
-  req->FollowDeferredRedirect(/*removed_headers=*/absl::nullopt,
-                              /*modified_headers=*/absl::nullopt);
+  req->FollowDeferredRedirect(/*removed_headers=*/std::nullopt,
+                              /*modified_headers=*/std::nullopt);
   d.RunUntilComplete();
 
   EXPECT_EQ(0, network_delegate.error_count());
@@ -1973,8 +1974,7 @@
 
   auto cookie1 = CanonicalCookie::Create(
       url, "AlreadySetCookie=1;Secure", base::Time::Now(),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */);
   auto delayed_cm = std::make_unique<DelayedCookieMonster>();
   delayed_cm->SetCanonicalCookieAsync(std::move(cookie1), url,
                                       net::CookieOptions::MakeAllInclusive(),
@@ -1982,8 +1982,7 @@
 
   auto cookie2 = CanonicalCookie::Create(
       url, "AlreadySetCookie=1;Secure", base::Time::Now(),
-      absl::nullopt /* server_time */,
-      absl::nullopt /* cookie_partition_key */);
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */);
   auto cm = std::make_unique<CookieMonster>(nullptr, nullptr);
   cm->SetCanonicalCookieAsync(std::move(cookie2), url,
                               net::CookieOptions::MakeAllInclusive(),
@@ -3558,7 +3557,7 @@
   {
     auto same_site_partitioned_cookie = CanonicalCookie::Create(
         create_cookie_url, "samesite_partitioned=1;Secure;Partitioned",
-        base::Time::Now(), absl::nullopt,
+        base::Time::Now(), std::nullopt,
         CookiePartitionKey::FromURLForTesting(create_cookie_url));
     ASSERT_TRUE(same_site_partitioned_cookie);
     ASSERT_TRUE(same_site_partitioned_cookie->IsPartitioned());
@@ -3575,7 +3574,7 @@
   {
     auto cross_site_partitioned_cookie = CanonicalCookie::Create(
         create_cookie_url, "xsite_partitioned=1;Secure;Partitioned",
-        base::Time::Now(), absl::nullopt,
+        base::Time::Now(), std::nullopt,
         CookiePartitionKey::FromURLForTesting(
             https_server.GetURL(kCrossSiteHost, "/")));
     ASSERT_TRUE(cross_site_partitioned_cookie);
@@ -3789,7 +3788,7 @@
       const HttpResponseHeaders* original_response_headers,
       scoped_refptr<HttpResponseHeaders>* override_response_headers,
       const IPEndPoint& endpoint,
-      absl::optional<GURL>* preserve_fragment_on_redirect_url) override;
+      std::optional<GURL>* preserve_fragment_on_redirect_url) override;
 
  private:
   std::string fixed_date_;
@@ -3801,7 +3800,7 @@
     const HttpResponseHeaders* original_response_headers,
     scoped_refptr<HttpResponseHeaders>* override_response_headers,
     const IPEndPoint& endpoint,
-    absl::optional<GURL>* preserve_fragment_on_redirect_url) {
+    std::optional<GURL>* preserve_fragment_on_redirect_url) {
   *override_response_headers = base::MakeRefCounted<HttpResponseHeaders>(
       original_response_headers->raw_headers());
 
@@ -4384,8 +4383,8 @@
     EXPECT_EQ(redirect_url, GURL(location));
 
     // Let the request finish.
-    r->FollowDeferredRedirect(absl::nullopt /* removed_headers */,
-                              absl::nullopt /* modified_headers */);
+    r->FollowDeferredRedirect(std::nullopt /* removed_headers */,
+                              std::nullopt /* modified_headers */);
     d.RunUntilComplete();
     EXPECT_EQ(OK, d.request_status());
     EXPECT_EQ(ProxyChain(ProxyServer::SCHEME_HTTP,
@@ -4436,8 +4435,8 @@
     EXPECT_EQ(redirect_url, GURL(location));
 
     // Let the request finish.
-    r->FollowDeferredRedirect(absl::nullopt /* removed_headers */,
-                              absl::nullopt /* modified_headers */);
+    r->FollowDeferredRedirect(std::nullopt /* removed_headers */,
+                              std::nullopt /* modified_headers */);
     d.RunUntilComplete();
 
     EXPECT_EQ(OK, d.request_status());
@@ -4495,8 +4494,8 @@
     EXPECT_EQ(redirect_url, GURL(location));
 
     // Let the request finish.
-    r->FollowDeferredRedirect(absl::nullopt /* removed_headers */,
-                              absl::nullopt /* modified_headers */);
+    r->FollowDeferredRedirect(std::nullopt /* removed_headers */,
+                              std::nullopt /* modified_headers */);
     d.RunUntilComplete();
 
     EXPECT_EQ(OK, d.request_status());
@@ -5240,7 +5239,7 @@
     return RunCallbackAsynchronously(
         request, base::BindOnce(
                      [](OnBeforeStartTransactionCallback callback, int result) {
-                       std::move(callback).Run(result, absl::nullopt);
+                       std::move(callback).Run(result, std::nullopt);
                      },
                      std::move(callback)));
   }
@@ -5251,7 +5250,7 @@
       const HttpResponseHeaders* original_response_headers,
       scoped_refptr<HttpResponseHeaders>* override_response_headers,
       const IPEndPoint& endpoint,
-      absl::optional<GURL>* preserve_fragment_on_redirect_url) override {
+      std::optional<GURL>* preserve_fragment_on_redirect_url) override {
     // TestNetworkDelegate always completes synchronously.
     CHECK_NE(ERR_IO_PENDING,
              TestNetworkDelegate::OnHeadersReceived(
@@ -5343,8 +5342,8 @@
     if (cancel_stage_ == CANCEL_ON_RECEIVED_REDIRECT)
       return;
     if (!defer_redirect) {
-      request->FollowDeferredRedirect(absl::nullopt /* removed_headers */,
-                                      absl::nullopt /* modified_headers */);
+      request->FollowDeferredRedirect(std::nullopt /* removed_headers */,
+                                      std::nullopt /* modified_headers */);
     }
   }
 
@@ -6757,8 +6756,8 @@
     EXPECT_EQ(0, d.response_started_count());
     EXPECT_TRUE(req->was_cached());
 
-    req->FollowDeferredRedirect(absl::nullopt /* removed_headers */,
-                                absl::nullopt /* modified_headers */);
+    req->FollowDeferredRedirect(std::nullopt /* removed_headers */,
+                                std::nullopt /* modified_headers */);
     d.RunUntilComplete();
     EXPECT_EQ(1, d.received_redirect_count());
     EXPECT_EQ(1, d.response_started_count());
@@ -7032,8 +7031,8 @@
 
     EXPECT_EQ(1, d.received_redirect_count());
 
-    req->FollowDeferredRedirect(absl::nullopt /* removed_headers */,
-                                absl::nullopt /* modified_headers */);
+    req->FollowDeferredRedirect(std::nullopt /* removed_headers */,
+                                std::nullopt /* modified_headers */);
     d.RunUntilComplete();
 
     EXPECT_EQ(1, d.response_started_count());
@@ -7086,7 +7085,7 @@
     modified_headers.SetHeader("Header2", "");
     modified_headers.SetHeader("Header3", "Value3");
 
-    req->FollowDeferredRedirect(absl::nullopt /* removed_headers */,
+    req->FollowDeferredRedirect(std::nullopt /* removed_headers */,
                                 modified_headers);
     d.RunUntilComplete();
 
@@ -7135,7 +7134,7 @@
     // Keep Header1 and remove Header2.
     std::vector<std::string> removed_headers({"Header2"});
     req->FollowDeferredRedirect(removed_headers,
-                                absl::nullopt /* modified_headers */);
+                                std::nullopt /* modified_headers */);
     d.RunUntilComplete();
 
     EXPECT_EQ(1, d.response_started_count());
@@ -7766,8 +7765,8 @@
   {
     GURL url = test_server.GetURL("/");
     auto cookie1 = CanonicalCookie::Create(
-        url, "cookienosamesite=1", base::Time::Now(), absl::nullopt,
-        absl::nullopt /* cookie_partition_key */);
+        url, "cookienosamesite=1", base::Time::Now(), std::nullopt,
+        std::nullopt /* cookie_partition_key */);
     base::RunLoop run_loop;
     CookieAccessResult access_result;
     cm.SetCanonicalCookieAsync(
@@ -7809,8 +7808,8 @@
   {
     GURL url = test_server.GetURL("/");
     auto cookie2 = CanonicalCookie::Create(
-        url, "cookiewithpath=1;path=/foo", base::Time::Now(), absl::nullopt,
-        absl::nullopt /* cookie_partition_key */);
+        url, "cookiewithpath=1;path=/foo", base::Time::Now(), std::nullopt,
+        std::nullopt /* cookie_partition_key */);
     base::RunLoop run_loop;
     // Note: cookie1 from the previous testcase is still in the cookie store.
     CookieAccessResult access_result;
@@ -7956,8 +7955,8 @@
     auto* cm = static_cast<CookieMonster*>(context->cookie_store());
     auto another_cookie = CanonicalCookie::Create(
         url_requiring_auth_wo_cookies, "another_cookie=true", base::Time::Now(),
-        absl::nullopt /* server_time */,
-        absl::nullopt /* cookie_partition_key */);
+        std::nullopt /* server_time */,
+        std::nullopt /* cookie_partition_key */);
     cm->SetCanonicalCookieAsync(std::move(another_cookie),
                                 url_requiring_auth_wo_cookies,
                                 net::CookieOptions::MakeAllInclusive(),
@@ -7986,8 +7985,8 @@
     cm->DeleteAllAsync(CookieStore::DeleteCallback());
     auto one_more_cookie = CanonicalCookie::Create(
         url_requiring_auth_wo_cookies, "one_more_cookie=true",
-        base::Time::Now(), absl::nullopt /* server_time */,
-        absl::nullopt /* cookie_partition_key */);
+        base::Time::Now(), std::nullopt /* server_time */,
+        std::nullopt /* cookie_partition_key */);
     cm->SetCanonicalCookieAsync(std::move(one_more_cookie),
                                 url_requiring_auth_wo_cookies,
                                 net::CookieOptions::MakeAllInclusive(),
@@ -8342,7 +8341,7 @@
 
     // Check maybe_stored_cookies on second round trip (and clearing from the
     // first).
-    request->FollowDeferredRedirect(absl::nullopt, absl::nullopt);
+    request->FollowDeferredRedirect(std::nullopt, std::nullopt);
     delegate.RunUntilComplete();
     EXPECT_THAT(delegate.request_status(), IsOk());
 
@@ -8377,8 +8376,8 @@
     auto* cm = static_cast<CookieMonster*>(context->cookie_store());
     auto another_cookie = CanonicalCookie::Create(
         original_url, "another_cookie=true", base::Time::Now(),
-        absl::nullopt /* server_time */,
-        absl::nullopt /* cookie_partition_key */);
+        std::nullopt /* server_time */,
+        std::nullopt /* cookie_partition_key */);
     cm->SetCanonicalCookieAsync(std::move(another_cookie), original_url,
                                 net::CookieOptions::MakeAllInclusive(),
                                 CookieStore::SetCookiesCallback());
@@ -8404,14 +8403,14 @@
     cm->DeleteAllAsync(CookieStore::DeleteCallback());
     auto one_more_cookie = CanonicalCookie::Create(
         original_url_wo_cookie, "one_more_cookie=true", base::Time::Now(),
-        absl::nullopt /* server_time */,
-        absl::nullopt /* cookie_partition_key */);
+        std::nullopt /* server_time */,
+        std::nullopt /* cookie_partition_key */);
     cm->SetCanonicalCookieAsync(std::move(one_more_cookie),
                                 original_url_wo_cookie,
                                 net::CookieOptions::MakeAllInclusive(),
                                 CookieStore::SetCookiesCallback());
 
-    request->FollowDeferredRedirect(absl::nullopt, absl::nullopt);
+    request->FollowDeferredRedirect(std::nullopt, std::nullopt);
     delegate.RunUntilComplete();
     EXPECT_THAT(delegate.request_status(), IsOk());
 
@@ -8759,8 +8758,8 @@
       std::make_unique<TestScopedURLInterceptor>(redirect_url, std::move(job));
 
   // Should trigger |job| to be started.
-  req->FollowDeferredRedirect(absl::nullopt /* removed_headers */,
-                              absl::nullopt /* modified_headers */);
+  req->FollowDeferredRedirect(std::nullopt /* removed_headers */,
+                              std::nullopt /* modified_headers */);
   d.RunUntilComplete();
   EXPECT_EQ(LOW, job_priority);
 }
@@ -11904,8 +11903,8 @@
 
   raw_req_headers = HttpRawRequestHeaders();
   raw_resp_headers = nullptr;
-  r->FollowDeferredRedirect(absl::nullopt /* removed_headers */,
-                            absl::nullopt /* modified_headers */);
+  r->FollowDeferredRedirect(std::nullopt /* removed_headers */,
+                            std::nullopt /* modified_headers */);
   delegate.RunUntilComplete();
   EXPECT_TRUE(raw_req_headers.FindHeaderForTest("X-Foo", &value));
   EXPECT_EQ("bar", value);
diff --git a/net/websockets/websocket_basic_handshake_stream.cc b/net/websockets/websocket_basic_handshake_stream.cc
index 8c3fc76..854aa2a 100644
--- a/net/websockets/websocket_basic_handshake_stream.cc
+++ b/net/websockets/websocket_basic_handshake_stream.cc
@@ -491,7 +491,7 @@
         // helpful, so use a different error message.
         if (headers->GetHttpVersion() == HttpVersion(0, 9)) {
           OnFailure("Error during WebSocket handshake: Invalid status line",
-                    ERR_FAILED, absl::nullopt);
+                    ERR_FAILED, std::nullopt);
         } else {
           OnFailure(base::StringPrintf("Error during WebSocket handshake: "
                                        "Unexpected response code: %d",
@@ -504,13 +504,13 @@
   } else {
     if (rv == ERR_EMPTY_RESPONSE) {
       OnFailure("Connection closed before receiving a handshake response", rv,
-                absl::nullopt);
+                std::nullopt);
       result_ = HandshakeResult::EMPTY_RESPONSE;
       return rv;
     }
     OnFailure(
         base::StrCat({"Error during WebSocket handshake: ", ErrorToString(rv)}),
-        rv, absl::nullopt);
+        rv, std::nullopt);
     // Some error codes (for example ERR_CONNECTION_CLOSED) get changed to OK at
     // higher levels. To prevent an unvalidated connection getting erroneously
     // upgraded, don't pass through the status code unchanged if it is
@@ -550,14 +550,14 @@
     return OK;
   }
   OnFailure("Error during WebSocket handshake: " + failure_message, ERR_FAILED,
-            absl::nullopt);
+            std::nullopt);
   return ERR_INVALID_RESPONSE;
 }
 
 void WebSocketBasicHandshakeStream::OnFailure(
     const std::string& message,
     int net_error,
-    absl::optional<int> response_code) {
+    std::optional<int> response_code) {
   net_log_.AddEvent(net::NetLogEventType::WEBSOCKET_UPGRADE_FAILURE,
                     [&] { return NetLogFailureParam(net_error, message); });
   // Avoid connection reuse if auth did not happen.
diff --git a/net/websockets/websocket_basic_handshake_stream.h b/net/websockets/websocket_basic_handshake_stream.h
index dbde35e..8665e25 100644
--- a/net/websockets/websocket_basic_handshake_stream.h
+++ b/net/websockets/websocket_basic_handshake_stream.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
@@ -22,7 +23,6 @@
 #include "net/log/net_log_with_source.h"
 #include "net/websockets/websocket_handshake_stream_base.h"
 #include "net/websockets/websocket_stream.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace net {
@@ -127,7 +127,7 @@
 
   void OnFailure(const std::string& message,
                  int net_error,
-                 absl::optional<int> response_code);
+                 std::optional<int> response_code);
 
   HttpStreamParser* parser() const { return state_.parser(); }
 
@@ -149,7 +149,7 @@
 
   // The key to be sent in the next Sec-WebSocket-Key header. Usually NULL (the
   // key is generated on the fly).
-  absl::optional<std::string> handshake_challenge_for_testing_;
+  std::optional<std::string> handshake_challenge_for_testing_;
 
   // The required value for the Sec-WebSocket-Accept header.
   std::string handshake_challenge_response_;
diff --git a/net/websockets/websocket_basic_stream_test.cc b/net/websockets/websocket_basic_stream_test.cc
index 5e5e44804..1b6797a 100644
--- a/net/websockets/websocket_basic_stream_test.cc
+++ b/net/websockets/websocket_basic_stream_test.cc
@@ -13,6 +13,7 @@
 #include <string.h>  // for memcpy() and memset().
 
 #include <iterator>
+#include <optional>
 #include <utility>
 
 #include "base/big_endian.h"
@@ -36,7 +37,6 @@
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/scheme_host_port.h"
 #include "url/url_constants.h"
 
@@ -166,7 +166,7 @@
         PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
         SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false);
     transport_socket->Init(
-        group_id, null_params, absl::nullopt /* proxy_annotation_tag */, MEDIUM,
+        group_id, null_params, std::nullopt /* proxy_annotation_tag */, MEDIUM,
         SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
         CompletionOnceCallback(), ClientSocketPool::ProxyAuthCallback(), &pool_,
         NetLogWithSource());
diff --git a/net/websockets/websocket_channel.cc b/net/websockets/websocket_channel.cc
index f9eca41..a12711e4 100644
--- a/net/websockets/websocket_channel.cc
+++ b/net/websockets/websocket_channel.cc
@@ -212,7 +212,7 @@
 
   void OnFailure(const std::string& message,
                  int net_error,
-                 absl::optional<int> response_code) override {
+                 std::optional<int> response_code) override {
     creator_->OnConnectFailure(message, net_error, response_code);
     // |this| has been deleted.
   }
@@ -236,7 +236,7 @@
                      scoped_refptr<HttpResponseHeaders> headers,
                      const IPEndPoint& remote_endpoint,
                      base::OnceCallback<void(const AuthCredentials*)> callback,
-                     absl::optional<AuthCredentials>* credentials) override {
+                     std::optional<AuthCredentials>* credentials) override {
     return creator_->OnAuthRequired(auth_info, std::move(headers),
                                     remote_endpoint, std::move(callback),
                                     credentials);
@@ -440,8 +440,7 @@
   if (!socket_url.SchemeIsWSOrWSS()) {
     // TODO(ricea): Kill the renderer (this error should have been caught by
     // Javascript).
-    event_interface_->OnFailChannel("Invalid scheme", ERR_FAILED,
-                                    absl::nullopt);
+    event_interface_->OnFailChannel("Invalid scheme", ERR_FAILED, std::nullopt);
     // |this| is deleted here.
     return;
   }
@@ -479,7 +478,7 @@
 
 void WebSocketChannel::OnConnectFailure(const std::string& message,
                                         int net_error,
-                                        absl::optional<int> response_code) {
+                                        std::optional<int> response_code) {
   DCHECK_EQ(CONNECTING, state_);
 
   // Copy the message before we delete its owner.
@@ -507,7 +506,7 @@
     scoped_refptr<HttpResponseHeaders> response_headers,
     const IPEndPoint& remote_endpoint,
     base::OnceCallback<void(const AuthCredentials*)> callback,
-    absl::optional<AuthCredentials>* credentials) {
+    std::optional<AuthCredentials>* credentials) {
   return event_interface_->OnAuthRequired(
       auth_info, std::move(response_headers), remote_endpoint,
       std::move(callback), credentials);
@@ -931,7 +930,7 @@
   // handshake.
   stream_->Close();
   SetState(CLOSED);
-  event_interface_->OnFailChannel(message, ERR_FAILED, absl::nullopt);
+  event_interface_->OnFailChannel(message, ERR_FAILED, std::nullopt);
 }
 
 ChannelState WebSocketChannel::SendClose(uint16_t code,
diff --git a/net/websockets/websocket_channel.h b/net/websockets/websocket_channel.h
index 69c65b5..f04e5d9b 100644
--- a/net/websockets/websocket_channel.h
+++ b/net/websockets/websocket_channel.h
@@ -9,6 +9,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -24,7 +25,6 @@
 #include "net/websockets/websocket_event_interface.h"
 #include "net/websockets/websocket_frame.h"
 #include "net/websockets/websocket_stream.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace url {
@@ -212,7 +212,7 @@
   // failure to the event interface. May delete |this|.
   void OnConnectFailure(const std::string& message,
                         int net_error,
-                        absl::optional<int> response_code);
+                        std::optional<int> response_code);
 
   // SSL certificate error callback from
   // WebSocketStream::CreateAndConnectStream(). Forwards the request to the
@@ -230,7 +230,7 @@
                      scoped_refptr<HttpResponseHeaders> response_headers,
                      const IPEndPoint& remote_endpoint,
                      base::OnceCallback<void(const AuthCredentials*)> callback,
-                     absl::optional<AuthCredentials>* credentials);
+                     std::optional<AuthCredentials>* credentials);
 
   // Sets |state_| to |new_state| and updates UMA if necessary.
   void SetState(State new_state);
diff --git a/net/websockets/websocket_channel_test.cc b/net/websockets/websocket_channel_test.cc
index 8454d532..90a34ca 100644
--- a/net/websockets/websocket_channel_test.cc
+++ b/net/websockets/websocket_channel_test.cc
@@ -183,7 +183,7 @@
   MOCK_METHOD0(OnSendDataFrameDone, void(void));          // NOLINT
   MOCK_METHOD0(OnClosingHandshake, void(void));           // NOLINT
   MOCK_METHOD3(OnFailChannel,
-               void(const std::string&, int, absl::optional<int>));  // NOLINT
+               void(const std::string&, int, std::optional<int>));  // NOLINT
   MOCK_METHOD3(OnDropChannel,
                void(bool, uint16_t, const std::string&));  // NOLINT
 
@@ -205,7 +205,7 @@
                      scoped_refptr<HttpResponseHeaders> response_headers,
                      const IPEndPoint& remote_endpoint,
                      base::OnceCallback<void(const AuthCredentials*)> callback,
-                     absl::optional<AuthCredentials>* credentials) override {
+                     std::optional<AuthCredentials>* credentials) override {
     return OnAuthRequiredCalled(std::move(auth_info),
                                 std::move(response_headers), remote_endpoint,
                                 credentials);
@@ -219,7 +219,7 @@
                int(const AuthChallengeInfo&,
                    scoped_refptr<HttpResponseHeaders>,
                    const IPEndPoint&,
-                   absl::optional<AuthCredentials>*));
+                   std::optional<AuthCredentials>*));
 };
 
 // This fake EventInterface is for tests which need a WebSocketEventInterface
@@ -238,7 +238,7 @@
   void OnClosingHandshake() override {}
   void OnFailChannel(const std::string& message,
                      int net_error,
-                     absl::optional<int> response_code) override {}
+                     std::optional<int> response_code) override {}
   void OnDropChannel(bool was_clean,
                      uint16_t code,
                      const std::string& reason) override {}
@@ -254,8 +254,8 @@
                      scoped_refptr<HttpResponseHeaders> response_headers,
                      const IPEndPoint& remote_endpoint,
                      base::OnceCallback<void(const AuthCredentials*)> callback,
-                     absl::optional<AuthCredentials>* credentials) override {
-    *credentials = absl::nullopt;
+                     std::optional<AuthCredentials>* credentials) override {
+    *credentials = std::nullopt;
     return OK;
   }
 };
@@ -1034,7 +1034,7 @@
   CreateChannelAndConnect();
 
   connect_data_.argument_saver.connect_delegate->OnFailure("hello", ERR_FAILED,
-                                                           absl::nullopt);
+                                                           std::nullopt);
 }
 
 TEST_F(WebSocketChannelEventInterfaceTest, NonWebSocketSchemeRejected) {
@@ -1595,7 +1595,7 @@
       url, response_headers, IPEndPoint(), base::Time());
   connect_delegate->OnStartOpeningHandshake(std::move(request_info));
 
-  connect_delegate->OnFailure("bye", ERR_FAILED, absl::nullopt);
+  connect_delegate->OnFailure("bye", ERR_FAILED, std::nullopt);
   base::RunLoop().RunUntilIdle();
 }
 
@@ -2669,7 +2669,7 @@
   const GURL wss_url("wss://example.com/on_auth_required");
   connect_data_.socket_url = wss_url;
   AuthChallengeInfo auth_info;
-  absl::optional<AuthCredentials> credentials;
+  std::optional<AuthCredentials> credentials;
   auto response_headers =
       base::MakeRefCounted<HttpResponseHeaders>("HTTP/1.1 200 OK");
   IPEndPoint remote_endpoint(net::IPAddress(127, 0, 0, 1), 80);
diff --git a/net/websockets/websocket_end_to_end_test.cc b/net/websockets/websocket_end_to_end_test.cc
index cc5f2040..d2bd3f70 100644
--- a/net/websockets/websocket_end_to_end_test.cc
+++ b/net/websockets/websocket_end_to_end_test.cc
@@ -11,6 +11,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -75,7 +76,6 @@
 #include "net/websockets/websocket_event_interface.h"
 #include "net/websockets/websocket_handshake_response_info.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
 #include "url/gurl.h"
 #include "url/origin.h"
@@ -151,7 +151,7 @@
 
   void OnFailChannel(const std::string& message,
                      int net_error,
-                     absl::optional<int> response_code) override;
+                     std::optional<int> response_code) override;
 
   void OnStartOpeningHandshake(
       std::unique_ptr<WebSocketHandshakeRequestInfo> request) override;
@@ -167,7 +167,7 @@
                      scoped_refptr<HttpResponseHeaders> response_headers,
                      const IPEndPoint& remote_endpoint,
                      base::OnceCallback<void(const AuthCredentials*)> callback,
-                     absl::optional<AuthCredentials>* credentials) override;
+                     std::optional<AuthCredentials>* credentials) override;
 
  private:
   void QuitNestedEventLoop();
@@ -225,7 +225,7 @@
 void ConnectTestingEventInterface::OnFailChannel(
     const std::string& message,
     int net_error,
-    absl::optional<int> response_code) {
+    std::optional<int> response_code) {
   failed_ = true;
   failure_message_ = message;
   QuitNestedEventLoop();
@@ -251,8 +251,8 @@
     scoped_refptr<HttpResponseHeaders> response_headers,
     const IPEndPoint& remote_endpoint,
     base::OnceCallback<void(const AuthCredentials*)> callback,
-    absl::optional<AuthCredentials>* credentials) {
-  *credentials = absl::nullopt;
+    std::optional<AuthCredentials>* credentials) {
+  *credentials = std::nullopt;
   return OK;
 }
 
diff --git a/net/websockets/websocket_event_interface.h b/net/websockets/websocket_event_interface.h
index caf5e4e..4391dd1 100644
--- a/net/websockets/websocket_event_interface.h
+++ b/net/websockets/websocket_event_interface.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -15,7 +16,6 @@
 #include "base/functional/callback_forward.h"
 #include "base/memory/scoped_refptr.h"
 #include "net/base/net_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class GURL;
 
@@ -100,13 +100,13 @@
   // |message| is a human readable string describing the failure. (It may be
   // empty.) |net_error| contains the network error code for the failure, which
   // may be |OK| if the failure was at a higher level. |response_code| contains
-  // the HTTP status code that caused the failure, or |absl::nullopt| if the
+  // the HTTP status code that caused the failure, or |std::nullopt| if the
   // attempt didn't get that far.
   //
   // This function deletes the Channel.
   virtual void OnFailChannel(const std::string& message,
                              int net_error,
-                             absl::optional<int> response_code) = 0;
+                             std::optional<int> response_code) = 0;
 
   // Called when the browser starts the WebSocket Opening Handshake.
   virtual void OnStartOpeningHandshake(
@@ -153,7 +153,7 @@
       scoped_refptr<HttpResponseHeaders> response_headers,
       const IPEndPoint& socket_address,
       base::OnceCallback<void(const AuthCredentials*)> callback,
-      absl::optional<AuthCredentials>* credentials) = 0;
+      std::optional<AuthCredentials>* credentials) = 0;
 
  protected:
   WebSocketEventInterface() = default;
diff --git a/net/websockets/websocket_handshake_stream_create_helper_test.cc b/net/websockets/websocket_handshake_stream_create_helper_test.cc
index 0b94dab..d9774df 100644
--- a/net/websockets/websocket_handshake_stream_create_helper_test.cc
+++ b/net/websockets/websocket_handshake_stream_create_helper_test.cc
@@ -4,6 +4,7 @@
 
 #include "net/websockets/websocket_handshake_stream_create_helper.h"
 
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -97,7 +98,6 @@
 #include "net/websockets/websocket_test_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 #include "url/scheme_host_port.h"
@@ -173,7 +173,7 @@
             PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
             SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false),
         scoped_refptr<ClientSocketPool::SocketParams>(),
-        absl::nullopt /* proxy_annotation_tag */, MEDIUM, SocketTag(),
+        std::nullopt /* proxy_annotation_tag */, MEDIUM, SocketTag(),
         ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(),
         ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource());
     return socket_handle;
@@ -195,7 +195,7 @@
       std::unique_ptr<WebSocketHandshakeResponseInfo> response) override {}
   void OnFailure(const std::string& failure_message,
                  int net_error,
-                 absl::optional<int> response_code) override {}
+                 std::optional<int> response_code) override {}
   void OnStartOpeningHandshake(
       std::unique_ptr<WebSocketHandshakeRequestInfo> request) override {}
   void OnSSLCertificateError(
@@ -208,8 +208,8 @@
                      scoped_refptr<HttpResponseHeaders> response_headers,
                      const IPEndPoint& host_port_pair,
                      base::OnceCallback<void(const AuthCredentials*)> callback,
-                     absl::optional<AuthCredentials>* credentials) override {
-    *credentials = absl::nullopt;
+                     std::optional<AuthCredentials>* credentials) override {
+    *credentials = std::nullopt;
     return OK;
   }
 };
@@ -227,7 +227,7 @@
   MOCK_METHOD3(OnFailure,
                void(const std::string& message,
                     int net_error,
-                    absl::optional<int> response_code));
+                    std::optional<int> response_code));
 };
 
 class WebSocketHandshakeStreamCreateHelperTest
diff --git a/net/websockets/websocket_http2_handshake_stream.cc b/net/websockets/websocket_http2_handshake_stream.cc
index 1658511..c87fc5d 100644
--- a/net/websockets/websocket_http2_handshake_stream.cc
+++ b/net/websockets/websocket_http2_handshake_stream.cc
@@ -96,7 +96,7 @@
 
   if (!session_) {
     const int rv = ERR_CONNECTION_CLOSED;
-    OnFailure("Connection closed before sending request.", rv, absl::nullopt);
+    OnFailure("Connection closed before sending request.", rv, std::nullopt);
     return rv;
   }
 
@@ -105,7 +105,7 @@
   IPEndPoint address;
   int result = session_->GetPeerAddress(&address);
   if (result != OK) {
-    OnFailure("Error getting IP address.", result, absl::nullopt);
+    OnFailure("Error getting IP address.", result, std::nullopt);
     return result;
   }
   http_response_info_->remote_endpoint = address;
@@ -324,7 +324,7 @@
     result_ = HandshakeResult::HTTP2_FAILED;
 
   OnFailure(base::StrCat({"Stream closed with error: ", ErrorToString(status)}),
-            status, absl::nullopt);
+            status, std::nullopt);
 
   if (callback_)
     std::move(callback_).Run(status);
@@ -393,14 +393,14 @@
 
   const int rv = ERR_INVALID_RESPONSE;
   OnFailure("Error during WebSocket handshake: " + failure_message, rv,
-            absl::nullopt);
+            std::nullopt);
   return rv;
 }
 
 void WebSocketHttp2HandshakeStream::OnFailure(
     const std::string& message,
     int net_error,
-    absl::optional<int> response_code) {
+    std::optional<int> response_code) {
   stream_request_->OnFailure(message, net_error, response_code);
 }
 
diff --git a/net/websockets/websocket_http2_handshake_stream.h b/net/websockets/websocket_http2_handshake_stream.h
index 0d6ed0d..fe5f3f5a 100644
--- a/net/websockets/websocket_http2_handshake_stream.h
+++ b/net/websockets/websocket_http2_handshake_stream.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
@@ -25,7 +26,6 @@
 #include "net/websockets/websocket_basic_stream_adapters.h"
 #include "net/websockets/websocket_handshake_stream_base.h"
 #include "net/websockets/websocket_stream.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -130,7 +130,7 @@
 
   void OnFailure(const std::string& message,
                  int net_error,
-                 absl::optional<int> response_code);
+                 std::optional<int> response_code);
 
   HandshakeResult result_ = HandshakeResult::HTTP2_INCOMPLETE;
 
diff --git a/net/websockets/websocket_http3_handshake_stream.cc b/net/websockets/websocket_http3_handshake_stream.cc
index d1a0d35..4388025 100644
--- a/net/websockets/websocket_http3_handshake_stream.cc
+++ b/net/websockets/websocket_http3_handshake_stream.cc
@@ -93,7 +93,7 @@
 
   if (!session_) {
     constexpr int rv = ERR_CONNECTION_CLOSED;
-    OnFailure("Connection closed before sending request.", rv, absl::nullopt);
+    OnFailure("Connection closed before sending request.", rv, std::nullopt);
     return rv;
   }
 
@@ -102,7 +102,7 @@
   IPEndPoint address;
   int result = session_->GetPeerAddress(&address);
   if (result != OK) {
-    OnFailure("Error getting IP address.", result, absl::nullopt);
+    OnFailure("Error getting IP address.", result, std::nullopt);
     return result;
   }
   http_response_info_->remote_endpoint = address;
@@ -321,7 +321,7 @@
   }
 
   OnFailure(base::StrCat({"Stream closed with error: ", ErrorToString(status)}),
-            status, absl::nullopt);
+            status, std::nullopt);
 
   if (callback_) {
     std::move(callback_).Run(status);
@@ -380,7 +380,7 @@
 
   const int rv = ERR_INVALID_RESPONSE;
   OnFailure("Error during WebSocket handshake: " + failure_message, rv,
-            absl::nullopt);
+            std::nullopt);
   return rv;
 }
 
@@ -388,7 +388,7 @@
 void WebSocketHttp3HandshakeStream::OnFailure(
     const std::string& message,
     int net_error,
-    absl::optional<int> response_code) {
+    std::optional<int> response_code) {
   stream_request_->OnFailure(message, net_error, response_code);
 }
 
diff --git a/net/websockets/websocket_http3_handshake_stream.h b/net/websockets/websocket_http3_handshake_stream.h
index 2176cb3..def197626 100644
--- a/net/websockets/websocket_http3_handshake_stream.h
+++ b/net/websockets/websocket_http3_handshake_stream.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <vector>
@@ -27,7 +28,6 @@
 #include "net/websockets/websocket_basic_stream_adapters.h"
 #include "net/websockets/websocket_handshake_stream_base.h"
 #include "net/websockets/websocket_stream.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -127,7 +127,7 @@
 
   void OnFailure(const std::string& message,
                  int net_error,
-                 absl::optional<int> response_code);
+                 std::optional<int> response_code);
 
   HandshakeResult result_ = HandshakeResult::HTTP3_INCOMPLETE;
 
diff --git a/net/websockets/websocket_stream.cc b/net/websockets/websocket_stream.cc
index d19bccc..d99a33e 100644
--- a/net/websockets/websocket_stream.cc
+++ b/net/websockets/websocket_stream.cc
@@ -4,6 +4,7 @@
 
 #include "net/websockets/websocket_stream.h"
 
+#include <optional>
 #include <ostream>
 #include <utility>
 
@@ -42,7 +43,6 @@
 #include "net/websockets/websocket_handshake_stream_create_helper.h"
 #include "net/websockets/websocket_http2_handshake_stream.h"
 #include "net/websockets/websocket_http3_handshake_stream.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -175,7 +175,7 @@
 
   void OnFailure(const std::string& message,
                  int net_error,
-                 absl::optional<int> response_code) override {
+                 std::optional<int> response_code) override {
     if (api_delegate_)
       api_delegate_->OnFailure(message, net_error, response_code);
     failure_message_ = message;
@@ -203,13 +203,13 @@
       ReportFailureWithMessage(
           "No handshake stream has been created or handshake stream is already "
           "destroyed.",
-          ERR_FAILED, absl::nullopt);
+          ERR_FAILED, std::nullopt);
       return;
     }
 
     if (!handshake_stream_->CanReadFromStream()) {
       ReportFailureWithMessage("Handshake stream is not readable.",
-                               ERR_CONNECTION_CLOSED, absl::nullopt);
+                               ERR_CONNECTION_CLOSED, std::nullopt);
       return;
     }
 
@@ -241,7 +241,7 @@
     }
   }
 
-  void ReportFailure(int net_error, absl::optional<int> response_code) {
+  void ReportFailure(int net_error, std::optional<int> response_code) {
     DCHECK(timer_);
     timer_->Stop();
     if (failure_message_.empty()) {
@@ -268,7 +268,7 @@
 
   void ReportFailureWithMessage(const std::string& failure_message,
                                 int net_error,
-                                absl::optional<int> response_code) {
+                                std::optional<int> response_code) {
     connect_delegate_->OnFailure(failure_message, net_error, response_code);
   }
 
@@ -308,8 +308,8 @@
 
   // The failure information supplied by WebSocketBasicHandshakeStream, if any.
   std::string failure_message_;
-  absl::optional<int> failure_net_error_;
-  absl::optional<int> failure_response_code_;
+  std::optional<int> failure_net_error_;
+  std::optional<int> failure_response_code_;
 
   // A timer for handshake timeout.
   std::unique_ptr<base::OneShotTimer> timer_;
@@ -389,7 +389,7 @@
 
   if (net_error != OK) {
     DVLOG(3) << "OnResponseStarted (request failed)";
-    owner_->ReportFailure(net_error, absl::nullopt);
+    owner_->ReportFailure(net_error, std::nullopt);
     return;
   }
   const int response_code = request->GetResponseCode();
@@ -401,7 +401,7 @@
       return;
     }
 
-    owner_->ReportFailure(net_error, absl::nullopt);
+    owner_->ReportFailure(net_error, std::nullopt);
     return;
   }
 
@@ -428,7 +428,7 @@
 
 void Delegate::OnAuthRequired(URLRequest* request,
                               const AuthChallengeInfo& auth_info) {
-  absl::optional<AuthCredentials> credentials;
+  std::optional<AuthCredentials> credentials;
   // This base::Unretained(this) relies on an assumption that |callback| can
   // be called called during the opening handshake.
   int rv = owner_->connect_delegate()->OnAuthRequired(
@@ -442,7 +442,7 @@
     return;
   if (rv != OK) {
     request->LogUnblocked();
-    owner_->ReportFailure(rv, absl::nullopt);
+    owner_->ReportFailure(rv, std::nullopt);
     return;
   }
   OnAuthRequiredComplete(request, nullptr);
diff --git a/net/websockets/websocket_stream.h b/net/websockets/websocket_stream.h
index 07c9c7af..c8dc6e1 100644
--- a/net/websockets/websocket_stream.h
+++ b/net/websockets/websocket_stream.h
@@ -6,6 +6,7 @@
 #define NET_WEBSOCKETS_WEBSOCKET_STREAM_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -20,7 +21,6 @@
 #include "net/websockets/websocket_event_interface.h"
 #include "net/websockets/websocket_handshake_request_info.h"
 #include "net/websockets/websocket_handshake_response_info.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class GURL;
 
@@ -77,7 +77,7 @@
       WebSocketHttp3HandshakeStream* handshake_stream) = 0;
   virtual void OnFailure(const std::string& message,
                          int net_error,
-                         absl::optional<int> response_code) = 0;
+                         std::optional<int> response_code) = 0;
 };
 
 // WebSocketStream is a transport-agnostic interface for reading and writing
@@ -113,7 +113,7 @@
     // |message| contains defails of the failure.
     virtual void OnFailure(const std::string& message,
                            int net_error,
-                           absl::optional<int> response_code) = 0;
+                           std::optional<int> response_code) = 0;
 
     // Called when the WebSocket Opening Handshake starts.
     virtual void OnStartOpeningHandshake(
@@ -143,7 +143,7 @@
         scoped_refptr<HttpResponseHeaders> response_headers,
         const IPEndPoint& remote_endpoint,
         base::OnceCallback<void(const AuthCredentials*)> callback,
-        absl::optional<AuthCredentials>* credentials) = 0;
+        std::optional<AuthCredentials>* credentials) = 0;
   };
 
   // Create and connect a WebSocketStream of an appropriate type. The actual
diff --git a/net/websockets/websocket_stream_cookie_test.cc b/net/websockets/websocket_stream_cookie_test.cc
index 7a5a2481..1ee3581 100644
--- a/net/websockets/websocket_stream_cookie_test.cc
+++ b/net/websockets/websocket_stream_cookie_test.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -39,7 +40,6 @@
 #include "net/websockets/websocket_test_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -161,10 +161,9 @@
   base::WeakPtrFactory<bool> weak_set_cookie_result(&set_cookie_result);
 
   base::RunLoop run_loop;
-  auto cookie =
-      CanonicalCookie::Create(cookie_url, cookie_line, base::Time::Now(),
-                              absl::nullopt /* server_time */,
-                              absl::nullopt /* cookie_partition_key */);
+  auto cookie = CanonicalCookie::Create(
+      cookie_url, cookie_line, base::Time::Now(),
+      std::nullopt /* server_time */, std::nullopt /* cookie_partition_key */);
   store->SetCanonicalCookieAsync(
       std::move(cookie), cookie_url, net::CookieOptions::MakeAllInclusive(),
       base::BindOnce(&SetCookieHelperFunction, run_loop.QuitClosure(),
diff --git a/net/websockets/websocket_stream_create_test_base.cc b/net/websockets/websocket_stream_create_test_base.cc
index 4b4d525f..19d49e0 100644
--- a/net/websockets/websocket_stream_create_test_base.cc
+++ b/net/websockets/websocket_stream_create_test_base.cc
@@ -57,7 +57,7 @@
 
   void OnFailure(const std::string& message,
                  int net_error,
-                 absl::optional<int> response_code) override {
+                 std::optional<int> response_code) override {
     owner_->has_failed_ = true;
     owner_->failure_message_ = message;
     owner_->failure_response_code_ = response_code.value_or(-1);
@@ -86,7 +86,7 @@
                      scoped_refptr<HttpResponseHeaders> response_headers,
                      const IPEndPoint& remote_endpoint,
                      base::OnceCallback<void(const AuthCredentials*)> callback,
-                     absl::optional<AuthCredentials>* credentials) override {
+                     std::optional<AuthCredentials>* credentials) override {
     owner_->run_loop_waiting_for_on_auth_required_.Quit();
     owner_->auth_challenge_info_ = auth_info;
     *credentials = owner_->auth_credentials_;
diff --git a/net/websockets/websocket_stream_create_test_base.h b/net/websockets/websocket_stream_create_test_base.h
index 04979b3..b0cce087 100644
--- a/net/websockets/websocket_stream_create_test_base.h
+++ b/net/websockets/websocket_stream_create_test_base.h
@@ -6,6 +6,7 @@
 #define NET_WEBSOCKETS_WEBSOCKET_STREAM_CREATE_TEST_BASE_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -21,7 +22,6 @@
 #include "net/test/test_with_task_environment.h"
 #include "net/websockets/websocket_event_interface.h"
 #include "net/websockets/websocket_test_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class GURL;
 
@@ -108,7 +108,7 @@
   base::OnceCallback<void(const AuthCredentials*)> on_auth_required_callback_;
 
   // This value will be copied to |*credentials| on OnAuthRequired.
-  absl::optional<AuthCredentials> auth_credentials_;
+  std::optional<AuthCredentials> auth_credentials_;
   // OnAuthRequired returns this value.
   int on_auth_required_rv_ = OK;
 
diff --git a/net/websockets/websocket_test_util.cc b/net/websockets/websocket_test_util.cc
index 6b8cdecb..b6d1a561 100644
--- a/net/websockets/websocket_test_util.cc
+++ b/net/websockets/websocket_test_util.cc
@@ -279,7 +279,7 @@
     scoped_refptr<HttpResponseHeaders> response_headers,
     const IPEndPoint& host_port_pair,
     base::OnceCallback<void(const AuthCredentials*)> callback,
-    absl::optional<AuthCredentials>* credentials) {
+    std::optional<AuthCredentials>* credentials) {
   return OK;
 }
 
diff --git a/net/websockets/websocket_test_util.h b/net/websockets/websocket_test_util.h
index ec0ba5e..f1b7e7e 100644
--- a/net/websockets/websocket_test_util.h
+++ b/net/websockets/websocket_test_util.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -25,7 +26,6 @@
 #include "net/websockets/websocket_event_interface.h"
 #include "net/websockets/websocket_handshake_stream_create_helper.h"
 #include "net/websockets/websocket_stream.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace url {
 class Origin;
@@ -210,7 +210,7 @@
       std::unique_ptr<WebSocketHandshakeResponseInfo> response) override {}
   void OnFailure(const std::string& message,
                  int net_error,
-                 absl::optional<int> response_code) override {}
+                 std::optional<int> response_code) override {}
   void OnStartOpeningHandshake(
       std::unique_ptr<WebSocketHandshakeRequestInfo> request) override {}
   void OnSSLCertificateError(
@@ -223,7 +223,7 @@
                      scoped_refptr<HttpResponseHeaders> response_headers,
                      const IPEndPoint& remote_endpoint,
                      base::OnceCallback<void(const AuthCredentials*)> callback,
-                     absl::optional<AuthCredentials>* credentials) override;
+                     std::optional<AuthCredentials>* credentials) override;
 };
 
 // WebSocketStreamRequestAPI implementation that sets the value of
@@ -240,7 +240,7 @@
       WebSocketHttp3HandshakeStream* handshake_stream) override;
   void OnFailure(const std::string& message,
                  int net_error,
-                 absl::optional<int> response_code) override {}
+                 std::optional<int> response_code) override {}
 };
 
 // A sub-class of WebSocketHandshakeStreamCreateHelper which sets a
diff --git a/services/device/generic_sensor/virtual_platform_sensor.cc b/services/device/generic_sensor/virtual_platform_sensor.cc
index 4ed6955..bc6b1c3 100644
--- a/services/device/generic_sensor/virtual_platform_sensor.cc
+++ b/services/device/generic_sensor/virtual_platform_sensor.cc
@@ -15,8 +15,12 @@
     mojom::SensorType type,
     SensorReadingSharedBuffer* reading_buffer,
     PlatformSensorProvider* provider,
-    std::optional<SensorReading> pending_reading)
+    std::optional<SensorReading> pending_reading,
+    const mojom::VirtualSensorMetadata& metadata)
     : PlatformSensor(type, reading_buffer, provider),
+      minimum_supported_frequency_(metadata.minimum_frequency),
+      maximum_supported_frequency_(metadata.maximum_frequency),
+      reporting_mode_(metadata.reporting_mode),
       pending_reading_(std::move(pending_reading)) {}
 
 VirtualPlatformSensor::~VirtualPlatformSensor() = default;
diff --git a/services/device/generic_sensor/virtual_platform_sensor.h b/services/device/generic_sensor/virtual_platform_sensor.h
index 15aee451..7146066 100644
--- a/services/device/generic_sensor/virtual_platform_sensor.h
+++ b/services/device/generic_sensor/virtual_platform_sensor.h
@@ -12,6 +12,7 @@
 #include "services/device/public/cpp/generic_sensor/platform_sensor_configuration.h"
 #include "services/device/public/cpp/generic_sensor/sensor_reading.h"
 #include "services/device/public/mojom/sensor.mojom-shared.h"
+#include "services/device/public/mojom/sensor_provider.mojom.h"
 
 namespace device {
 
@@ -22,7 +23,8 @@
   VirtualPlatformSensor(mojom::SensorType type,
                         SensorReadingSharedBuffer* reading_buffer,
                         PlatformSensorProvider* provider,
-                        std::optional<SensorReading> pending_reading);
+                        std::optional<SensorReading> pending_reading,
+                        const mojom::VirtualSensorMetadata& metadata);
 
   // Simulates the reporting of a new reading by a platform sensor.
   //
@@ -46,17 +48,6 @@
     return optimal_configuration_;
   }
 
-  void set_minimum_supported_frequency(double frequency) {
-    minimum_supported_frequency_ = frequency;
-  }
-  void set_maximum_supported_frequency(double frequency) {
-    maximum_supported_frequency_ = frequency;
-  }
-
-  void set_reporting_mode(mojom::ReportingMode reporting_mode) {
-    reporting_mode_ = reporting_mode;
-  }
-
  protected:
   ~VirtualPlatformSensor() override;
 
diff --git a/services/device/generic_sensor/virtual_platform_sensor_provider.cc b/services/device/generic_sensor/virtual_platform_sensor_provider.cc
index 1053d704..ad5a5ab 100644
--- a/services/device/generic_sensor/virtual_platform_sensor_provider.cc
+++ b/services/device/generic_sensor/virtual_platform_sensor_provider.cc
@@ -114,18 +114,8 @@
   metadata->pending_reading.swap(pending_reading);
 
   auto sensor = base::MakeRefCounted<VirtualPlatformSensor>(
-      type, reading_buffer, this, std::move(pending_reading));
-  if (metadata->mojo_metadata->minimum_frequency.has_value()) {
-    sensor->set_minimum_supported_frequency(
-        metadata->mojo_metadata->minimum_frequency.value());
-  }
-  if (metadata->mojo_metadata->maximum_frequency.has_value()) {
-    sensor->set_maximum_supported_frequency(
-        metadata->mojo_metadata->maximum_frequency.value());
-  }
-  if (metadata->mojo_metadata->reporting_mode.has_value()) {
-    sensor->set_reporting_mode(metadata->mojo_metadata->reporting_mode.value());
-  }
+      type, reading_buffer, this, std::move(pending_reading),
+      *metadata->mojo_metadata);
   std::move(callback).Run(std::move(sensor));
 }
 
diff --git a/services/network/cookie_settings_unittest.cc b/services/network/cookie_settings_unittest.cc
index be4b414a..9085791e 100644
--- a/services/network/cookie_settings_unittest.cc
+++ b/services/network/cookie_settings_unittest.cc
@@ -88,11 +88,39 @@
 // NOTE: Consider modifying
 // /components/content_settings/core/browser/cookie_settings_unittest.cc if
 // applicable.
-enum TestVariables {
-  kTopLevelStorageAccessGrantEligible = 0,
+
+// To avoid an explosion of test cases, please don't just add a boolean to
+// the test features. Consider whether features can interact with each other and
+// whether you really need all combinations.
+
+// Controls features that can unblock 3p cookies.
+enum GrantSource {
+  // Not eligible for additional grants.
+  kNoneGranted,
+  // Eligible for StorageAccess grants.
   kStorageAccessGrantsEligible,
+  // Eligible for TopLevelStorageAccess grants.
+  kTopLevelStorageAccessGrantEligible,
+
+  kGrantSourceCount
+};
+
+// Features that can block 3p cookies.
+enum BlockSource {
+  // 3p cookie blocking is not enabled.
+  kNoneBlocked,
+  // Tracking protection enabled by default.
   kTrackingProtectionEnabledFor3pcd,
+  // Third-party cookie blocking is enabled through a flag.
   kForceThirdPartyCookieBlockingFlagEnabled,
+
+  kBlockSourceCount
+
+};
+
+enum TestVariables {
+  kGrantSource,
+  kBlockSource,
   kHostIndexedMetadataGrantsEnabled
 };
 
@@ -130,10 +158,8 @@
 class CookieSettingsTest
     : public CookieSettingsTestBase,
       public testing::TestWithParam<
-          std::tuple</*kTopLevelStorageAccessGrantEligible*/ bool,
-                     /*kStorageAccessGrantsEligible*/ bool,
-                     /*kTrackingProtectionEnabledFor3pcd*/ bool,
-                     /*kForceThirdPartyCookieBlockingFlagEnabled*/ bool,
+          std::tuple</*kGrantSource*/ GrantSource,
+                     /*kBlockSource*/ BlockSource,
                      /*kHostIndexedMetadataGrantsEnabled*/ bool>> {
  public:
   CookieSettingsTest() {
@@ -163,22 +189,23 @@
   // Indicates whether the setting comes from the testing flag if the test case
   // has 3pc blocked.
   bool IsForceThirdPartyCookieBlockingFlagEnabled() const {
-    return std::get<TestVariables::kForceThirdPartyCookieBlockingFlagEnabled>(
-        GetParam());
+    return std::get<TestVariables::kBlockSource>(GetParam()) ==
+           BlockSource::kForceThirdPartyCookieBlockingFlagEnabled;
   }
 
   bool IsTrackingProtectionEnabledFor3pcd() const {
-    return std::get<TestVariables::kTrackingProtectionEnabledFor3pcd>(
-        GetParam());
+    return std::get<TestVariables::kBlockSource>(GetParam()) ==
+           BlockSource::kTrackingProtectionEnabledFor3pcd;
   }
 
   bool IsStorageAccessGrantEligible() const {
-    return std::get<TestVariables::kStorageAccessGrantsEligible>(GetParam());
+    return std::get<TestVariables::kGrantSource>(GetParam()) ==
+           GrantSource::kStorageAccessGrantsEligible;
   }
 
   bool IsTopLevelStorageAccessGrantEligible() const {
-    return std::get<TestVariables::kTopLevelStorageAccessGrantEligible>(
-        GetParam());
+    return std::get<TestVariables::kGrantSource>(GetParam()) ==
+           GrantSource::kTopLevelStorageAccessGrantEligible;
   }
 
   bool IsHostIndexedMetadataGrantsEnabled() const {
@@ -1645,14 +1672,10 @@
   std::stringstream custom_test_name;
   // clang-format off
   custom_test_name
-      << "TopLvlStorageAccess_"
-      << std::get<TestVariables::kTopLevelStorageAccessGrantEligible>(info.param)
-      << "_StorageAccess_"
-      << std::get<TestVariables::kStorageAccessGrantsEligible>(info.param)
-      << "_TrackingProtection3pcd_"
-      << std::get<TestVariables::kTrackingProtectionEnabledFor3pcd>(info.param)
-      << "_Force3pcb_"
-      << std::get<TestVariables::kForceThirdPartyCookieBlockingFlagEnabled>(info.param)
+      << "GrantSource_"
+      << std::get<TestVariables::kGrantSource>(info.param)
+      << "_BlockSource_"
+      << std::get<TestVariables::kBlockSource>(info.param)
       << "_HostIndexed_"
       << std::get<TestVariables::kHostIndexedMetadataGrantsEnabled>(info.param);
   // clang-format on
@@ -1662,10 +1685,10 @@
 INSTANTIATE_TEST_SUITE_P(
     /* no prefix */,
     CookieSettingsTest,
-    testing::Combine(testing::Bool(),
-                     testing::Bool(),
-                     testing::Bool(),
-                     testing::Bool(),
+    testing::Combine(testing::Range(GrantSource::kNoneGranted,
+                                    GrantSource::kGrantSourceCount),
+                     testing::Range(BlockSource::kNoneBlocked,
+                                    BlockSource::kBlockSourceCount),
                      testing::Bool()),
     CustomTestName);
 
diff --git a/services/network/cors/cors_url_loader_shared_dictionary_unittest.cc b/services/network/cors/cors_url_loader_shared_dictionary_unittest.cc
index 68f82ce..8d4c73ab 100644
--- a/services/network/cors/cors_url_loader_shared_dictionary_unittest.cc
+++ b/services/network/cors/cors_url_loader_shared_dictionary_unittest.cc
@@ -141,7 +141,7 @@
     EXPECT_EQ(dictionary_url, dictionary_info.url());
     EXPECT_EQ(base::FeatureList::IsEnabled(
                   network::features::kCompressionDictionaryTransport)
-                  ? shared_dictionary::kDefaultExpiration
+                  ? base::Seconds(2592000)
                   : shared_dictionary::kMaxExpirationForOriginTrial,
               dictionary_info.expiration());
     EXPECT_EQ("/path*", dictionary_info.match());
diff --git a/services/network/p2p/socket.cc b/services/network/p2p/socket.cc
index 599a157..018afd0 100644
--- a/services/network/p2p/socket.cc
+++ b/services/network/p2p/socket.cc
@@ -136,12 +136,13 @@
     const net::NetworkTrafficAnnotationTag& traffic_annotation,
     net::NetLog* net_log,
     ProxyResolvingClientSocketFactory* proxy_resolving_socket_factory,
-    P2PMessageThrottler* throttler) {
+    P2PMessageThrottler* throttler,
+    absl::optional<base::UnguessableToken> devtools_token) {
   switch (type) {
     case P2P_SOCKET_UDP:
-      return std::make_unique<P2PSocketUdp>(delegate, std::move(client),
-                                            std::move(socket), throttler,
-                                            traffic_annotation, net_log);
+      return std::make_unique<P2PSocketUdp>(
+          delegate, std::move(client), std::move(socket), throttler,
+          traffic_annotation, net_log, devtools_token);
     case P2P_SOCKET_TCP_CLIENT:
     case P2P_SOCKET_SSLTCP_CLIENT:
     case P2P_SOCKET_TLS_CLIENT:
diff --git a/services/network/p2p/socket.h b/services/network/p2p/socket.h
index 20a6385..b10e1f3c 100644
--- a/services/network/p2p/socket.h
+++ b/services/network/p2p/socket.h
@@ -14,6 +14,7 @@
 #include "base/containers/span.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
+#include "base/unguessable_token.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver.h"
@@ -68,7 +69,8 @@
       const net::NetworkTrafficAnnotationTag& traffic_annotation,
       net::NetLog* net_log,
       ProxyResolvingClientSocketFactory* proxy_resolving_socket_factory,
-      P2PMessageThrottler* throttler);
+      P2PMessageThrottler* throttler,
+      absl::optional<base::UnguessableToken> devtools_token);
 
   P2PSocket(const P2PSocket&) = delete;
   P2PSocket& operator=(const P2PSocket&) = delete;
diff --git a/services/network/p2p/socket_manager.cc b/services/network/p2p/socket_manager.cc
index b6eea8e..f187044 100644
--- a/services/network/p2p/socket_manager.cc
+++ b/services/network/p2p/socket_manager.cc
@@ -423,6 +423,7 @@
     const P2PPortRange& port_range,
     const P2PHostAndIPEndPoint& remote_address,
     const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
+    const absl::optional<base::UnguessableToken>& devtools_token,
     mojo::PendingRemote<mojom::P2PSocketClient> client,
     mojo::PendingReceiver<mojom::P2PSocket> receiver) {
   if (port_range.min_port > port_range.max_port ||
@@ -440,11 +441,11 @@
     LOG(ERROR) << "Too many sockets created";
     return;
   }
-  std::unique_ptr<P2PSocket> socket =
-      P2PSocket::Create(this, std::move(client), std::move(receiver), type,
-                        net::NetworkTrafficAnnotationTag(traffic_annotation),
-                        url_request_context_->net_log(),
-                        proxy_resolving_socket_factory_.get(), &throttler_);
+  std::unique_ptr<P2PSocket> socket = P2PSocket::Create(
+      this, std::move(client), std::move(receiver), type,
+      net::NetworkTrafficAnnotationTag(traffic_annotation),
+      url_request_context_->net_log(), proxy_resolving_socket_factory_.get(),
+      &throttler_, devtools_token);
 
   if (!socket)
     return;
diff --git a/services/network/p2p/socket_manager.h b/services/network/p2p/socket_manager.h
index ffcd8e6..080db58 100644
--- a/services/network/p2p/socket_manager.h
+++ b/services/network/p2p/socket_manager.h
@@ -139,6 +139,7 @@
       const P2PPortRange& port_range,
       const P2PHostAndIPEndPoint& remote_address,
       const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
+      const absl::optional<base::UnguessableToken>& devtools_token,
       mojo::PendingRemote<mojom::P2PSocketClient> client,
       mojo::PendingReceiver<mojom::P2PSocket> receiver) override;
 
diff --git a/services/network/p2p/socket_udp.cc b/services/network/p2p/socket_udp.cc
index ed09359..1cf64434e 100644
--- a/services/network/p2p/socket_udp.cc
+++ b/services/network/p2p/socket_udp.cc
@@ -101,17 +101,20 @@
 P2PSocketUdp::PendingPacket::~PendingPacket() = default;
 
 P2PSocketUdp::P2PSocketUdp(
+
     Delegate* Delegate,
     mojo::PendingRemote<mojom::P2PSocketClient> client,
     mojo::PendingReceiver<mojom::P2PSocket> socket,
     P2PMessageThrottler* throttler,
     const net::NetworkTrafficAnnotationTag& traffic_annotation,
     net::NetLog* net_log,
-    const DatagramServerSocketFactory& socket_factory)
+    const DatagramServerSocketFactory& socket_factory,
+    absl::optional<base::UnguessableToken> devtools_token)
     : P2PSocket(Delegate, std::move(client), std::move(socket), P2PSocket::UDP),
       throttler_(throttler),
       traffic_annotation_(traffic_annotation),
-      net_log_(net_log),
+      net_log_with_source_(
+          net::NetLogWithSource::Make(net_log, net::NetLogSourceType::SOCKET)),
       socket_factory_(socket_factory) {}
 
 P2PSocketUdp::P2PSocketUdp(
@@ -120,14 +123,16 @@
     mojo::PendingReceiver<mojom::P2PSocket> socket,
     P2PMessageThrottler* throttler,
     const net::NetworkTrafficAnnotationTag& traffic_annotation,
-    net::NetLog* net_log)
+    net::NetLog* net_log,
+    absl::optional<base::UnguessableToken> devtools_token)
     : P2PSocketUdp(Delegate,
                    std::move(client),
                    std::move(socket),
                    throttler,
                    traffic_annotation,
                    net_log,
-                   base::BindRepeating(&DefaultSocketFactory)) {}
+                   base::BindRepeating(&DefaultSocketFactory),
+                   devtools_token) {}
 
 P2PSocketUdp::~P2PSocketUdp() = default;
 
@@ -141,7 +146,7 @@
   DCHECK((min_port == 0 && max_port == 0) || min_port > 0);
   DCHECK_LE(min_port, max_port);
 
-  socket_ = socket_factory_.Run(net_log_.get());
+  socket_ = socket_factory_.Run(net_log());
 
   int result = -1;
   if (min_port == 0) {
@@ -149,8 +154,9 @@
   } else if (local_address.port() == 0) {
     for (unsigned port = min_port; port <= max_port && result < 0; ++port) {
       result = socket_->Listen(net::IPEndPoint(local_address.address(), port));
-      if (result < 0 && port != max_port)
-        socket_ = socket_factory_.Run(net_log_.get());
+      if (result < 0 && port != max_port) {
+        socket_ = socket_factory_.Run(net_log());
+      }
     }
   } else if (local_address.port() >= min_port &&
              local_address.port() <= max_port) {
diff --git a/services/network/p2p/socket_udp.h b/services/network/p2p/socket_udp.h
index 29d7e6c..d5a104a 100644
--- a/services/network/p2p/socket_udp.h
+++ b/services/network/p2p/socket_udp.h
@@ -52,13 +52,15 @@
                P2PMessageThrottler* throttler,
                const net::NetworkTrafficAnnotationTag& traffic_annotation,
                net::NetLog* net_log,
-               const DatagramServerSocketFactory& socket_factory);
+               const DatagramServerSocketFactory& socket_factory,
+               absl::optional<base::UnguessableToken> devtools_token);
   P2PSocketUdp(Delegate* delegate,
                mojo::PendingRemote<mojom::P2PSocketClient> client,
                mojo::PendingReceiver<mojom::P2PSocket> socket,
                P2PMessageThrottler* throttler,
                const net::NetworkTrafficAnnotationTag& traffic_annotation,
-               net::NetLog* net_log);
+               net::NetLog* net_log,
+               absl::optional<base::UnguessableToken> devtools_token);
 
   P2PSocketUdp(const P2PSocketUdp&) = delete;
   P2PSocketUdp& operator=(const P2PSocketUdp&) = delete;
@@ -119,6 +121,7 @@
               int result);
 
   int SetSocketDiffServCodePointInternal(net::DiffServCodePoint dscp);
+  net::NetLog* net_log() const { return net_log_with_source_.net_log(); }
 
   // Called at the end of sends to send out SendComplete to the |client_|.
   void ProcessSendCompletions();
@@ -142,7 +145,7 @@
   raw_ptr<P2PMessageThrottler> throttler_;
 
   const net::NetworkTrafficAnnotationTag traffic_annotation_;
-  raw_ptr<net::NetLog> net_log_;
+  net::NetLogWithSource net_log_with_source_;
 
   // Callback object that returns a new socket when invoked.
   DatagramServerSocketFactory socket_factory_;
diff --git a/services/network/p2p/socket_udp_unittest.cc b/services/network/p2p/socket_udp_unittest.cc
index dcaac5dc..944d04c 100644
--- a/services/network/p2p/socket_udp_unittest.cc
+++ b/services/network/p2p/socket_udp_unittest.cc
@@ -293,7 +293,8 @@
         &throttler_, TRAFFIC_ANNOTATION_FOR_TESTS,
         /*net_log=*/nullptr,
         base::BindRepeating(&CreateFakeDatagramServerSocket, &sent_packets_,
-                            nullptr, &fake_clock_));
+                            nullptr, &fake_clock_),
+        absl::nullopt);
 
     local_address_ = ParseAddress(kTestLocalIpAddress, kTestPort1);
     socket_impl_->Init(
@@ -608,7 +609,7 @@
     std::unique_ptr<P2PSocketUdp> socket_impl(new P2PSocketUdp(
         &socket_delegate_, std::move(socket_client), std::move(socket_receiver),
         &throttler, TRAFFIC_ANNOTATION_FOR_TESTS, /*net_log=*/nullptr,
-        fake_socket_factory));
+        fake_socket_factory, absl::nullopt));
     net::IPEndPoint local_address = ParseAddress(kTestLocalIpAddress, 0);
     socket_impl->Init(
         local_address, min_port, max_port,
@@ -631,7 +632,7 @@
   std::unique_ptr<P2PSocketUdp> socket_impl(new P2PSocketUdp(
       &socket_delegate_, std::move(socket_client), std::move(socket_receiver),
       &throttler, TRAFFIC_ANNOTATION_FOR_TESTS,
-      /*net_log=*/nullptr, std::move(fake_socket_factory)));
+      /*net_log=*/nullptr, std::move(fake_socket_factory), absl::nullopt));
   net::IPEndPoint local_address = ParseAddress(kTestLocalIpAddress, 0);
 
   auto* socket_impl_ptr = socket_impl.get();
@@ -672,7 +673,7 @@
   std::unique_ptr<P2PSocketUdp> socket_host(new P2PSocketUdp(
       &socket_delegate_, std::move(socket_client), std::move(socket_receiver),
       &throttler, TRAFFIC_ANNOTATION_FOR_TESTS,
-      /*net_log=*/nullptr, std::move(fake_socket_factory)));
+      /*net_log=*/nullptr, std::move(fake_socket_factory), absl::nullopt));
   net::IPEndPoint local_address = ParseAddress(kTestLocalIpAddress, valid_port);
   socket_host->Init(
       local_address, min_port, max_port,
@@ -711,7 +712,7 @@
   auto socket_impl = std::make_unique<P2PSocketUdp>(
       &socket_delegate_, std::move(socket_client), std::move(socket_receiver),
       &throttler, TRAFFIC_ANNOTATION_FOR_TESTS, /*net_log=*/nullptr,
-      std::move(fake_socket_factory));
+      std::move(fake_socket_factory), absl::nullopt);
   net::IPEndPoint local_address =
       ParseAddress(kTestLocalIpAddress, invalid_port);
 
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc
index 8a7f203c..a18e43f 100644
--- a/services/network/public/cpp/features.cc
+++ b/services/network/public/cpp/features.cc
@@ -395,16 +395,6 @@
 BASE_FEATURE(kCompressionDictionaryTransportBackend,
              "CompressionDictionaryTransportBackend",
              base::FEATURE_ENABLED_BY_DEFAULT);
-const base::FeatureParam<CompressionDictionaryTransportBackendVersion>::Option
-    kCompressionDictionaryTransportBackendVersionOptions[] = {
-        {CompressionDictionaryTransportBackendVersion::kV1, "v1"},
-        {CompressionDictionaryTransportBackendVersion::kV2, "v2"}};
-const base::FeatureParam<CompressionDictionaryTransportBackendVersion>
-    kCompressionDictionaryTransportBackendVersion{
-        &kCompressionDictionaryTransportBackend,
-        "CompressionDictionaryTransportBackendVersion",
-        CompressionDictionaryTransportBackendVersion::kV2,
-        &kCompressionDictionaryTransportBackendVersionOptions};
 
 // When both this feature and the kCompressionDictionaryTransportBackend feature
 // are enabled, the following will happen:
diff --git a/services/network/public/cpp/features.h b/services/network/public/cpp/features.h
index e9a2385..3513b22 100644
--- a/services/network/public/cpp/features.h
+++ b/services/network/public/cpp/features.h
@@ -151,15 +151,6 @@
 COMPONENT_EXPORT(NETWORK_CPP)
 BASE_DECLARE_FEATURE(kCompressionDictionaryTransportBackend);
 
-enum class CompressionDictionaryTransportBackendVersion {
-  kV1,
-  kV2,
-};
-
-COMPONENT_EXPORT(NETWORK_CPP)
-extern const base::FeatureParam<CompressionDictionaryTransportBackendVersion>
-    kCompressionDictionaryTransportBackendVersion;
-
 COMPONENT_EXPORT(NETWORK_CPP)
 BASE_DECLARE_FEATURE(kCompressionDictionaryTransport);
 COMPONENT_EXPORT(NETWORK_CPP)
diff --git a/services/network/public/cpp/shared_dictionary_encoding_names.cc b/services/network/public/cpp/shared_dictionary_encoding_names.cc
index 4d9a176..0fe0903 100644
--- a/services/network/public/cpp/shared_dictionary_encoding_names.cc
+++ b/services/network/public/cpp/shared_dictionary_encoding_names.cc
@@ -9,12 +9,7 @@
 namespace network {
 
 const char* GetSharedBrotliContentEncodingName() {
-  switch (features::kCompressionDictionaryTransportBackendVersion.Get()) {
-    case features::CompressionDictionaryTransportBackendVersion::kV1:
-      return "sbr";
-    case features::CompressionDictionaryTransportBackendVersion::kV2:
-      return "br-d";
-  }
+  return "br-d";
 }
 
 const char* GetSharedZstdContentEncodingName() {
diff --git a/services/network/public/cpp/shared_dictionary_encoding_names.h b/services/network/public/cpp/shared_dictionary_encoding_names.h
index 9c0d1ac..cb54b00 100644
--- a/services/network/public/cpp/shared_dictionary_encoding_names.h
+++ b/services/network/public/cpp/shared_dictionary_encoding_names.h
@@ -9,9 +9,7 @@
 
 namespace network {
 
-// Returns the content encoding name of Shared Brotli:
-//   "sbr": when CompressionDictionaryTransportBackendVersion is kV1.
-//   "br-d": when CompressionDictionaryTransportBackendVersion is kV2.
+// Returns the content encoding name of Shared Brotli: "br-d"
 COMPONENT_EXPORT(NETWORK_CPP) const char* GetSharedBrotliContentEncodingName();
 
 // Returns the content encoding name of Shared Zstd: "zstd-d".
diff --git a/services/network/public/mojom/p2p.mojom b/services/network/public/mojom/p2p.mojom
index 770d3d52..01d5f79 100644
--- a/services/network/public/mojom/p2p.mojom
+++ b/services/network/public/mojom/p2p.mojom
@@ -4,6 +4,7 @@
 
 module network.mojom;
 
+import "mojo/public/mojom/base/unguessable_token.mojom";
 import "mojo/public/mojom/base/time.mojom";
 import "mojo/public/mojom/base/read_only_buffer.mojom";
 import "services/network/public/mojom/network_interface.mojom";
@@ -62,11 +63,13 @@
                            int32 address_family,
                            bool enable_mdns) => (array<IPAddress> addresses);
 
+  // Creates a P2PSocket
   CreateSocket(P2PSocketType type,
                IPEndPoint local_address,
                P2PPortRange port_range,
                P2PHostAndIPEndPoint remote_address,
                MutableNetworkTrafficAnnotationTag traffic_annotation,
+               mojo_base.mojom.UnguessableToken? devtools_token,
                pending_remote<P2PSocketClient> client,
                pending_receiver<P2PSocket> socket);
 };
diff --git a/services/network/shared_dictionary/shared_dictionary_constants.cc b/services/network/shared_dictionary/shared_dictionary_constants.cc
index f374b50..44dca4d8 100644
--- a/services/network/shared_dictionary/shared_dictionary_constants.cc
+++ b/services/network/shared_dictionary/shared_dictionary_constants.cc
@@ -16,16 +16,11 @@
 
 }  // namespace
 
-const char kSecAvailableDictionaryHeaderName[] = "sec-available-dictionary";
 const char kAvailableDictionaryHeaderName[] = "available-dictionary";
-
 const char kUseAsDictionaryHeaderName[] = "use-as-dictionary";
-
 const char kContentDictionaryHeaderName[] = "content-dictionary";
-
 const char kOptionNameMatch[] = "match";
 const char kOptionNameMatchDest[] = "match-dest";
-const char kOptionNameExpires[] = "expires";
 const char kOptionNameType[] = "type";
 const char kOptionNameId[] = "id";
 
diff --git a/services/network/shared_dictionary/shared_dictionary_constants.h b/services/network/shared_dictionary/shared_dictionary_constants.h
index 1d893e2..241128c 100644
--- a/services/network/shared_dictionary/shared_dictionary_constants.h
+++ b/services/network/shared_dictionary/shared_dictionary_constants.h
@@ -13,11 +13,6 @@
 
 namespace network::shared_dictionary {
 
-// The default value (1 year) of expiration time in "use-as-dictionary"
-// HTTP header.
-// This will not be used when V2 backend is enabled.
-constexpr base::TimeDelta kDefaultExpiration = base::Seconds(31536000);
-
 // The max expiration time (30 days) for Origin Trial. This is used when
 // CompressionDictionaryTransport feature is disabled in the network service.
 // TODO(crbug.com/1413922): Remove this after the Origin Trial experiment.
@@ -35,11 +30,6 @@
 base::ScopedClosureRunner SetDictionarySizeLimitForTesting(
     size_t dictionary_size_limit);
 
-// The header name of "sec-available-dictionary".
-// This will not be used when V2 backend is enabled.
-COMPONENT_EXPORT(NETWORK_SERVICE)
-extern const char kSecAvailableDictionaryHeaderName[];
-
 // The header name of "available-dictionary".
 COMPONENT_EXPORT(NETWORK_SERVICE)
 extern const char kAvailableDictionaryHeaderName[];
@@ -58,10 +48,6 @@
 // The dictionary option name of "match-dest".
 COMPONENT_EXPORT(NETWORK_SERVICE) extern const char kOptionNameMatchDest[];
 
-// The dictionary option name of "expires".
-// This will not be used when V2 backend is enabled.
-COMPONENT_EXPORT(NETWORK_SERVICE) extern const char kOptionNameExpires[];
-
 // The dictionary option name of "type".
 COMPONENT_EXPORT(NETWORK_SERVICE) extern const char kOptionNameType[];
 
diff --git a/services/network/shared_dictionary/shared_dictionary_manager_on_disk_unittest.cc b/services/network/shared_dictionary/shared_dictionary_manager_on_disk_unittest.cc
index 1725412..b4182796 100644
--- a/services/network/shared_dictionary/shared_dictionary_manager_on_disk_unittest.cc
+++ b/services/network/shared_dictionary/shared_dictionary_manager_on_disk_unittest.cc
@@ -14,7 +14,6 @@
 #include "base/strings/stringprintf.h"
 #include "base/test/bind.h"
 #include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/test/test_file_util.h"
 #include "base/time/time.h"
@@ -162,20 +161,9 @@
 
 }  // namespace
 
-class SharedDictionaryManagerOnDiskTest
-    : public ::testing::Test,
-      public testing::WithParamInterface<
-          features::CompressionDictionaryTransportBackendVersion> {
+class SharedDictionaryManagerOnDiskTest : public ::testing::Test {
  public:
-  SharedDictionaryManagerOnDiskTest() {
-    std::vector<base::test::FeatureRefAndParams> enabled_features;
-    enabled_features.emplace_back(base::test::FeatureRefAndParams(
-        features::kCompressionDictionaryTransportBackend,
-        {{features::kCompressionDictionaryTransportBackendVersion.name,
-          features::kCompressionDictionaryTransportBackendVersion.GetName(
-              GetVersion())}}));
-    scoped_feature_list_.InitWithFeaturesAndParameters(enabled_features, {});
-  }
+  SharedDictionaryManagerOnDiskTest() = default;
   ~SharedDictionaryManagerOnDiskTest() override = default;
 
   SharedDictionaryManagerOnDiskTest(const SharedDictionaryManagerOnDiskTest&) =
@@ -192,10 +180,6 @@
   void TearDown() override { FlushCacheTasks(); }
 
  protected:
-  features::CompressionDictionaryTransportBackendVersion GetVersion() const {
-    return GetParam();
-  }
-
   static base::UnguessableToken GetDiskCacheKeyTokenOfFirstDictionary(
       const std::map<
           url::SchemeHostPort,
@@ -272,26 +256,9 @@
   // `file_permissions_restorer_` must be below `tmp_directory_` to restore the
   // file permission correctly.
   std::unique_ptr<base::FilePermissionRestorer> file_permissions_restorer_;
-  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
-INSTANTIATE_TEST_SUITE_P(
-    All,
-    SharedDictionaryManagerOnDiskTest,
-    testing::ValuesIn(
-        {features::CompressionDictionaryTransportBackendVersion::kV1,
-         features::CompressionDictionaryTransportBackendVersion::kV2}),
-    [](const testing::TestParamInfo<
-        features::CompressionDictionaryTransportBackendVersion>& info) {
-      switch (info.param) {
-        case features::CompressionDictionaryTransportBackendVersion::kV1:
-          return "V1";
-        case features::CompressionDictionaryTransportBackendVersion::kV2:
-          return "V2";
-      }
-    });
-
-TEST_P(SharedDictionaryManagerOnDiskTest, ReusingRefCountedSharedDictionary) {
+TEST_F(SharedDictionaryManagerOnDiskTest, ReusingRefCountedSharedDictionary) {
   std::unique_ptr<SharedDictionaryManager> manager =
       CreateSharedDictionaryManager();
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
@@ -336,7 +303,7 @@
                         dict1->size()));
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest,
+TEST_F(SharedDictionaryManagerOnDiskTest,
        MaybeCreateWriterAfterManagerDeleted) {
   std::unique_ptr<SharedDictionaryManager> manager =
       CreateSharedDictionaryManager();
@@ -362,7 +329,7 @@
   EXPECT_FALSE(writer);
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest, GetDictionaryAfterManagerDeleted) {
+TEST_F(SharedDictionaryManagerOnDiskTest, GetDictionaryAfterManagerDeleted) {
   std::unique_ptr<SharedDictionaryManager> manager =
       CreateSharedDictionaryManager();
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
@@ -380,7 +347,7 @@
   EXPECT_FALSE(dict);
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest,
+TEST_F(SharedDictionaryManagerOnDiskTest,
        DictionaryWrittenInDiskCacheAfterManagerDeleted) {
   std::unique_ptr<SharedDictionaryManager> manager =
       CreateSharedDictionaryManager();
@@ -398,7 +365,7 @@
   FlushCacheTasks();
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest, OverridingDictionary) {
+TEST_F(SharedDictionaryManagerOnDiskTest, OverridingDictionary) {
   std::unique_ptr<SharedDictionaryManager> manager =
       CreateSharedDictionaryManager();
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
@@ -470,7 +437,7 @@
                         dict1->size()));
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest, MultipleDictionaries) {
+TEST_F(SharedDictionaryManagerOnDiskTest, MultipleDictionaries) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
 
@@ -555,7 +522,7 @@
                         dict2->size()));
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest, GetDictionary) {
+TEST_F(SharedDictionaryManagerOnDiskTest, GetDictionary) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
 
@@ -610,7 +577,7 @@
 // Test that corruptted disk cache doesn't cause crash.
 // CorruptDiskCache() doesn't work on Fuchsia. So disabling the following tests
 // on Fuchsia.
-TEST_P(SharedDictionaryManagerOnDiskTest, CorruptedDiskCacheAndWriteData) {
+TEST_F(SharedDictionaryManagerOnDiskTest, CorruptedDiskCacheAndWriteData) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
 
@@ -648,7 +615,7 @@
   }
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest, CorruptedDiskCacheAndGetData) {
+TEST_F(SharedDictionaryManagerOnDiskTest, CorruptedDiskCacheAndGetData) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
 
@@ -699,7 +666,7 @@
 }
 #endif  // !BUILDFLAG(IS_FUCHSIA)
 
-TEST_P(SharedDictionaryManagerOnDiskTest, CorruptedDatabase) {
+TEST_F(SharedDictionaryManagerOnDiskTest, CorruptedDatabase) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
 
@@ -787,7 +754,7 @@
   }
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest, MetadataBrokenDatabase) {
+TEST_F(SharedDictionaryManagerOnDiskTest, MetadataBrokenDatabase) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
 
@@ -856,7 +823,7 @@
   }
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest, LastUsedTime) {
+TEST_F(SharedDictionaryManagerOnDiskTest, LastUsedTime) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
   base::Time last_used_time_after_second_get_dict;
@@ -930,7 +897,7 @@
   return arg.url().spec() == url;
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest, ClearData) {
+TEST_F(SharedDictionaryManagerOnDiskTest, ClearData) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
   {
@@ -1052,7 +1019,7 @@
                         DictionaryUrlIs("https://target.test/4"))))));
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest, ClearDataSerializedOperation) {
+TEST_F(SharedDictionaryManagerOnDiskTest, ClearDataSerializedOperation) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
   std::unique_ptr<SharedDictionaryManager> manager =
@@ -1109,7 +1076,7 @@
   EXPECT_TRUE(GetOnDiskDictionaryMap(storage.get()).empty());
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest, ClearDataForIsolationKey) {
+TEST_F(SharedDictionaryManagerOnDiskTest, ClearDataForIsolationKey) {
   net::SharedDictionaryIsolationKey isolation_key1(url::Origin::Create(kUrl),
                                                    kSite);
   net::SharedDictionaryIsolationKey isolation_key2(
@@ -1185,7 +1152,7 @@
               DictionaryUrlIs("https://origin1.test/d"))))));
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest, ExpiredDictionaryDeletionOnReload) {
+TEST_F(SharedDictionaryManagerOnDiskTest, ExpiredDictionaryDeletionOnReload) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
   base::UnguessableToken token1, token2;
@@ -1234,7 +1201,7 @@
   EXPECT_TRUE(DiskCacheEntryExists(manager.get(), token2));
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest,
+TEST_F(SharedDictionaryManagerOnDiskTest,
        ExpiredDictionaryDeletionOnNewDictionary) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
@@ -1283,7 +1250,7 @@
   EXPECT_TRUE(DiskCacheEntryExists(manager.get(), token2));
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest,
+TEST_F(SharedDictionaryManagerOnDiskTest,
        ExpiredDictionaryDeletionOnSetCacheMaxSize) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
@@ -1321,7 +1288,7 @@
   EXPECT_FALSE(DiskCacheEntryExists(manager.get(), token));
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest,
+TEST_F(SharedDictionaryManagerOnDiskTest,
        ExpiredDictionaryDeletionOnClearData) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
@@ -1362,7 +1329,7 @@
   EXPECT_FALSE(DiskCacheEntryExists(manager.get(), token));
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest,
+TEST_F(SharedDictionaryManagerOnDiskTest,
        ExpiredDictionaryDeletionOnClearDataForIsolationKey) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
@@ -1404,7 +1371,7 @@
   EXPECT_FALSE(DiskCacheEntryExists(manager.get(), token));
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest, CacheEvictionOnReload) {
+TEST_F(SharedDictionaryManagerOnDiskTest, CacheEvictionOnReload) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
   base::UnguessableToken token1, token2, token3;
@@ -1458,7 +1425,7 @@
   EXPECT_TRUE(DiskCacheEntryExists(manager.get(), token3));
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest, CacheEvictionOnSetCacheMaxSize) {
+TEST_F(SharedDictionaryManagerOnDiskTest, CacheEvictionOnSetCacheMaxSize) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
   std::unique_ptr<SharedDictionaryManager> manager =
@@ -1502,7 +1469,7 @@
   EXPECT_TRUE(DiskCacheEntryExists(manager.get(), token3));
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest, CacheEvictionOnNewDictionary) {
+TEST_F(SharedDictionaryManagerOnDiskTest, CacheEvictionOnNewDictionary) {
   const net::SchemefulSite site1(GURL("https://site1.test"));
   const net::SchemefulSite site2(GURL("https://site2.test"));
   const net::SchemefulSite site3(GURL("https://site3.test"));
@@ -1584,7 +1551,7 @@
   EXPECT_TRUE(DiskCacheEntryExists(manager.get(), token3));
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest,
+TEST_F(SharedDictionaryManagerOnDiskTest,
        CacheEvictionPerSiteExceededSizeLimit) {
   const net::SchemefulSite site1(GURL("https://site1.test"));
   const net::SchemefulSite site2(GURL("https://site2.test"));
@@ -1672,7 +1639,7 @@
   EXPECT_FALSE(DiskCacheEntryExists(manager.get(), token2));
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest,
+TEST_F(SharedDictionaryManagerOnDiskTest,
        CacheEvictionPerSiteExceededCountLimit) {
   const net::SchemefulSite site1(GURL("https://site1.test"));
   const net::SchemefulSite site2(GURL("https://site2.test"));
@@ -1788,7 +1755,7 @@
   EXPECT_TRUE(DiskCacheEntryExists(manager.get(), token3));
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest,
+TEST_F(SharedDictionaryManagerOnDiskTest,
        CacheEvictionAfterUpdatingLastUsedTime) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
@@ -1864,7 +1831,7 @@
   EXPECT_TRUE(DiskCacheEntryExists(manager.get(), token4));
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest,
+TEST_F(SharedDictionaryManagerOnDiskTest,
        MismatchingEntryDeletionMetadataUnavailableDictionary) {
   const base::UnguessableToken token = base::UnguessableToken::Create();
   const std::string entry_key = token.ToString();
@@ -1894,7 +1861,7 @@
       0, 1);
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest,
+TEST_F(SharedDictionaryManagerOnDiskTest,
        MismatchingEntryDeletionInvalidDiskCacheEntry) {
   const std::string kTestKey = "test";
   const std::string kTestData = "Hello world";
@@ -1923,7 +1890,7 @@
       0, 1);
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest,
+TEST_F(SharedDictionaryManagerOnDiskTest,
        MismatchingEntryDeletionDiskCacheEntryUnavailableDictionary) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
@@ -1992,7 +1959,7 @@
   EXPECT_TRUE(GetOnDiskDictionaryMap(storage.get()).empty());
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest,
+TEST_F(SharedDictionaryManagerOnDiskTest,
        MismatchingEntryDeletionCanBeTriggeredOnlyOnce) {
   std::unique_ptr<SharedDictionaryManager> manager =
       CreateSharedDictionaryManager();
@@ -2033,7 +2000,7 @@
   EXPECT_TRUE(DiskCacheEntryExists(manager.get(), entry_key));
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest,
+TEST_F(SharedDictionaryManagerOnDiskTest,
        MismatchingEntryDeletionWritingEntryMustNotBeDeleted) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
@@ -2099,7 +2066,7 @@
               DictionaryUrlIs("https://target1.test/d"))))));
 }
 
-TEST_P(SharedDictionaryManagerOnDiskTest,
+TEST_F(SharedDictionaryManagerOnDiskTest,
        MismatchingEntryDeletionWritingDiskCacheEntryMustNotBeDeleted) {
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl),
                                                   kSite);
diff --git a/services/network/shared_dictionary/shared_dictionary_manager_unittest.cc b/services/network/shared_dictionary/shared_dictionary_manager_unittest.cc
index f253363..b7888c8 100644
--- a/services/network/shared_dictionary/shared_dictionary_manager_unittest.cc
+++ b/services/network/shared_dictionary/shared_dictionary_manager_unittest.cc
@@ -16,7 +16,6 @@
 #include "base/strings/strcat.h"
 #include "base/strings/stringprintf.h"
 #include "base/test/bind.h"
-#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/test/test_future.h"
 #include "base/time/time.h"
@@ -92,16 +91,6 @@
   }
 }
 
-std::string ToString(
-    features::CompressionDictionaryTransportBackendVersion version) {
-  switch (version) {
-    case features::CompressionDictionaryTransportBackendVersion::kV1:
-      return "V1";
-    case features::CompressionDictionaryTransportBackendVersion::kV2:
-      return "V2";
-  }
-}
-
 void CheckDiskCacheEntryDataEquals(
     SharedDictionaryDiskCache& disk_cache,
     const base::UnguessableToken& disk_cache_key_token,
@@ -156,12 +145,8 @@
 }
 
 base::TimeDelta GetDefaultExpiration() {
-  if (features::kCompressionDictionaryTransportBackendVersion.Get() ==
-      features::CompressionDictionaryTransportBackendVersion::kV2) {
-    return base::Seconds(2592000);  // See kDefaultCacheControlHeader
-  }
   return base::FeatureList::IsEnabled(features::kCompressionDictionaryTransport)
-             ? shared_dictionary::kDefaultExpiration
+             ? base::Seconds(2592000)
              : shared_dictionary::kMaxExpirationForOriginTrial;
 }
 
@@ -169,19 +154,9 @@
 
 class SharedDictionaryManagerTest
     : public ::testing::Test,
-      public ::testing::WithParamInterface<
-          std::tuple<TestManagerType,
-                     features::CompressionDictionaryTransportBackendVersion>> {
+      public ::testing::WithParamInterface<TestManagerType> {
  public:
-  SharedDictionaryManagerTest() {
-    std::vector<base::test::FeatureRefAndParams> enabled_features;
-    enabled_features.emplace_back(base::test::FeatureRefAndParams(
-        features::kCompressionDictionaryTransportBackend,
-        {{features::kCompressionDictionaryTransportBackendVersion.name,
-          features::kCompressionDictionaryTransportBackendVersion.GetName(
-              GetVersion())}}));
-    scoped_feature_list_.InitWithFeaturesAndParameters(enabled_features, {});
-  }
+  SharedDictionaryManagerTest() = default;
   ~SharedDictionaryManagerTest() override = default;
 
   SharedDictionaryManagerTest(const SharedDictionaryManagerTest&) = delete;
@@ -203,10 +178,7 @@
   }
 
  protected:
-  TestManagerType GetManagerType() const { return std::get<0>(GetParam()); }
-  features::CompressionDictionaryTransportBackendVersion GetVersion() const {
-    return std::get<1>(GetParam());
-  }
+  TestManagerType GetManagerType() const { return GetParam(); }
   std::unique_ptr<SharedDictionaryManager> CreateSharedDictionaryManager() {
     switch (GetManagerType()) {
       case TestManagerType::kInMemory:
@@ -267,22 +239,14 @@
   base::ScopedTempDir tmp_directory_;
   base::FilePath database_path_;
   base::FilePath cache_directory_path_;
-  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 INSTANTIATE_TEST_SUITE_P(
     All,
     SharedDictionaryManagerTest,
-    ::testing::Combine(
-        testing::Values(TestManagerType::kInMemory, TestManagerType::kOnDisk),
-        testing::Values(
-            features::CompressionDictionaryTransportBackendVersion::kV1,
-            features::CompressionDictionaryTransportBackendVersion::kV2)),
-    [](const testing::TestParamInfo<std::tuple<
-           TestManagerType,
-           features::CompressionDictionaryTransportBackendVersion>>& info) {
-      return ToString(std::get<0>(info.param)) + "_" +
-             ToString(std::get<1>(info.param));
+    testing::ValuesIn({TestManagerType::kInMemory, TestManagerType::kOnDisk}),
+    [](const testing::TestParamInfo<TestManagerType>& info) {
+      return ToString(info.param);
     });
 
 TEST_P(SharedDictionaryManagerTest, SameStorageForSameIsolationKey) {
@@ -624,60 +588,7 @@
   }
 }
 
-TEST_P(SharedDictionaryManagerTest,
-       WriterForUseAsDictionaryHeaderExpiresOption) {
-  // We don't support `expires` option in the V2 backend.
-  if (GetVersion() ==
-      features::CompressionDictionaryTransportBackendVersion::kV2) {
-    return;
-  }
-  std::unique_ptr<SharedDictionaryManager> manager =
-      CreateSharedDictionaryManager();
-  net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl1),
-                                                  kSite1);
-
-  scoped_refptr<SharedDictionaryStorage> storage =
-      manager->GetStorage(isolation_key);
-  ASSERT_TRUE(storage);
-
-  struct {
-    std::string header_string;
-    bool expect_success;
-  } kTestCases[] = {
-      // Valid `expires` value.
-      {"match=\"test\", expires=1000", true},
-      // List `expires` value is not supported.
-      {"match=\"test\", expires=(1000 2000)", false},
-      // String `expires` value is not supported.
-      {"match=\"test\", expires=PI", false},
-  };
-  for (const auto& testcase : kTestCases) {
-    SCOPED_TRACE(base::StringPrintf("header_string: %s",
-                                    testcase.header_string.c_str()));
-    scoped_refptr<net::HttpResponseHeaders> headers =
-        net::HttpResponseHeaders::TryToCreate(base::StrCat(
-            {"HTTP/1.1 200 OK\n", shared_dictionary::kUseAsDictionaryHeaderName,
-             ": ", testcase.header_string, "\n\n"}));
-    ASSERT_TRUE(headers);
-    scoped_refptr<SharedDictionaryWriter> writer = storage->MaybeCreateWriter(
-        GURL("https://origin1.test/testfile.txt"),
-        /*request_time=*/base::Time::Now(), /*response_time=*/base::Time::Now(),
-        *headers,
-        /*was_fetched_via_cache=*/false,
-        /*access_allowed_check_callback=*/base::BindOnce([]() {
-          return true;
-        }));
-    EXPECT_EQ(testcase.expect_success, !!writer);
-  }
-}
-
 TEST_P(SharedDictionaryManagerTest, DictionaryLifetimeFromCacheControlHeader) {
-  // We don't use the cache conterol header for the lifetime of the dictionary
-  // in the V1 backend.
-  if (GetVersion() ==
-      features::CompressionDictionaryTransportBackendVersion::kV1) {
-    return;
-  }
   std::unique_ptr<SharedDictionaryManager> manager =
       CreateSharedDictionaryManager();
   net::SharedDictionaryIsolationKey isolation_key(url::Origin::Create(kUrl1),
@@ -744,30 +655,27 @@
 
   struct {
     std::string header_string;
-    bool expect_success_v1;
-    bool expect_success_v2;
+    bool expect_success;
     std::string expected_id;
   } kTestCases[] = {
       // Valid `id` value.
-      {"match=\"test\", id=\"test_id\"", /*expect_success_v1=*/true,
-       /*expect_success_v2=*/true, /*expected_id=*/"test_id"},
+      {"match=\"test\", id=\"test_id\"",
+       /*expect_success=*/true, /*expected_id=*/"test_id"},
       // Valid `id` value with backslash.
-      {"match=\"test\", id=\"test\\\\id\"", /*expect_success_v1=*/true,
-       /*expect_success_v2=*/true, /*expected_id=*/"test\\id"},
+      {"match=\"test\", id=\"test\\\\id\"",
+       /*expect_success=*/true, /*expected_id=*/"test\\id"},
       // Valid `id` value with double quote.
-      {"match=\"test\", id=\"test\\\"id\"", /*expect_success_v1=*/true,
-       /*expect_success_v2=*/true, /*expected_id=*/"test\"id"},
+      {"match=\"test\", id=\"test\\\"id\"",
+       /*expect_success=*/true, /*expected_id=*/"test\"id"},
       // `id` should not be a list.
-      {"match=\"test\", id=(\"id1\" \"id2\")", /*expect_success_v1=*/true,
-       /*expect_success_v2=*/false},
+      {"match=\"test\", id=(\"id1\" \"id2\")",
+       /*expect_success=*/false},
       // `id` can be 1024 characters long.
       {base::StrCat({"match=\"test\", id=\"", std::string(1024, 'x'), "\""}),
-       /*expect_success_v1=*/true,
-       /*expect_success_v2=*/true, /*expected_id=*/std::string(1024, 'x')},
+       /*expect_success=*/true, /*expected_id=*/std::string(1024, 'x')},
       // `id` too long.
       {base::StrCat({"match=\"test\", id=\"", std::string(1025, 'x'), "\""}),
-       /*expect_success_v1=*/true,
-       /*expect_success_v2=*/false},
+       /*expect_success=*/false},
   };
   for (const auto& testcase : kTestCases) {
     SCOPED_TRACE(base::StringPrintf("header_string: %s",
@@ -786,14 +694,7 @@
         /*access_allowed_check_callback=*/base::BindOnce([]() {
           return true;
         }));
-    switch (GetVersion()) {
-      case features::CompressionDictionaryTransportBackendVersion::kV1:
-        EXPECT_EQ(testcase.expect_success_v1, !!writer);
-        continue;
-      case features::CompressionDictionaryTransportBackendVersion::kV2:
-        EXPECT_EQ(testcase.expect_success_v2, !!writer);
-        break;
-    }
+    EXPECT_EQ(testcase.expect_success, !!writer);
     if (!writer) {
       continue;
     }
@@ -824,43 +725,40 @@
 
   struct {
     std::string header_string;
-    bool expect_success_v1;
-    bool expect_success_v2;
+    bool expect_success;
     std::vector<mojom::RequestDestination> expected_match_dest;
   } kTestCases[] = {
       // No `match-dest` value.
-      {"match=\"test\"", /*expect_success_v1=*/true,
-       /*expect_success_v2=*/true, /*expected_match_dest=*/{}},
+      {"match=\"test\"",
+       /*expect_success=*/true, /*expected_match_dest=*/{}},
       // Valid `match-dest` value.
-      {"match=\"test\", match-dest=(\"document\")", /*expect_success_v1=*/true,
-       /*expect_success_v2=*/true,
+      {"match=\"test\", match-dest=(\"document\")",
+       /*expect_success=*/true,
        /*expected_match_dest=*/{mojom::RequestDestination::kDocument}},
       // `match-dest` must be a list.
-      {"match=\"test\", match-dest=\"document\"", /*expect_success_v1=*/true,
-       /*expect_success_v2=*/false},
+      {"match=\"test\", match-dest=\"document\"",
+       /*expect_success=*/false},
       // Unknown `match-dest` value should be treated as empty.
-      {"match=\"test\", match-dest=(\"unknown\")", /*expect_success_v1=*/true,
-       /*expect_success_v2=*/true,
+      {"match=\"test\", match-dest=(\"unknown\")",
+       /*expect_success=*/true,
        /*expected_match_dest=*/{}},
       //`match-dest` should not be a sf-token.
       // https://github.com/httpwg/http-extensions/issues/2723
-      {"match=\"test\", match-dest=(document)", /*expect_success_v1=*/true,
-       /*expect_success_v2=*/false},
+      {"match=\"test\", match-dest=(document)",
+       /*expect_success=*/false},
       // Valid `match-dest` value "".
-      {"match=\"test\", match-dest=(\"\")", /*expect_success_v1=*/true,
-       /*expect_success_v2=*/true,
+      {"match=\"test\", match-dest=(\"\")",
+       /*expect_success=*/true,
        /*expected_match_dest=*/{mojom::RequestDestination::kEmpty}},
       // Valid `match-dest` value ("document" "frame" "iframe").
       {"match=\"test\", match-dest=(\"document\" \"frame\" \"iframe\")",
-       /*expect_success_v1=*/true,
-       /*expect_success_v2=*/true,
+       /*expect_success=*/true,
        /*expected_match_dest=*/
        {mojom::RequestDestination::kDocument, mojom::RequestDestination::kFrame,
         mojom::RequestDestination::kIframe}},
       // Valid `match-dest` value ("document" "frame" "iframe" "").
       {"match=\"test\", match-dest=(\"document\" \"\")",
-       /*expect_success_v1=*/true,
-       /*expect_success_v2=*/true,
+       /*expect_success=*/true,
        /*expected_match_dest=*/
        {mojom::RequestDestination::kEmpty,
         mojom::RequestDestination::kDocument}},
@@ -886,14 +784,7 @@
         /*access_allowed_check_callback=*/base::BindOnce([]() {
           return true;
         }));
-    switch (GetVersion()) {
-      case features::CompressionDictionaryTransportBackendVersion::kV1:
-        EXPECT_EQ(testcase.expect_success_v1, !!writer);
-        continue;
-      case features::CompressionDictionaryTransportBackendVersion::kV2:
-        EXPECT_EQ(testcase.expect_success_v2, !!writer);
-        break;
-    }
+    EXPECT_EQ(testcase.expect_success, !!writer);
     if (!writer) {
       continue;
     }
@@ -922,13 +813,12 @@
   ASSERT_TRUE(storage);
   struct {
     std::string header_string;
-    bool expect_success_v1;
-    bool expect_success_v2;
+    bool expect_success;
   } kTestCases[] = {
       // Invalid as a constructor string of URLPattern.
-      {"{", true, false},
+      {"{", false},
       // Unsupported regexp group.
-      {"(a|b)", true, false},
+      {"(a|b)", false},
   };
   for (const auto& testcase : kTestCases) {
     SCOPED_TRACE(
@@ -947,14 +837,7 @@
         /*access_allowed_check_callback=*/base::BindOnce([]() {
           return true;
         }));
-    switch (GetVersion()) {
-      case features::CompressionDictionaryTransportBackendVersion::kV1:
-        EXPECT_EQ(testcase.expect_success_v1, !!writer);
-        break;
-      case features::CompressionDictionaryTransportBackendVersion::kV2:
-        EXPECT_EQ(testcase.expect_success_v2, !!writer);
-        break;
-    }
+    EXPECT_EQ(testcase.expect_success, !!writer);
   }
 }
 
diff --git a/services/network/shared_dictionary/shared_dictionary_network_transaction.cc b/services/network/shared_dictionary/shared_dictionary_network_transaction.cc
index 8c78b5091..66f31e68a 100644
--- a/services/network/shared_dictionary/shared_dictionary_network_transaction.cc
+++ b/services/network/shared_dictionary/shared_dictionary_network_transaction.cc
@@ -153,11 +153,9 @@
     result = SharedDictionaryEncodingType::kSharedZstd;
   }
 
-  // Check "Content-Dictionary" header if V2 backend is enabled, and the
-  // content encoding indicates that a dictionary is used.
-  if (features::kCompressionDictionaryTransportBackendVersion.Get() !=
-          features::CompressionDictionaryTransportBackendVersion::kV1 &&
-      result != SharedDictionaryEncodingType::kNotUsed) {
+  // Check "Content-Dictionary" header when the content encoding indicates that
+  // a dictionary is used.
+  if (result != SharedDictionaryEncodingType::kNotUsed) {
     CHECK(!dictionary_hash_base64_.empty());
     std::string content_dictionary;
     if (!headers.GetNormalizedHeader(
@@ -262,21 +260,11 @@
     shared_dictionary_.reset();
     return;
   }
-
-  switch (features::kCompressionDictionaryTransportBackendVersion.Get()) {
-    case features::CompressionDictionaryTransportBackendVersion::kV1:
-      request_headers->SetHeader(
-          network::shared_dictionary::kSecAvailableDictionaryHeaderName,
-          base::ToLowerASCII(base::HexEncode(shared_dictionary_->hash().data)));
-      break;
-    case features::CompressionDictionaryTransportBackendVersion::kV2:
-      dictionary_hash_base64_ = base::StrCat(
-          {":", base::Base64Encode(shared_dictionary_->hash().data), ":"});
-      request_headers->SetHeader(
-          network::shared_dictionary::kAvailableDictionaryHeaderName,
-          dictionary_hash_base64_);
-      break;
-  }
+  dictionary_hash_base64_ = base::StrCat(
+      {":", base::Base64Encode(shared_dictionary_->hash().data), ":"});
+  request_headers->SetHeader(
+      network::shared_dictionary::kAvailableDictionaryHeaderName,
+      dictionary_hash_base64_);
   if (base::FeatureList::IsEnabled(network::features::kSharedZstd)) {
     AddAcceptEncoding(request_headers,
                       base::StrCat({GetSharedBrotliContentEncodingName(), ", ",
diff --git a/services/network/shared_dictionary/shared_dictionary_network_transaction.h b/services/network/shared_dictionary/shared_dictionary_network_transaction.h
index 21f8b7cc..3de3c51 100644
--- a/services/network/shared_dictionary/shared_dictionary_network_transaction.h
+++ b/services/network/shared_dictionary/shared_dictionary_network_transaction.h
@@ -153,7 +153,7 @@
   scoped_refptr<SharedDictionaryStorage> shared_dictionary_storage_;
   std::unique_ptr<SharedDictionary> shared_dictionary_;
   // The Structured Field sf-binary hash of sha256 of dictionary calculated when
-  // sending a HTTP request. This is not used when V1 backend is used.
+  // sending a HTTP request.
   std::string dictionary_hash_base64_;
 
   DictionaryStatus dictionary_status_ = DictionaryStatus::kNoDictionary;
diff --git a/services/network/shared_dictionary/shared_dictionary_network_transaction_unittest.cc b/services/network/shared_dictionary/shared_dictionary_network_transaction_unittest.cc
index 52e39e3..d6a49a6 100644
--- a/services/network/shared_dictionary/shared_dictionary_network_transaction_unittest.cc
+++ b/services/network/shared_dictionary/shared_dictionary_network_transaction_unittest.cc
@@ -224,20 +224,10 @@
                                          std::string* response_headers,
                                          std::string* response_data) {
   std::string header_value;
-  switch (features::kCompressionDictionaryTransportBackendVersion.Get()) {
-    case features::CompressionDictionaryTransportBackendVersion::kV1:
-      EXPECT_TRUE(request->extra_headers.GetHeader(
-          network::shared_dictionary::kSecAvailableDictionaryHeaderName,
-          &header_value));
-      EXPECT_EQ(kTestDictionarySha256, header_value);
-      break;
-    case features::CompressionDictionaryTransportBackendVersion::kV2:
-      EXPECT_TRUE(request->extra_headers.GetHeader(
-          network::shared_dictionary::kAvailableDictionaryHeaderName,
-          &header_value));
-      EXPECT_EQ(kTestDictionarySha256Base64, header_value);
-      break;
-  }
+  EXPECT_TRUE(request->extra_headers.GetHeader(
+      network::shared_dictionary::kAvailableDictionaryHeaderName,
+      &header_value));
+  EXPECT_EQ(kTestDictionarySha256Base64, header_value);
   *response_data = kBrotliEncodedDataString;
 }
 
@@ -246,20 +236,10 @@
                                        std::string* response_headers,
                                        std::string* response_data) {
   std::string header_value;
-  switch (features::kCompressionDictionaryTransportBackendVersion.Get()) {
-    case features::CompressionDictionaryTransportBackendVersion::kV1:
-      EXPECT_TRUE(request->extra_headers.GetHeader(
-          network::shared_dictionary::kSecAvailableDictionaryHeaderName,
-          &header_value));
-      EXPECT_EQ(kTestDictionarySha256, header_value);
-      break;
-    case features::CompressionDictionaryTransportBackendVersion::kV2:
       EXPECT_TRUE(request->extra_headers.GetHeader(
           network::shared_dictionary::kAvailableDictionaryHeaderName,
           &header_value));
       EXPECT_EQ(kTestDictionarySha256Base64, header_value);
-      break;
-  }
   *response_data = kZstdEncodedDataString;
 }
 
@@ -269,37 +249,11 @@
                            std::string* response_headers,
                            std::string* response_data) {
       EXPECT_FALSE(request->extra_headers.HasHeader(
-          network::shared_dictionary::kSecAvailableDictionaryHeaderName));
+          network::shared_dictionary::kAvailableDictionaryHeaderName));
       *response_data = kTestData;
     });
 
-const net::MockTransaction kBrotliDictionaryTestTransactionV1 = {
-    .url = "https://test.example/test",
-    .method = "GET",
-    .request_time = base::Time(),
-    .request_headers = "sec-fetch-dest: document\r\n",
-    .load_flags = net::LOAD_CAN_USE_SHARED_DICTIONARY,
-    .transport_info = TestSpdyTransportInfo(),
-    .status = "HTTP/1.1 200 OK",
-    .response_headers =
-        "content-encoding: sbr\n"
-        "content-dictionary: :wZcortNlA8/IGg9TWeb0cuEh93vyCi+qx5lBkSk8BiM=:\n",
-    .response_time = base::Time(),
-    .data = "",  // We set the body in the `handler` function.
-    .dns_aliases = {},
-    .fps_cache_filter = std::nullopt,
-    .browser_run_id = std::nullopt,
-    .test_mode = net::TEST_MODE_NORMAL,
-    .handler = base::BindRepeating(&BrotliTestTransactionHandler),
-    .read_handler = net::MockTransactionReadHandler(),
-    .cert = nullptr,
-    .cert_status = 0,
-    .ssl_connection_status = 0,
-    .start_return_code = net::OK,
-    .read_return_code = net::OK,
-};
-
-const net::MockTransaction kBrotliDictionaryTestTransactionV2 = {
+const net::MockTransaction kBrotliDictionaryTestTransaction = {
     .url = "https://test.example/test",
     .method = "GET",
     .request_time = base::Time(),
@@ -351,42 +305,20 @@
     .read_return_code = net::OK,
 };
 
-class SharedDictionaryNetworkTransactionTestBase : public ::testing::Test {
+class SharedDictionaryNetworkTransactionTest : public ::testing::Test {
  public:
-  explicit SharedDictionaryNetworkTransactionTestBase(
-      network::features::CompressionDictionaryTransportBackendVersion version)
-      : version_(version),
-        network_layer_(std::make_unique<net::MockNetworkLayer>()) {
-    scoped_feature_list_.InitWithFeaturesAndParameters(
-        /*enabled_features=*/
-        {base::test::FeatureRefAndParams(
-            network::features::kCompressionDictionaryTransportBackend,
-            {{network::features::kCompressionDictionaryTransportBackendVersion
-                  .name,
-              network::features::kCompressionDictionaryTransportBackendVersion
-                  .GetName(GetVersion())}})},
-        /*disabled_features=*/{});
-    net::AddMockTransaction(&GetBrotliDictionaryTestTransaction());
+  SharedDictionaryNetworkTransactionTest()
+      : network_layer_(std::make_unique<net::MockNetworkLayer>()) {
+    net::AddMockTransaction(&kBrotliDictionaryTestTransaction);
   }
-  ~SharedDictionaryNetworkTransactionTestBase() override = default;
+  ~SharedDictionaryNetworkTransactionTest() override = default;
 
-  SharedDictionaryNetworkTransactionTestBase(
-      const SharedDictionaryNetworkTransactionTestBase&) = delete;
-  SharedDictionaryNetworkTransactionTestBase& operator=(
-      const SharedDictionaryNetworkTransactionTestBase&) = delete;
+  SharedDictionaryNetworkTransactionTest(
+      const SharedDictionaryNetworkTransactionTest&) = delete;
+  SharedDictionaryNetworkTransactionTest& operator=(
+      const SharedDictionaryNetworkTransactionTest&) = delete;
 
  protected:
-  network::features::CompressionDictionaryTransportBackendVersion GetVersion() {
-    return version_;
-  }
-  const net::MockTransaction& GetBrotliDictionaryTestTransaction() {
-    switch (GetVersion()) {
-      case network::features::CompressionDictionaryTransportBackendVersion::kV1:
-        return kBrotliDictionaryTestTransactionV1;
-      case network::features::CompressionDictionaryTransportBackendVersion::kV2:
-        return kBrotliDictionaryTestTransactionV2;
-    }
-  }
   std::unique_ptr<net::HttpTransaction> CreateNetworkTransaction() {
     std::unique_ptr<net::HttpTransaction> network_transaction;
     network_layer_->CreateTransaction(net::DEFAULT_PRIORITY,
@@ -399,59 +331,17 @@
   net::MockNetworkLayer& network_layer() { return *network_layer_.get(); }
 
  private:
-  const network::features::CompressionDictionaryTransportBackendVersion
-      version_;
   std::unique_ptr<net::MockNetworkLayer> network_layer_;
   base::test::TaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
-  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
-class SharedDictionaryNetworkTransactionTest
-    : public SharedDictionaryNetworkTransactionTestBase,
-      public ::testing::WithParamInterface<
-          network::features::CompressionDictionaryTransportBackendVersion> {
- public:
-  SharedDictionaryNetworkTransactionTest()
-      : SharedDictionaryNetworkTransactionTestBase(GetVersion()) {}
-  ~SharedDictionaryNetworkTransactionTest() override = default;
-
-  SharedDictionaryNetworkTransactionTest(
-      const SharedDictionaryNetworkTransactionTest&) = delete;
-  SharedDictionaryNetworkTransactionTest& operator=(
-      const SharedDictionaryNetworkTransactionTest&) = delete;
-
- protected:
-  network::features::CompressionDictionaryTransportBackendVersion GetVersion() {
-    return GetParam();
-  }
-};
-
-INSTANTIATE_TEST_SUITE_P(
-    All,
-    SharedDictionaryNetworkTransactionTest,
-    testing::Values(
-        network::features::CompressionDictionaryTransportBackendVersion::kV1,
-        network::features::CompressionDictionaryTransportBackendVersion::kV2),
-    [](const testing::TestParamInfo<
-        network::features::CompressionDictionaryTransportBackendVersion>&
-           info) {
-      switch (info.param) {
-        case network::features::CompressionDictionaryTransportBackendVersion::
-            kV1:
-          return "V1";
-        case network::features::CompressionDictionaryTransportBackendVersion::
-            kV2:
-          return "V2";
-      }
-    });
-
-TEST_P(SharedDictionaryNetworkTransactionTest, SyncDictionary) {
+TEST_F(SharedDictionaryNetworkTransactionTest, SyncDictionary) {
   DummySharedDictionaryManager manager(
       base::MakeRefCounted<DummySharedDictionaryStorage>(
           std::make_unique<DummySyncDictionary>(kTestDictionaryData)));
 
-  net::MockHttpRequest request(GetBrotliDictionaryTestTransaction());
+  net::MockHttpRequest request(kBrotliDictionaryTestTransaction);
   SharedDictionaryNetworkTransaction transaction(manager,
                                                  CreateNetworkTransaction());
   transaction.SetIsSharedDictionaryReadAllowedCallback(
@@ -474,15 +364,14 @@
   EXPECT_EQ(kTestData, std::string(buf->data(), read_result));
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest, NotAllowedToUseDictionary) {
+TEST_F(SharedDictionaryNetworkTransactionTest, NotAllowedToUseDictionary) {
   DummySharedDictionaryManager manager(
       base::MakeRefCounted<DummySharedDictionaryStorage>(
           std::make_unique<DummySyncDictionary>(kTestDictionaryData)));
 
   // Override MockTransaction to check that there is no available-dictionary
   // header.
-  net::MockTransaction new_mock_transaction =
-      GetBrotliDictionaryTestTransaction();
+  net::MockTransaction new_mock_transaction = kBrotliDictionaryTestTransaction;
   new_mock_transaction.handler =
       kTestTransactionHandlerWithoutAvailableDictionary;
   net::AddMockTransaction(&new_mock_transaction);
@@ -510,15 +399,14 @@
   EXPECT_EQ(kTestData, std::string(buf->data(), read_result));
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest, DictionaryId) {
+TEST_F(SharedDictionaryNetworkTransactionTest, DictionaryId) {
   DummySharedDictionaryManager manager(
       base::MakeRefCounted<DummySharedDictionaryStorage>(
           std::make_unique<DummySyncDictionary>(kTestDictionaryData,
                                                 "test-id")));
 
   // Override MockTransaction to check the dictionary-id header
-  net::MockTransaction new_mock_transaction =
-      GetBrotliDictionaryTestTransaction();
+  net::MockTransaction new_mock_transaction = kBrotliDictionaryTestTransaction;
   new_mock_transaction.handler = base::BindRepeating(
       [](const net::HttpRequestInfo* request, std::string* response_status,
          std::string* response_headers, std::string* response_data) {
@@ -553,7 +441,7 @@
   EXPECT_EQ(kTestData, std::string(buf->data(), read_result));
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest,
+TEST_F(SharedDictionaryNetworkTransactionTest,
        DictionaryIdWithBackSlashAndDquote) {
   DummySharedDictionaryManager manager(
       base::MakeRefCounted<DummySharedDictionaryStorage>(
@@ -561,8 +449,7 @@
                                                 "test\\dictionary\"id")));
 
   // Override MockTransaction to check the dictionary-id header
-  net::MockTransaction new_mock_transaction =
-      GetBrotliDictionaryTestTransaction();
+  net::MockTransaction new_mock_transaction = kBrotliDictionaryTestTransaction;
   new_mock_transaction.handler = base::BindRepeating(
       [](const net::HttpRequestInfo* request, std::string* response_status,
          std::string* response_headers, std::string* response_data) {
@@ -597,14 +484,13 @@
   EXPECT_EQ(kTestData, std::string(buf->data(), read_result));
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest, EmptyDictionaryId) {
+TEST_F(SharedDictionaryNetworkTransactionTest, EmptyDictionaryId) {
   DummySharedDictionaryManager manager(
       base::MakeRefCounted<DummySharedDictionaryStorage>(
           std::make_unique<DummySyncDictionary>(kTestDictionaryData, "")));
 
   // Override MockTransaction to check the dictionary-id header
-  net::MockTransaction new_mock_transaction =
-      GetBrotliDictionaryTestTransaction();
+  net::MockTransaction new_mock_transaction = kBrotliDictionaryTestTransaction;
   new_mock_transaction.handler = base::BindRepeating(
       [](const net::HttpRequestInfo* request, std::string* response_status,
          std::string* response_headers, std::string* response_data) {
@@ -636,7 +522,7 @@
   EXPECT_EQ(kTestData, std::string(buf->data(), read_result));
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest,
+TEST_F(SharedDictionaryNetworkTransactionTest,
        RequireKnownRootCertCheckFailure) {
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndEnableFeature(
@@ -647,8 +533,7 @@
 
   // Override MockTransaction to check that there is no available-dictionary
   // header.
-  net::MockTransaction new_mock_transaction =
-      GetBrotliDictionaryTestTransaction();
+  net::MockTransaction new_mock_transaction = kBrotliDictionaryTestTransaction;
   new_mock_transaction.handler =
       kTestTransactionHandlerWithoutAvailableDictionary;
   new_mock_transaction.transport_info.cert_is_issued_by_known_root = false;
@@ -678,7 +563,7 @@
   EXPECT_EQ(kTestData, std::string(buf->data(), read_result));
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest,
+TEST_F(SharedDictionaryNetworkTransactionTest,
        RequireKnownRootCertCheckSuccess) {
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndEnableFeature(
@@ -689,8 +574,7 @@
 
   // The BrotliTestTransactionHandler `new_mock_transaction.handler` will check
   // that the there is a correct available-dictionary request header.
-  net::MockTransaction new_mock_transaction =
-      GetBrotliDictionaryTestTransaction();
+  net::MockTransaction new_mock_transaction = kBrotliDictionaryTestTransaction;
   new_mock_transaction.transport_info.cert_is_issued_by_known_root = true;
 
   net::AddMockTransaction(&new_mock_transaction);
@@ -718,7 +602,7 @@
   EXPECT_EQ(kTestData, std::string(buf->data(), read_result));
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest,
+TEST_F(SharedDictionaryNetworkTransactionTest,
        RequireKnownRootCertCheckSuccessForLocalhost) {
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndEnableFeature(
@@ -729,8 +613,7 @@
 
   // The BrotliTestTransactionHandler `new_mock_transaction.handler` will check
   // that the there is a correct available-dictionary request header.
-  net::MockTransaction new_mock_transaction =
-      GetBrotliDictionaryTestTransaction();
+  net::MockTransaction new_mock_transaction = kBrotliDictionaryTestTransaction;
   new_mock_transaction.url = "http:///localhost:1234/test";
   new_mock_transaction.transport_info.cert_is_issued_by_known_root = false;
 
@@ -759,14 +642,13 @@
   EXPECT_EQ(kTestData, std::string(buf->data(), read_result));
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest, NoMatchingDictionary) {
+TEST_F(SharedDictionaryNetworkTransactionTest, NoMatchingDictionary) {
   DummySharedDictionaryManager manager(
       base::MakeRefCounted<DummySharedDictionaryStorage>(nullptr));
 
   // Override MockTransaction to check that there is no available-dictionary
   // header.
-  net::MockTransaction new_mock_transaction =
-      GetBrotliDictionaryTestTransaction();
+  net::MockTransaction new_mock_transaction = kBrotliDictionaryTestTransaction;
   new_mock_transaction.handler =
       kTestTransactionHandlerWithoutAvailableDictionary;
   net::AddMockTransaction(&new_mock_transaction);
@@ -794,15 +676,14 @@
   EXPECT_EQ(kTestData, std::string(buf->data(), read_result));
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest, OpaqueFrameOrigin) {
+TEST_F(SharedDictionaryNetworkTransactionTest, OpaqueFrameOrigin) {
   DummySharedDictionaryManager manager(
       base::MakeRefCounted<DummySharedDictionaryStorage>(
           std::make_unique<DummySyncDictionary>(kTestDictionaryData)));
 
   // Override MockTransaction to check that there is no available-dictionary
   // header.
-  net::MockTransaction new_mock_transaction =
-      GetBrotliDictionaryTestTransaction();
+  net::MockTransaction new_mock_transaction = kBrotliDictionaryTestTransaction;
   new_mock_transaction.handler =
       kTestTransactionHandlerWithoutAvailableDictionary;
   net::AddMockTransaction(&new_mock_transaction);
@@ -831,13 +712,12 @@
   EXPECT_EQ(kTestData, std::string(buf->data(), read_result));
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest, WithoutValidLoadFlag) {
+TEST_F(SharedDictionaryNetworkTransactionTest, WithoutValidLoadFlag) {
   DummySharedDictionaryManager manager(/*storage=*/nullptr);
 
   // Override MockTransaction to check that there is no available-dictionary
   // header.
-  net::MockTransaction new_mock_transaction =
-      GetBrotliDictionaryTestTransaction();
+  net::MockTransaction new_mock_transaction = kBrotliDictionaryTestTransaction;
   new_mock_transaction.handler =
       kTestTransactionHandlerWithoutAvailableDictionary;
   net::AddMockTransaction(&new_mock_transaction);
@@ -871,14 +751,13 @@
   EXPECT_FALSE(manager.create_storage_called());
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest, NoSbrContentEncoding) {
+TEST_F(SharedDictionaryNetworkTransactionTest, NoSbrContentEncoding) {
   DummySharedDictionaryManager manager(
       base::MakeRefCounted<DummySharedDictionaryStorage>(
           std::make_unique<DummySyncDictionary>(kTestDictionaryData)));
 
   // Override MockTransaction to remove `content-encoding: sbr`.
-  net::MockTransaction new_mock_transaction =
-      GetBrotliDictionaryTestTransaction();
+  net::MockTransaction new_mock_transaction = kBrotliDictionaryTestTransaction;
   new_mock_transaction.response_headers = "";
   net::AddMockTransaction(&new_mock_transaction);
 
@@ -908,23 +787,14 @@
   EXPECT_EQ(kBrotliEncodedDataString, std::string(buf->data(), read_result));
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest, NoContentDictionary) {
+TEST_F(SharedDictionaryNetworkTransactionTest, NoContentDictionary) {
   DummySharedDictionaryManager manager(
       base::MakeRefCounted<DummySharedDictionaryStorage>(
           std::make_unique<DummySyncDictionary>(kTestDictionaryData)));
 
   // Override MockTransaction to remove "content-dictionary" header.
-  net::MockTransaction new_mock_transaction =
-      GetBrotliDictionaryTestTransaction();
-
-  switch (GetVersion()) {
-    case network::features::CompressionDictionaryTransportBackendVersion::kV1:
-      new_mock_transaction.response_headers = "content-encoding: sbr\n";
-      break;
-    case network::features::CompressionDictionaryTransportBackendVersion::kV2:
-      new_mock_transaction.response_headers = "content-encoding: br-d\n";
-      break;
-  }
+  net::MockTransaction new_mock_transaction = kBrotliDictionaryTestTransaction;
+  new_mock_transaction.response_headers = "content-encoding: br-d\n";
   net::AddMockTransaction(&new_mock_transaction);
 
   net::MockHttpRequest request(new_mock_transaction);
@@ -937,56 +807,26 @@
   ASSERT_THAT(transaction.Start(&request, start_callback.callback(),
                                 net::NetLogWithSource()),
               net::test::IsError(net::ERR_IO_PENDING));
-
-  if (GetVersion() ==
-      network::features::CompressionDictionaryTransportBackendVersion::kV2) {
-    EXPECT_THAT(start_callback.WaitForResult(),
-                net::test::IsError(net::ERR_DICTIONARY_LOAD_FAILED));
-    return;
-  }
-
-  // When V1 backend is used, even if there is no "content-dictionary"
-  // header, SharedDictionaryNetworkTransaction can decode the body.
-  EXPECT_THAT(start_callback.WaitForResult(), net::test::IsError(net::OK));
-
-  scoped_refptr<net::IOBufferWithSize> buf =
-      base::MakeRefCounted<net::IOBufferWithSize>(kDefaultBufferSize);
-  net::TestCompletionCallback read_callback;
-  ASSERT_THAT(
-      transaction.Read(buf.get(), buf->size(), read_callback.callback()),
-      net::test::IsError(net::ERR_IO_PENDING));
-  int read_result = read_callback.WaitForResult();
-  EXPECT_THAT(read_result, kTestData.size());
-  EXPECT_EQ(kTestData, std::string(buf->data(), read_result));
+  EXPECT_THAT(start_callback.WaitForResult(),
+              net::test::IsError(net::ERR_DICTIONARY_LOAD_FAILED));
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest, WrongContentDictionary) {
+TEST_F(SharedDictionaryNetworkTransactionTest, WrongContentDictionary) {
   DummySharedDictionaryManager manager(
       base::MakeRefCounted<DummySharedDictionaryStorage>(
           std::make_unique<DummySyncDictionary>(kTestDictionaryData)));
 
   // Override MockTransaction to change the "content-dictionary" header.
-  net::MockTransaction new_mock_transaction =
-      GetBrotliDictionaryTestTransaction();
+  net::MockTransaction new_mock_transaction = kBrotliDictionaryTestTransaction;
 
   // The hash `kTestDictionaryData` is
   // ":wZcortNlA8/IGg9TWeb0cuEh93vyCi+qx5lBkSk8BiM=:". But the header contains
   // "content-dictionary" header with a different hash
   // ":U5abz16WDg7b8KS93msLPpOB4Vbef1uRzoORYkJw9BY=:".
-  switch (GetVersion()) {
-    case network::features::CompressionDictionaryTransportBackendVersion::kV1:
-      new_mock_transaction.response_headers =
-          "content-encoding: sbr\n"
-          "content-dictionary: "
-          ":U5abz16WDg7b8KS93msLPpOB4Vbef1uRzoORYkJw9BY=:\n";
-      break;
-    case network::features::CompressionDictionaryTransportBackendVersion::kV2:
-      new_mock_transaction.response_headers =
-          "content-encoding: br-d\n"
-          "content-dictionary: "
-          ":U5abz16WDg7b8KS93msLPpOB4Vbef1uRzoORYkJw9BY=:\n";
-      break;
-  }
+  new_mock_transaction.response_headers =
+      "content-encoding: br-d\n"
+      "content-dictionary: "
+      ":U5abz16WDg7b8KS93msLPpOB4Vbef1uRzoORYkJw9BY=:\n";
   net::AddMockTransaction(&new_mock_transaction);
 
   net::MockHttpRequest request(new_mock_transaction);
@@ -999,35 +839,17 @@
   ASSERT_THAT(transaction.Start(&request, start_callback.callback(),
                                 net::NetLogWithSource()),
               net::test::IsError(net::ERR_IO_PENDING));
-  if (GetVersion() ==
-      network::features::CompressionDictionaryTransportBackendVersion::kV2) {
-    EXPECT_THAT(start_callback.WaitForResult(),
-                net::test::IsError(net::ERR_DICTIONARY_LOAD_FAILED));
-    return;
-  }
-
-  // When V1 backend is used, even if there is a wrong "content-dictionary"
-  // header, SharedDictionaryNetworkTransaction can decode the body.
-  EXPECT_THAT(start_callback.WaitForResult(), net::test::IsError(net::OK));
-  scoped_refptr<net::IOBufferWithSize> buf =
-      base::MakeRefCounted<net::IOBufferWithSize>(kDefaultBufferSize);
-  net::TestCompletionCallback read_callback;
-  ASSERT_THAT(
-      transaction.Read(buf.get(), buf->size(), read_callback.callback()),
-      net::test::IsError(net::ERR_IO_PENDING));
-  int read_result = read_callback.WaitForResult();
-  EXPECT_THAT(read_result, kTestData.size());
-  EXPECT_EQ(kTestData, std::string(buf->data(), read_result));
+  EXPECT_THAT(start_callback.WaitForResult(),
+              net::test::IsError(net::ERR_DICTIONARY_LOAD_FAILED));
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest, MultipleContentEncodingWithSbr) {
+TEST_F(SharedDictionaryNetworkTransactionTest, MultipleContentEncodingWithSbr) {
   DummySharedDictionaryManager manager(
       base::MakeRefCounted<DummySharedDictionaryStorage>(
           std::make_unique<DummySyncDictionary>(kTestDictionaryData)));
 
   // Override MockTransaction to set `content-encoding: sbr, deflate`.
-  net::MockTransaction new_mock_transaction =
-      GetBrotliDictionaryTestTransaction();
+  net::MockTransaction new_mock_transaction = kBrotliDictionaryTestTransaction;
   new_mock_transaction.response_headers = "content-encoding: sbr, deflate\n";
   net::AddMockTransaction(&new_mock_transaction);
 
@@ -1057,7 +879,7 @@
   EXPECT_EQ(kBrotliEncodedDataString, std::string(buf->data(), read_result));
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest,
+TEST_F(SharedDictionaryNetworkTransactionTest,
        AsyncDictionarySuccessBeforeStartReading) {
   std::unique_ptr<DummyAsyncDictionary> dictionary =
       std::make_unique<DummyAsyncDictionary>(kTestDictionaryData);
@@ -1066,7 +888,7 @@
       base::MakeRefCounted<DummySharedDictionaryStorage>(
           std::move(dictionary)));
 
-  net::MockHttpRequest request(GetBrotliDictionaryTestTransaction());
+  net::MockHttpRequest request(kBrotliDictionaryTestTransaction);
   SharedDictionaryNetworkTransaction transaction(manager,
                                                  CreateNetworkTransaction());
   transaction.SetIsSharedDictionaryReadAllowedCallback(
@@ -1094,7 +916,7 @@
   EXPECT_EQ(kTestData, std::string(buf->data(), read_result));
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest,
+TEST_F(SharedDictionaryNetworkTransactionTest,
        AsyncDictionarySuccessAfterStartReading) {
   std::unique_ptr<DummyAsyncDictionary> dictionary =
       std::make_unique<DummyAsyncDictionary>(kTestDictionaryData);
@@ -1103,7 +925,7 @@
       base::MakeRefCounted<DummySharedDictionaryStorage>(
           std::move(dictionary)));
 
-  net::MockHttpRequest request(GetBrotliDictionaryTestTransaction());
+  net::MockHttpRequest request(kBrotliDictionaryTestTransaction);
   SharedDictionaryNetworkTransaction transaction(manager,
                                                  CreateNetworkTransaction());
   transaction.SetIsSharedDictionaryReadAllowedCallback(
@@ -1135,7 +957,7 @@
   EXPECT_EQ(kTestData, std::string(buf->data(), read_result));
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest,
+TEST_F(SharedDictionaryNetworkTransactionTest,
        AsyncDictionarySuccessAfterTransactionDestroy) {
   std::unique_ptr<DummyAsyncDictionary> dictionary =
       std::make_unique<DummyAsyncDictionary>(kTestDictionaryData);
@@ -1144,7 +966,7 @@
       base::MakeRefCounted<DummySharedDictionaryStorage>(
           std::move(dictionary)));
 
-  net::MockHttpRequest request(GetBrotliDictionaryTestTransaction());
+  net::MockHttpRequest request(kBrotliDictionaryTestTransaction);
   std::unique_ptr<SharedDictionaryNetworkTransaction> transaction =
       std::make_unique<SharedDictionaryNetworkTransaction>(
           manager, CreateNetworkTransaction());
@@ -1177,7 +999,7 @@
   EXPECT_FALSE(read_callback.have_result());
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest,
+TEST_F(SharedDictionaryNetworkTransactionTest,
        AsyncDictionaryFailureBeforeStartReading) {
   std::unique_ptr<DummyAsyncDictionary> dictionary =
       std::make_unique<DummyAsyncDictionary>(kTestDictionaryData);
@@ -1186,7 +1008,7 @@
       base::MakeRefCounted<DummySharedDictionaryStorage>(
           std::move(dictionary)));
 
-  net::MockHttpRequest request(GetBrotliDictionaryTestTransaction());
+  net::MockHttpRequest request(kBrotliDictionaryTestTransaction);
   SharedDictionaryNetworkTransaction transaction(manager,
                                                  CreateNetworkTransaction());
   transaction.SetIsSharedDictionaryReadAllowedCallback(
@@ -1211,7 +1033,7 @@
       net::test::IsError(net::ERR_DICTIONARY_LOAD_FAILED));
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest,
+TEST_F(SharedDictionaryNetworkTransactionTest,
        AsyncDictionaryFailureAfterStartReading) {
   std::unique_ptr<DummyAsyncDictionary> dictionary =
       std::make_unique<DummyAsyncDictionary>(kTestDictionaryData);
@@ -1220,7 +1042,7 @@
       base::MakeRefCounted<DummySharedDictionaryStorage>(
           std::move(dictionary)));
 
-  net::MockHttpRequest request(GetBrotliDictionaryTestTransaction());
+  net::MockHttpRequest request(kBrotliDictionaryTestTransaction);
   SharedDictionaryNetworkTransaction transaction(manager,
                                                  CreateNetworkTransaction());
   transaction.SetIsSharedDictionaryReadAllowedCallback(
@@ -1250,7 +1072,7 @@
   EXPECT_EQ(net::ERR_DICTIONARY_LOAD_FAILED, read_callback.WaitForResult());
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest, Restart) {
+TEST_F(SharedDictionaryNetworkTransactionTest, Restart) {
   DummySharedDictionaryManager manager(
       base::MakeRefCounted<DummySharedDictionaryStorage>(nullptr));
 
@@ -1291,7 +1113,7 @@
   ASSERT_FALSE(transaction.IsReadyToRestartForAuth());
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest, StopCaching) {
+TEST_F(SharedDictionaryNetworkTransactionTest, StopCaching) {
   DummySharedDictionaryManager manager(
       base::MakeRefCounted<DummySharedDictionaryStorage>(nullptr));
   SharedDictionaryNetworkTransaction transaction(manager,
@@ -1301,7 +1123,7 @@
   EXPECT_TRUE(network_layer().stop_caching_called());
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest, DoneReading) {
+TEST_F(SharedDictionaryNetworkTransactionTest, DoneReading) {
   DummySharedDictionaryManager manager(
       base::MakeRefCounted<DummySharedDictionaryStorage>(nullptr));
 
@@ -1312,7 +1134,7 @@
   EXPECT_TRUE(network_layer().done_reading_called());
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest, GetLoadState) {
+TEST_F(SharedDictionaryNetworkTransactionTest, GetLoadState) {
   DummySharedDictionaryManager manager(
       base::MakeRefCounted<DummySharedDictionaryStorage>(nullptr));
 
@@ -1341,7 +1163,7 @@
   EXPECT_EQ(net::LOAD_STATE_READING_RESPONSE, transaction.GetLoadState());
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest, SharedZstd) {
+TEST_F(SharedDictionaryNetworkTransactionTest, SharedZstd) {
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndEnableFeature(network::features::kSharedZstd);
 
@@ -1376,7 +1198,7 @@
   EXPECT_EQ(kTestData, std::string(buf->data(), read_result));
 }
 
-TEST_P(SharedDictionaryNetworkTransactionTest, NoZstdDContentEncoding) {
+TEST_F(SharedDictionaryNetworkTransactionTest, NoZstdDContentEncoding) {
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndEnableFeature(network::features::kSharedZstd);
 
@@ -1458,18 +1280,13 @@
 }
 
 class SharedDictionaryNetworkTransactionProtocolCheckTest
-    : public SharedDictionaryNetworkTransactionTestBase,
+    : public SharedDictionaryNetworkTransactionTest,
       public testing::WithParamInterface<
           std::tuple<ProtocolCheckFeatureTestCase,
                      ProtocolCheckProtocolTestCase,
                      ProtocolCheckHostTestCase>> {
  public:
-  SharedDictionaryNetworkTransactionProtocolCheckTest()
-      : SharedDictionaryNetworkTransactionTestBase(
-            // Protocol check logic doesn't depend on versions. So we just check
-            // the V2 behavior.
-            network::features::CompressionDictionaryTransportBackendVersion::
-                kV2) {
+  SharedDictionaryNetworkTransactionProtocolCheckTest() {
     std::vector<base::test::FeatureRef> enabled_features;
     std::vector<base::test::FeatureRef> disabled_features;
     if (AllowHttp1()) {
@@ -1489,8 +1306,7 @@
 
  protected:
   net::MockTransaction CreateMockTransaction() {
-    net::MockTransaction mock_transaction =
-        GetBrotliDictionaryTestTransaction();
+    net::MockTransaction mock_transaction = kBrotliDictionaryTestTransaction;
     if (IsLocalHost()) {
       mock_transaction.url = "http://localhost/test";
     }
diff --git a/services/network/shared_dictionary/shared_dictionary_storage.cc b/services/network/shared_dictionary/shared_dictionary_storage.cc
index a747378b..6821c136 100644
--- a/services/network/shared_dictionary/shared_dictionary_storage.cc
+++ b/services/network/shared_dictionary/shared_dictionary_storage.cc
@@ -35,7 +35,7 @@
  public:
   DictionaryHeaderInfo(std::string match,
                        std::set<network::mojom::RequestDestination> match_dest,
-                       std::optional<base::TimeDelta> expiration,
+                       base::TimeDelta expiration,
                        std::string type,
                        std::string id)
       : match(std::move(match)),
@@ -47,9 +47,7 @@
 
   std::string match;
   std::set<network::mojom::RequestDestination> match_dest;
-  // TODO(crbug.com/1413922): Stop using std::optional when we remove V1 backend
-  // support.
-  std::optional<base::TimeDelta> expiration;
+  base::TimeDelta expiration;
   std::string type;
   std::string id;
 };
@@ -70,24 +68,10 @@
     return std::nullopt;
   }
 
-  const bool is_v1 =
-      features::kCompressionDictionaryTransportBackendVersion.Get() ==
-      features::CompressionDictionaryTransportBackendVersion::kV1;
-  // Don't use the value of `expires` in the `Use-As-Dictionary` response header
-  // when V2 backend is enabled.
-  const bool check_expires_dictionary_value = is_v1;
-  // Don't use the value of `match-dest` in the `Use-As-Dictionary` response
-  // header when V1 backend is enabled.
-  const bool check_match_dest_dictionary_value = !is_v1;
-  // Don't use the value of `id` in the `Use-As-Dictionary` response header when
-  // V1 backend is enabled.
-  const bool check_id_dictionary_value = !is_v1;
-
   std::optional<std::string> match_value;
   // Maybe we don't need to support multiple match-dest.
   // https://github.com/httpwg/http-extensions/issues/2722
   std::set<network::mojom::RequestDestination> match_dest_values;
-  std::optional<base::TimeDelta> expires_value;
   std::string type_value = std::string(kDefaultTypeRaw);
   std::string id_value;
   for (const auto& entry : dictionary.value()) {
@@ -97,8 +81,7 @@
         return std::nullopt;
       }
       match_value = entry.second.member.front().item.GetString();
-    } else if (check_match_dest_dictionary_value &&
-               entry.first == shared_dictionary::kOptionNameMatchDest) {
+    } else if (entry.first == shared_dictionary::kOptionNameMatchDest) {
       if (!entry.second.member_is_inner_list) {
         // `match-dest` must be a list.
         return std::nullopt;
@@ -117,22 +100,13 @@
           match_dest_values.insert(*dest_value);
         }
       }
-    } else if (check_expires_dictionary_value &&
-               entry.first == shared_dictionary::kOptionNameExpires) {
-      if ((entry.second.member.size() != 1u) ||
-          !entry.second.member.front().item.is_integer()) {
-        return std::nullopt;
-      }
-      expires_value =
-          base::Seconds(entry.second.member.front().item.GetInteger());
     } else if (entry.first == shared_dictionary::kOptionNameType) {
       if ((entry.second.member.size() != 1u) ||
           !entry.second.member.front().item.is_token()) {
         return std::nullopt;
       }
       type_value = entry.second.member.front().item.GetString();
-    } else if (check_id_dictionary_value &&
-               entry.first == shared_dictionary::kOptionNameId) {
+    } else if (entry.first == shared_dictionary::kOptionNameId) {
       if ((entry.second.member.size() != 1u) ||
           !entry.second.member.front().item.is_string()) {
         return std::nullopt;
@@ -143,46 +117,33 @@
       }
     }
   }
-
-  if (!check_expires_dictionary_value) {
-    // Use the fressness lifetime caliculated from the response header.
-    net::HttpResponseHeaders::FreshnessLifetimes lifetimes =
-        headers.GetFreshnessLifetimes(response_time);
-    // We calculate `expires_value` which is a delta from the response time to
-    // the expiration time. So we get the age of the response on the response
-    // time by setting `current_time` argument to `response_time`.
-    base::TimeDelta age_on_response_time =
-        headers.GetCurrentAge(request_time, response_time,
-                              /*current_time=*/response_time);
-    // We can use `freshness + staleness - current_age` as the expiration time.
-    expires_value =
-        lifetimes.freshness + lifetimes.staleness - age_on_response_time;
-    if (*expires_value <= base::TimeDelta()) {
-      return std::nullopt;
-    }
-  }
   if (!match_value) {
     return std::nullopt;
   }
-  return DictionaryHeaderInfo(
-      std::move(*match_value), std::move(match_dest_values),
-      std::move(expires_value), std::move(type_value), std::move(id_value));
+
+  // Use the fressness lifetime caliculated from the response header.
+  net::HttpResponseHeaders::FreshnessLifetimes lifetimes =
+      headers.GetFreshnessLifetimes(response_time);
+  // We calculate `expires_value` which is a delta from the response time to
+  // the expiration time. So we get the age of the response on the response
+  // time by setting `current_time` argument to `response_time`.
+  base::TimeDelta age_on_response_time =
+      headers.GetCurrentAge(request_time, response_time,
+                            /*current_time=*/response_time);
+  // We can use `freshness + staleness - current_age` as the expiration time.
+  base::TimeDelta expiration =
+      lifetimes.freshness + lifetimes.staleness - age_on_response_time;
+  if (expiration <= base::TimeDelta()) {
+    return std::nullopt;
+  }
+
+  return DictionaryHeaderInfo(std::move(*match_value),
+                              std::move(match_dest_values), expiration,
+                              std::move(type_value), std::move(id_value));
 }
 
 }  // namespace
 
-// static
-bool SharedDictionaryStorage::NeedToUseUrlPatternMatcher() {
-  return features::kCompressionDictionaryTransportBackendVersion.Get() !=
-         features::CompressionDictionaryTransportBackendVersion::kV1;
-}
-
-// static
-bool SharedDictionaryStorage::NeedToRemoveMatchDestAndId() {
-  return features::kCompressionDictionaryTransportBackendVersion.Get() ==
-         features::CompressionDictionaryTransportBackendVersion::kV1;
-}
-
 SharedDictionaryStorage::SharedDictionaryStorage() = default;
 
 SharedDictionaryStorage::~SharedDictionaryStorage() = default;
@@ -200,12 +161,7 @@
   if (!info) {
     return nullptr;
   }
-  // TODO(crubg.com/1413922) Stop using kDefaultExpiration when we remove V1
-  // backend support.
-  base::TimeDelta expiration = shared_dictionary::kDefaultExpiration;
-  if (info->expiration) {
-    expiration = *info->expiration;
-  }
+  base::TimeDelta expiration = info->expiration;
   if (!base::FeatureList::IsEnabled(
           network::features::kCompressionDictionaryTransport)) {
     // During the Origin Trial experiment, kCompressionDictionaryTransport is
diff --git a/services/network/shared_dictionary/shared_dictionary_storage.h b/services/network/shared_dictionary/shared_dictionary_storage.h
index 83da110a..ae1f636 100644
--- a/services/network/shared_dictionary/shared_dictionary_storage.h
+++ b/services/network/shared_dictionary/shared_dictionary_storage.h
@@ -69,12 +69,6 @@
  protected:
   friend class base::RefCounted<SharedDictionaryStorage>;
 
-  // Returns true when V2 backend is used.
-  // TODO(crbug.com/1413922): Remove this when we remove V1 backend support.
-  static bool NeedToUseUrlPatternMatcher();
-  // Returns true when V1 backend is used.
-  static bool NeedToRemoveMatchDestAndId();
-
   SharedDictionaryStorage();
   virtual ~SharedDictionaryStorage();
 
@@ -128,16 +122,9 @@
         !base::Contains(info.match_dest(), destination)) {
       continue;
     }
-    if (!info.matcher()) {
-      // This is for V1 backend.
-      // TODO(crbug.com/1413922): Remove this after V1 backend is removed.
-      if (base::MatchPattern(url.path(), info.match())) {
-        matched_info = &info;
-      }
-    } else {
-      if (info.matcher()->Match(url)) {
-        matched_info = &info;
-      }
+    CHECK(info.matcher());
+    if (info.matcher()->Match(url)) {
+      matched_info = &info;
     }
   }
   return matched_info;
diff --git a/services/network/shared_dictionary/shared_dictionary_storage_in_memory.cc b/services/network/shared_dictionary/shared_dictionary_storage_in_memory.cc
index c4cb8d5..fd8371f7 100644
--- a/services/network/shared_dictionary/shared_dictionary_storage_in_memory.cc
+++ b/services/network/shared_dictionary/shared_dictionary_storage_in_memory.cc
@@ -115,13 +115,11 @@
     const std::set<mojom::RequestDestination>& match_dest,
     const std::string& id) {
   std::unique_ptr<SimpleUrlPatternMatcher> matcher;
-  if (NeedToUseUrlPatternMatcher()) {
-    auto matcher_create_result = SimpleUrlPatternMatcher::Create(match, url);
-    if (!matcher_create_result.has_value()) {
-      return nullptr;
-    }
-    matcher = std::move(matcher_create_result.value());
+  auto matcher_create_result = SimpleUrlPatternMatcher::Create(match, url);
+  if (!matcher_create_result.has_value()) {
+    return nullptr;
   }
+  matcher = std::move(matcher_create_result.value());
   return base::MakeRefCounted<SharedDictionaryWriterInMemory>(
       base::BindOnce(&SharedDictionaryStorageInMemory::OnDictionaryWritten,
                      weak_factory_.GetWeakPtr(), url, response_time, expiration,
diff --git a/services/network/shared_dictionary/shared_dictionary_storage_on_disk.cc b/services/network/shared_dictionary/shared_dictionary_storage_on_disk.cc
index d1e5c80..b48e953 100644
--- a/services/network/shared_dictionary/shared_dictionary_storage_on_disk.cc
+++ b/services/network/shared_dictionary/shared_dictionary_storage_on_disk.cc
@@ -244,13 +244,11 @@
   }
 
   std::unique_ptr<SimpleUrlPatternMatcher> matcher;
-  if (NeedToUseUrlPatternMatcher()) {
-    auto matcher_create_result = SimpleUrlPatternMatcher::Create(match, url);
-    if (!matcher_create_result.has_value()) {
-      return nullptr;
-    }
-    matcher = std::move(matcher_create_result.value());
+  auto matcher_create_result = SimpleUrlPatternMatcher::Create(match, url);
+  if (!matcher_create_result.has_value()) {
+    return nullptr;
   }
+  matcher = std::move(matcher_create_result.value());
   return manager_->CreateWriter(
       isolation_key_, url, response_time, expiration, match, match_dest, id,
       base::BindOnce(&SharedDictionaryStorageOnDisk::OnDictionaryWritten,
@@ -278,28 +276,17 @@
     return;
   }
 
-  const bool need_matcher = NeedToUseUrlPatternMatcher();
-  const bool need_to_remove_dest_and_id = NeedToRemoveMatchDestAndId();
   for (auto& info : result.value()) {
     const url::SchemeHostPort scheme_host_port =
         url::SchemeHostPort(info.url());
     const std::string match = info.match();
     std::unique_ptr<SimpleUrlPatternMatcher> matcher;
-    if (need_matcher) {
-      auto matcher_create_result =
-          SimpleUrlPatternMatcher::Create(match, info.url());
-      if (!matcher_create_result.has_value()) {
-        continue;
-      }
-      matcher = std::move(matcher_create_result.value());
+    auto matcher_create_result =
+        SimpleUrlPatternMatcher::Create(match, info.url());
+    if (!matcher_create_result.has_value()) {
+      continue;
     }
-    if (need_to_remove_dest_and_id) {
-      info = net::SharedDictionaryInfo(
-          info.url(), info.response_time(), info.expiration(), info.match(),
-          /*match_dest_string=*/"", /*id=*/"", info.last_used_time(),
-          info.size(), info.hash(), info.disk_cache_key_token(),
-          info.primary_key_in_database());
-    }
+    matcher = std::move(matcher_create_result.value());
     WrappedDictionaryInfo wrapped_info(std::move(info), std::move(matcher));
     auto key = std::make_tuple(match, wrapped_info.match_dest());
     dictionary_info_map_[scheme_host_port].insert(
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 7083b5b..83f6f49 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -3893,26 +3893,6 @@
             ]
         }
     ],
-    "ChromeWallpaperSearchLaunch": [
-        {
-            "platforms": [
-                "chromeos",
-                "chromeos_lacros",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "CustomizeChromeWallpaperSearch",
-                        "CustomizeChromeWallpaperSearchInspirationCard"
-                    ]
-                }
-            ]
-        }
-    ],
     "ChromeWideEchoCancellation": [
         {
             "platforms": [
@@ -5437,6 +5417,24 @@
             ]
         }
     ],
+    "DbscPhase1aStudy": [
+        {
+            "platforms": [
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "params": {
+                        "dice-support": "enabled"
+                    },
+                    "enable_features": [
+                        "EnableBoundSessionCredentials"
+                    ]
+                }
+            ]
+        }
+    ],
     "DecodedImageWorkingSetBudget": [
         {
             "platforms": [
@@ -6954,13 +6952,29 @@
             ],
             "experiments": [
                 {
-                    "name": "Enabled",
+                    "name": "Enabled_20240202",
                     "params": {
                         "OneTapForMapsConsentModeParam": "iph"
                     },
                     "enable_features": [
                         "EnableOneTapForMaps"
-                    ]
+                    ],
+                    "disable_features": [
+                        "EnableExpKitTextClassifier"
+                    ],
+                    "min_os_version": "16.4.0"
+                },
+                {
+                    "name": "EnabledWithTC_20240202",
+                    "params": {
+                        "OneTapForMapsConsentModeParam": "iph",
+                        "onetap": "true"
+                    },
+                    "enable_features": [
+                        "EnableExpKitTextClassifier",
+                        "EnableOneTapForMaps"
+                    ],
+                    "min_os_version": "16.4.0"
                 }
             ]
         }
@@ -9303,22 +9317,6 @@
             ]
         }
     ],
-    "IOSExpKitCalendarTextClassifier": [
-        {
-            "platforms": [
-                "ios"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "EnableExpKitCalendarTextClassifier",
-                        "EnableExpKitTextClassifier"
-                    ]
-                }
-            ]
-        }
-    ],
     "IOSExternalActions": [
         {
             "platforms": [
@@ -12137,58 +12135,6 @@
             ]
         }
     ],
-    "OmniboxActionsUISimplification": [
-        {
-            "platforms": [
-                "chromeos",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "params": {
-                        "ActionsUISimplificationIncludeRealbox": "true",
-                        "ActionsUISimplificationTrimExtra": "true"
-                    },
-                    "enable_features": [
-                        "OmniboxActionsUISimplification"
-                    ]
-                },
-                {
-                    "name": "ExcludeRealbox",
-                    "params": {
-                        "ActionsUISimplificationIncludeRealbox": "false",
-                        "ActionsUISimplificationTrimExtra": "true"
-                    },
-                    "enable_features": [
-                        "OmniboxActionsUISimplification"
-                    ]
-                },
-                {
-                    "name": "ExcludeRealbox_TrimExtraFalse",
-                    "params": {
-                        "ActionsUISimplificationIncludeRealbox": "false",
-                        "ActionsUISimplificationTrimExtra": "false"
-                    },
-                    "enable_features": [
-                        "OmniboxActionsUISimplification"
-                    ]
-                },
-                {
-                    "name": "TrimExtraFalse",
-                    "params": {
-                        "ActionsUISimplificationIncludeRealbox": "true",
-                        "ActionsUISimplificationTrimExtra": "false"
-                    },
-                    "enable_features": [
-                        "OmniboxActionsUISimplification"
-                    ]
-                }
-            ]
-        }
-    ],
     "OmniboxBundledExperimentV1": [
         {
             "platforms": [
@@ -21604,6 +21550,27 @@
             ]
         }
     ],
+    "WebProtectCustomRuleMessageDialog": [
+        {
+            "platforms": [
+                "chromeos",
+                "chromeos_lacros",
+                "fuchsia",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "DialogCustomRuleMessageEnabled",
+                        "RealTimeUrlFilteringCustomMessage"
+                    ]
+                }
+            ]
+        }
+    ],
     "WebProtectPrint": [
         {
             "platforms": [
diff --git a/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom b/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom
index b203fde..ca5f304 100644
--- a/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom
+++ b/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom
@@ -837,6 +837,7 @@
     kInsetArea = 781,
     kViewTransitionClass = 782,
     kPositionTryOrder = 783,
+    kPositionTryOptions = 784,
 
     // 1. Add new features above this line (don't change the assigned numbers of
     //    the existing items).
diff --git a/third_party/blink/public/web/web_autofill_client.h b/third_party/blink/public/web/web_autofill_client.h
index 98e6356..848def1 100644
--- a/third_party/blink/public/web/web_autofill_client.h
+++ b/third_party/blink/public/web/web_autofill_client.h
@@ -90,11 +90,12 @@
       const WebElement&,
       WebFormRelatedChangeType) {}
   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) {}
+  // Called when the value of `element` has been changed by JavaScript.
+  // `old_value` contains the value before being changed.
+  // `was_autofilled` is the state of the field prior to the JS change.
+  virtual void JavaScriptChangedValue(const WebFormControlElement& element,
+                                      const WebString& old_value,
+                                      bool was_autofilled) {}
 
   // Called when the focused node has changed. This is not called if the focus
   // moves outside the frame.
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h b/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h
index 93cecd0..ae0081b 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h
+++ b/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h
@@ -316,19 +316,15 @@
     return V8String(isolate, value);
   }
 
-  template <size_t sizeOfValue>
-  static v8::Local<v8::Value> ToV8SignedIntegerInternal(int64_t value,
-                                                        v8::Isolate*);
-
-  template <>
-  v8::Local<v8::Value> ToV8SignedIntegerInternal<4>(int64_t value,
-                                                    v8::Isolate* isolate) {
-    return v8::Integer::New(isolate, static_cast<int32_t>(value));
+  static v8::Local<v8::Value> ToV8(int32_t value,
+                                   v8::Local<v8::Object> creation_context,
+                                   v8::Isolate* isolate) {
+    return v8::Integer::New(isolate, value);
   }
 
-  template <>
-  v8::Local<v8::Value> ToV8SignedIntegerInternal<8>(int64_t value,
-                                                    v8::Isolate* isolate) {
+  static v8::Local<v8::Value> ToV8(int64_t value,
+                                   v8::Local<v8::Object> creation_context,
+                                   v8::Isolate* isolate) {
     int32_t value_in32_bit = static_cast<int32_t>(value);
     if (value_in32_bit == value) {
       return v8::Integer::New(isolate, value_in32_bit);
@@ -337,19 +333,15 @@
     return v8::Number::New(isolate, value);
   }
 
-  template <size_t sizeOfValue>
-  static v8::Local<v8::Value> ToV8UnsignedIntegerInternal(uint64_t value,
-                                                          v8::Isolate*);
-
-  template <>
-  v8::Local<v8::Value> ToV8UnsignedIntegerInternal<4>(uint64_t value,
-                                                      v8::Isolate* isolate) {
-    return v8::Integer::NewFromUnsigned(isolate, static_cast<uint32_t>(value));
+  static v8::Local<v8::Value> ToV8(uint32_t value,
+                                   v8::Local<v8::Object> creation_context,
+                                   v8::Isolate* isolate) {
+    return v8::Integer::NewFromUnsigned(isolate, value);
   }
 
-  template <>
-  v8::Local<v8::Value> ToV8UnsignedIntegerInternal<8>(uint64_t value,
-                                                      v8::Isolate* isolate) {
+  static v8::Local<v8::Value> ToV8(uint64_t value,
+                                   v8::Local<v8::Object> creation_context,
+                                   v8::Isolate* isolate) {
     uint32_t value_in32_bit = static_cast<uint32_t>(value);
     if (value_in32_bit == value) {
       return v8::Integer::NewFromUnsigned(isolate, value_in32_bit);
@@ -358,30 +350,6 @@
     return v8::Number::New(isolate, value);
   }
 
-  static v8::Local<v8::Value> ToV8(int32_t value,
-                                   v8::Local<v8::Object> creation_context,
-                                   v8::Isolate* isolate) {
-    return ToV8SignedIntegerInternal<sizeof value>(value, isolate);
-  }
-
-  static v8::Local<v8::Value> ToV8(int64_t value,
-                                   v8::Local<v8::Object> creation_context,
-                                   v8::Isolate* isolate) {
-    return ToV8SignedIntegerInternal<sizeof value>(value, isolate);
-  }
-
-  static v8::Local<v8::Value> ToV8(uint32_t value,
-                                   v8::Local<v8::Object> creation_context,
-                                   v8::Isolate* isolate) {
-    return ToV8UnsignedIntegerInternal<sizeof value>(value, isolate);
-  }
-
-  static v8::Local<v8::Value> ToV8(uint64_t value,
-                                   v8::Local<v8::Object> creation_context,
-                                   v8::Isolate* isolate) {
-    return ToV8UnsignedIntegerInternal<sizeof value>(value, isolate);
-  }
-
   static v8::Local<v8::Value> ToV8(bool value,
                                    v8::Local<v8::Object> creation_context,
                                    v8::Isolate* isolate) {
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.cc b/third_party/blink/renderer/core/animation/css/css_animations.cc
index 18f1f14..c0e563e0 100644
--- a/third_party/blink/renderer/core/animation/css/css_animations.cc
+++ b/third_party/blink/renderer/core/animation/css/css_animations.cc
@@ -2844,6 +2844,10 @@
   return property == PropertyHandle(GetCSSPropertyLineHeight());
 }
 
+bool IsDisplayPropertyHandle(const PropertyHandle& property) {
+  return property == PropertyHandle(GetCSSPropertyDisplay());
+}
+
 void AdoptActiveAnimationInterpolations(
     EffectStack* effect_stack,
     CSSAnimationUpdate& update,
@@ -3250,6 +3254,13 @@
   return element_animations && element_animations->GetEffectStack().HasRevert();
 }
 
+bool CSSAnimations::IsAnimatingDisplayProperty(
+    const ElementAnimations* element_animations) {
+  return element_animations &&
+         element_animations->GetEffectStack().AffectsProperties(
+             IsDisplayPropertyHandle);
+}
+
 void CSSAnimations::Trace(Visitor* visitor) const {
   visitor->Trace(timeline_data_);
   visitor->Trace(transitions_);
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.h b/third_party/blink/renderer/core/animation/css/css_animations.h
index 9f22d1a..4378833 100644
--- a/third_party/blink/renderer/core/animation/css/css_animations.h
+++ b/third_party/blink/renderer/core/animation/css/css_animations.h
@@ -85,6 +85,7 @@
   static bool IsAnimatingFontAffectingProperties(const ElementAnimations*);
   static bool IsAnimatingLineHeightProperty(const ElementAnimations*);
   static bool IsAnimatingRevert(const ElementAnimations*);
+  static bool IsAnimatingDisplayProperty(const ElementAnimations*);
   static void CalculateTimelineUpdate(CSSAnimationUpdate&,
                                       Element& animating_element,
                                       const ComputedStyleBuilder&);
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5
index 3148f6d..f1b889ce 100644
--- a/third_party/blink/renderer/core/css/css_properties.json5
+++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -4169,6 +4169,20 @@
       runtime_flag: "CSSAnchorPositioning",
     },
     {
+      name: "position-try-options",
+      property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      style_builder_custom_functions: ["value"],
+      field_group: "*",
+      field_template: "external",
+      keywords: ["none", "flip-block", "flip-inline", "flip-start"],
+      typedom_types: ["Keyword"],
+      include_paths: ["third_party/blink/renderer/core/style/position_try_options.h"],
+      wrapper_pointer_name: "Member",
+      type_name: "PositionTryOptions",
+      default_value: "nullptr",
+      runtime_flag: "CSSAnchorPositioning",
+    },
+    {
       name: "position-try-order",
       property_methods: ["CSSValueFromComputedStyleInternal"],
       field_group: "*",
diff --git a/third_party/blink/renderer/core/css/css_property_equality.cc b/third_party/blink/renderer/core/css/css_property_equality.cc
index 9ccfea9e..c7c33560 100644
--- a/third_party/blink/renderer/core/css/css_property_equality.cc
+++ b/third_party/blink/renderer/core/css/css_property_equality.cc
@@ -916,6 +916,9 @@
       return a.Zoom() == b.Zoom();
     case CSSPropertyID::kPositionTryOrder:
       return a.PositionTryOrder() == b.PositionTryOrder();
+    case CSSPropertyID::kPositionTryOptions:
+      return base::ValuesEquivalent(a.GetPositionTryOptions(),
+                                    b.GetPositionTryOptions());
 
     // These properties are not animateable, but perhaps equality should still
     // be defined for them.
diff --git a/third_party/blink/renderer/core/css/css_value_keywords.json5 b/third_party/blink/renderer/core/css/css_value_keywords.json5
index 3fe0a20b..ca80ee1 100644
--- a/third_party/blink/renderer/core/css/css_value_keywords.json5
+++ b/third_party/blink/renderer/core/css/css_value_keywords.json5
@@ -1792,5 +1792,11 @@
     "most-height",
     "most-block-size",
     "most-inline-size",
+
+    // position-try-options
+    // none
+    "flip-block",
+    "flip-inline",
+    "flip-start",
   ],
 }
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
index 5a19e42a..878a4aab 100644
--- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
+++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
@@ -7119,5 +7119,49 @@
                                             CSSValuePair::kKeepIdenticalValues);
 }
 
+CSSValue* ConsumeSinglePositionTryOption(CSSParserTokenRange& range,
+                                         const CSSParserContext& context) {
+  if (CSSValue* dashed_ident = ConsumeDashedIdent(range, context)) {
+    return dashed_ident;
+  }
+  CSSValueList* list = CSSValueList::CreateSpaceSeparated();
+  bool flip_block = false;
+  bool flip_inline = false;
+  bool flip_start = false;
+  while (!range.AtEnd()) {
+    CSSIdentifierValue* tactic =
+        ConsumeIdent<CSSValueID::kFlipBlock, CSSValueID::kFlipInline,
+                     CSSValueID::kFlipStart>(range);
+    if (!tactic) {
+      break;
+    }
+    switch (tactic->GetValueID()) {
+      case CSSValueID::kFlipBlock:
+        if (flip_block) {
+          return nullptr;
+        }
+        flip_block = true;
+        break;
+      case CSSValueID::kFlipInline:
+        if (flip_inline) {
+          return nullptr;
+        }
+        flip_inline = true;
+        break;
+      case CSSValueID::kFlipStart:
+        if (flip_start) {
+          return nullptr;
+        }
+        flip_start = true;
+        break;
+      default:
+        NOTREACHED();
+        return nullptr;
+    }
+    list->Append(*tactic);
+  }
+  return list->length() ? list : nullptr;
+}
+
 }  // namespace css_parsing_utils
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.h b/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
index cf9da4d..881d1852 100644
--- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
+++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
@@ -691,6 +691,9 @@
   return true;
 }
 
+CSSValue* ConsumeSinglePositionTryOption(CSSParserTokenRange& range,
+                                         const CSSParserContext& context);
+
 }  // namespace css_parsing_utils
 }  // namespace blink
 
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 b02ecc81..e877b57 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
@@ -6865,6 +6865,93 @@
       *style.PositionFallbackBounds());
 }
 
+const CSSValue* PositionTryOptions::ParseSingleValue(
+    CSSParserTokenRange& range,
+    const CSSParserContext& context,
+    const CSSParserLocalContext&) const {
+  // position-try-options: none | [ <dashed-ident> | <try-tactic> ]#
+  // <try-tactic> = flip-block || flip-inline || flip-start
+  if (range.Peek().Id() == CSSValueID::kNone) {
+    return css_parsing_utils::ConsumeIdent(range);
+  }
+  return css_parsing_utils::ConsumeCommaSeparatedList(
+      css_parsing_utils::ConsumeSinglePositionTryOption, range, context);
+}
+
+const CSSValue* PositionTryOptions::CSSValueFromComputedStyleInternal(
+    const ComputedStyle& style,
+    const LayoutObject*,
+    bool allow_visited_style) const {
+  if (const blink::PositionTryOptions* options =
+          style.GetPositionTryOptions()) {
+    CSSValueList* option_list = CSSValueList::CreateCommaSeparated();
+    for (const auto& option : options->GetOptions()) {
+      if (option.HasTryTactic()) {
+        CSSValueList* tactic_list = CSSValueList::CreateSpaceSeparated();
+        TryTacticFlags tactic = option.GetTryTactic();
+        if (tactic & static_cast<TryTacticFlags>(TryTactic::kFlipBlock)) {
+          tactic_list->Append(
+              *CSSIdentifierValue::Create(CSSValueID::kFlipBlock));
+        }
+        if (tactic & static_cast<TryTacticFlags>(TryTactic::kFlipInline)) {
+          tactic_list->Append(
+              *CSSIdentifierValue::Create(CSSValueID::kFlipInline));
+        }
+        if (tactic & static_cast<TryTacticFlags>(TryTactic::kFlipStart)) {
+          tactic_list->Append(
+              *CSSIdentifierValue::Create(CSSValueID::kFlipStart));
+        }
+        option_list->Append(*tactic_list);
+      } else {
+        option_list->Append(*MakeGarbageCollected<CSSCustomIdentValue>(
+            *option.GetPositionTryName()));
+      }
+    }
+    return option_list;
+  }
+  return CSSIdentifierValue::Create(CSSValueID::kNone);
+}
+
+void PositionTryOptions::ApplyValue(StyleResolverState& state,
+                                    const CSSValue& value,
+                                    ValueMode) const {
+  if (value.IsIdentifierValue()) {
+    DCHECK(To<CSSIdentifierValue>(value).GetValueID() == CSSValueID::kNone);
+    // Just represent as nullptr.
+    return;
+  }
+  HeapVector<PositionTryOption> options;
+  for (const auto& option : To<CSSValueList>(value)) {
+    if (const auto* name = DynamicTo<CSSCustomIdentValue>(*option)) {
+      options.push_back(PositionTryOption(
+          StyleBuilderConverter::ConvertCustomIdent(state, *name)));
+      continue;
+    }
+    TryTacticFlags try_tactics = static_cast<TryTacticFlags>(TryTactic::kNone);
+    for (const auto& tactic : To<CSSValueList>(*option)) {
+      switch (To<CSSIdentifierValue>(*tactic).GetValueID()) {
+        case CSSValueID::kFlipBlock:
+          try_tactics |= static_cast<TryTacticFlags>(TryTactic::kFlipBlock);
+          break;
+        case CSSValueID::kFlipInline:
+          try_tactics |= static_cast<TryTacticFlags>(TryTactic::kFlipInline);
+          break;
+        case CSSValueID::kFlipStart:
+          try_tactics |= static_cast<TryTacticFlags>(TryTactic::kFlipStart);
+          break;
+        default:
+          NOTREACHED();
+          break;
+      }
+    }
+    DCHECK_NE(try_tactics, static_cast<TryTacticFlags>(TryTactic::kNone));
+    options.push_back(try_tactics);
+  }
+  DCHECK(!options.empty());
+  state.StyleBuilder().SetPositionTryOptions(
+      MakeGarbageCollected<blink::PositionTryOptions>(options));
+}
+
 const CSSValue* PositionTryOrder::CSSValueFromComputedStyleInternal(
     const ComputedStyle& style,
     const LayoutObject*,
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc b/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc
index d474895d..96b9fd4 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc
@@ -210,11 +210,20 @@
 void StyleResolverState::LoadPendingResources() {
   if (pseudo_request_type_ == StyleRequest::kForComputedStyle ||
       (ParentStyle() && ParentStyle()->IsEnsuredInDisplayNone()) ||
-      (StyleBuilder().Display() == EDisplay::kNone &&
-       !GetElement().LayoutObjectIsNeeded(style_builder_->GetDisplayStyle())) ||
       StyleBuilder().IsEnsuredOutsideFlatTree()) {
     return;
   }
+  if (StyleBuilder().Display() == EDisplay::kNone &&
+      !GetElement().LayoutObjectIsNeeded(style_builder_->GetDisplayStyle())) {
+    // Don't load resources for display:none elements unless we are animating
+    // display. If we are animating display, we might otherwise have ended up
+    // caching a base style with pending images.
+    Element* animating_element = GetAnimatingElement();
+    if (!animating_element || !CSSAnimations::IsAnimatingDisplayProperty(
+                                  animating_element->GetElementAnimations())) {
+      return;
+    }
+  }
 
   if (StyleBuilder().StyleType() == kPseudoIdTargetText) {
     // Do not load any resources for ::target-text since that could leak text
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 10b6fe0a..260b14b6 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
@@ -1066,17 +1066,15 @@
 }
 
 void HTMLInputElement::setCheckedForBinding(bool now_checked) {
-  if (!IsAutofilled()) {
-    SetChecked(now_checked);
-  } else {
-    bool old_value = this->Checked();
-    SetChecked(now_checked, TextFieldEventBehavior::kDispatchNoEvent,
-               old_value == now_checked ? WebAutofillState::kAutofilled
-                                        : WebAutofillState::kNotFilled);
-    if (Page* page = GetDocument().GetPage()) {
-      page->GetChromeClient().JavaScriptChangedAutofilledValue(
-          *this, old_value ? u"true" : u"false");
-    }
+  bool old_value = this->Checked();
+  bool was_autofilled = IsAutofilled();
+  SetChecked(now_checked, TextFieldEventBehavior::kDispatchNoEvent,
+             was_autofilled && old_value == now_checked
+                 ? WebAutofillState::kAutofilled
+                 : WebAutofillState::kNotFilled);
+  if (Page* page = GetDocument().GetPage()) {
+    page->GetChromeClient().JavaScriptChangedValue(
+        *this, old_value ? "true" : "false", was_autofilled);
   }
 }
 
@@ -1252,19 +1250,16 @@
                                       "to the empty string.");
     return;
   }
-  if (!IsAutofilled()) {
-    SetValue(value);
-  } else {
-    String old_value = this->Value();
-    SetValue(value, TextFieldEventBehavior::kDispatchNoEvent,
-             TextControlSetValueSelection::kSetSelectionToEnd,
-             old_value == value && !value.empty()
-                 ? WebAutofillState::kAutofilled
-                 : WebAutofillState::kNotFilled);
-    if (Page* page = GetDocument().GetPage()) {
-      page->GetChromeClient().JavaScriptChangedAutofilledValue(*this,
-                                                               old_value);
-    }
+  String old_value = this->Value();
+  bool was_autofilled = IsAutofilled();
+  SetValue(value, TextFieldEventBehavior::kDispatchNoEvent,
+           TextControlSetValueSelection::kSetSelectionToEnd,
+           was_autofilled && old_value == value && !value.empty()
+               ? WebAutofillState::kAutofilled
+               : WebAutofillState::kNotFilled);
+  if (Page* page = GetDocument().GetPage()) {
+    page->GetChromeClient().JavaScriptChangedValue(*this, old_value,
+                                                   was_autofilled);
   }
 }
 
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 e3ddd53..fd9caae 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
@@ -282,17 +282,15 @@
 }
 
 void HTMLSelectElement::setValueForBinding(const String& value) {
-  if (!IsAutofilled()) {
-    SetValue(value);
-  } else {
-    String old_value = this->Value();
-    SetValue(value, false,
-             value != old_value ? WebAutofillState::kNotFilled
-                                : WebAutofillState::kAutofilled);
-    if (Page* page = GetDocument().GetPage()) {
-      page->GetChromeClient().JavaScriptChangedAutofilledValue(*this,
-                                                               old_value);
-    }
+  String old_value = this->Value();
+  bool was_autofilled = IsAutofilled();
+  SetValue(value, false,
+           !was_autofilled || value != old_value
+               ? WebAutofillState::kNotFilled
+               : WebAutofillState::kAutofilled);
+  if (Page* page = GetDocument().GetPage()) {
+    page->GetChromeClient().JavaScriptChangedValue(*this, old_value,
+                                                   was_autofilled);
   }
 }
 
diff --git a/third_party/blink/renderer/core/html/forms/html_select_list_element.cc b/third_party/blink/renderer/core/html/forms/html_select_list_element.cc
index ccafe9e7..a8997dc6 100644
--- a/third_party/blink/renderer/core/html/forms/html_select_list_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_select_list_element.cc
@@ -471,17 +471,15 @@
 }
 
 void HTMLSelectListElement::setValueForBinding(const String& value) {
-  if (!IsAutofilled()) {
-    setValue(value);
-  } else {
-    String old_value = this->value();
-    setValue(value, /*send_events=*/false,
-             value != old_value ? WebAutofillState::kNotFilled
-                                : WebAutofillState::kAutofilled);
-    if (Page* page = GetDocument().GetPage()) {
-      page->GetChromeClient().JavaScriptChangedAutofilledValue(*this,
-                                                               old_value);
-    }
+  String old_value = this->value();
+  bool was_autofilled = IsAutofilled();
+  setValue(value, /*send_events=*/false,
+           !was_autofilled || value != old_value
+               ? WebAutofillState::kNotFilled
+               : WebAutofillState::kAutofilled);
+  if (Page* page = GetDocument().GetPage()) {
+    page->GetChromeClient().JavaScriptChangedValue(*this, old_value,
+                                                   was_autofilled);
   }
 }
 
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 1579d64..48a5401 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
@@ -453,18 +453,16 @@
 }
 
 void HTMLTextAreaElement::setValueForBinding(const String& value) {
-  if (!IsAutofilled()) {
-    SetValue(value);
-  } else {
-    String old_value = this->Value();
-    SetValue(value, TextFieldEventBehavior::kDispatchNoEvent,
-             TextControlSetValueSelection::kSetSelectionToEnd,
-             value != old_value ? WebAutofillState::kNotFilled
-                                : WebAutofillState::kAutofilled);
-    if (Page* page = GetDocument().GetPage()) {
-      page->GetChromeClient().JavaScriptChangedAutofilledValue(*this,
-                                                               old_value);
-    }
+  String old_value = this->Value();
+  bool was_autofilled = IsAutofilled();
+  SetValue(value, TextFieldEventBehavior::kDispatchNoEvent,
+           TextControlSetValueSelection::kSetSelectionToEnd,
+           !was_autofilled || value != old_value
+               ? WebAutofillState::kNotFilled
+               : WebAutofillState::kAutofilled);
+  if (Page* page = GetDocument().GetPage()) {
+    page->GetChromeClient().JavaScriptChangedValue(*this, old_value,
+                                                   was_autofilled);
   }
 }
 
diff --git a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
index 68f93bb..707e8f34 100644
--- a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
@@ -1829,6 +1829,11 @@
       .build();
 }
 
+void InspectorNetworkAgent::WillCreateP2PSocketUdp(
+    absl::optional<base::UnguessableToken>* devtools_token) {
+  *devtools_token = devtools_token_;
+}
+
 void InspectorNetworkAgent::WillCreateWebSocket(
     ExecutionContext* execution_context,
     uint64_t identifier,
diff --git a/third_party/blink/renderer/core/inspector/inspector_network_agent.h b/third_party/blink/renderer/core/inspector/inspector_network_agent.h
index 5e84086b..12f96ef 100644
--- a/third_party/blink/renderer/core/inspector/inspector_network_agent.h
+++ b/third_party/blink/renderer/core/inspector/inspector_network_agent.h
@@ -177,6 +177,7 @@
                                 ClientNavigationReason);
   void FrameClearedScheduledNavigation(LocalFrame*);
 
+  void WillCreateP2PSocketUdp(absl::optional<base::UnguessableToken>*);
   void WillCreateWebSocket(ExecutionContext*,
                            uint64_t identifier,
                            const KURL& request_url,
diff --git a/third_party/blink/renderer/core/page/chrome_client.h b/third_party/blink/renderer/core/page/chrome_client.h
index f2c0e73..c3f7d47 100644
--- a/third_party/blink/renderer/core/page/chrome_client.h
+++ b/third_party/blink/renderer/core/page/chrome_client.h
@@ -518,10 +518,12 @@
 
   virtual void SelectOrSelectListFieldOptionsChanged(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) {}
+  // Called when the value of `element` has been changed by JavaScript.
+  // `old_value` contains the value before being changed.
+  // `was_autofilled` is the state of the field prior to the JS change.
+  virtual void JavaScriptChangedValue(HTMLFormControlElement&,
+                                      const String& old_value,
+                                      bool was_autofilled) {}
 
   // 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 6036ee7..fa71dd7 100644
--- a/third_party/blink/renderer/core/page/chrome_client_impl.cc
+++ b/third_party/blink/renderer/core/page/chrome_client_impl.cc
@@ -1359,13 +1359,13 @@
     fill_client->AjaxSucceeded();
 }
 
-void ChromeClientImpl::JavaScriptChangedAutofilledValue(
-    HTMLFormControlElement& element,
-    const String& old_value) {
+void ChromeClientImpl::JavaScriptChangedValue(HTMLFormControlElement& element,
+                                              const String& old_value,
+                                              bool was_autofilled) {
   Document& doc = element.GetDocument();
   if (auto* fill_client = AutofillClientFromFrame(doc.GetFrame())) {
-    fill_client->JavaScriptChangedAutofilledValue(
-        WebFormControlElement(&element), old_value);
+    fill_client->JavaScriptChangedValue(WebFormControlElement(&element),
+                                        old_value, was_autofilled);
   }
 }
 
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 e4330c7..414af7ccb 100644
--- a/third_party/blink/renderer/core/page/chrome_client_impl.h
+++ b/third_party/blink/renderer/core/page/chrome_client_impl.h
@@ -272,8 +272,9 @@
   void DidChangeSelectionInSelectControl(HTMLFormControlElement&) override;
   void SelectOrSelectListFieldOptionsChanged(HTMLFormControlElement&) override;
   void AjaxSucceeded(LocalFrame*) override;
-  void JavaScriptChangedAutofilledValue(HTMLFormControlElement&,
-                                        const String& old_value) override;
+  void JavaScriptChangedValue(HTMLFormControlElement&,
+                              const String& old_value,
+                              bool was_autofilled) 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 d6d0e5a..6e737d6 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
@@ -84,8 +84,9 @@
 namespace {
 class FakeChromeClientForAutofill : public EmptyChromeClient {
  public:
-  void JavaScriptChangedAutofilledValue(HTMLFormControlElement& element,
-                                        const String& old_value) override {
+  void JavaScriptChangedValue(HTMLFormControlElement& element,
+                              const String& old_value,
+                              bool was_autofilled) override {
     last_notification_ = {element.GetIdAttribute().Utf8(), old_value.Utf8()};
   }
   std::vector<std::string> GetAndResetLastEvent() {
@@ -395,7 +396,7 @@
   base::test::ScopedFeatureList scoped_feature_list_;
 };
 
-// Validates the JavaScriptChangedAutofilledValue notification if JavaScript
+// Validates the JavaScriptChangedValue notification if JavaScript
 // overrides the autofilled content of form controls *after* the fill has been
 // concluded.
 TEST_F(AutofillChromeClientTest, NotificationsOfJavaScriptChangesAfterFill) {
@@ -474,16 +475,17 @@
   EXPECT_THAT(chrome_client_->GetAndResetLastEvent(),
               ::testing::ElementsAre("selectlist", "autofilled_selectlist"));
 
-  // Because this is not in state "autofilled", the chrome client is not
+  // Even for elements that are not in state "autofilled", the chrome client is
   // informed about the change.
   EXPECT_THAT(not_autofilled_text->Value().IsNull(), ::testing::IsTrue());
   ExecuteScript(
       "document.getElementById('not_autofilled_text').value = 'new_text';");
   EXPECT_THAT(not_autofilled_text->Value(), Eq("new_text"));
-  EXPECT_THAT(chrome_client_->GetAndResetLastEvent(), ::testing::ElementsAre());
+  EXPECT_THAT(chrome_client_->GetAndResetLastEvent(),
+              ::testing::ElementsAre("not_autofilled_text", ""));
 }
 
-// Validates the JavaScriptChangedAutofilledValue notification if JavaScript
+// Validates the JavaScriptChangedValue notification if JavaScript
 // overrides the autofilled content of form controls during the fill operation.
 // This is the case because a JavaScript event handler on change signals is
 // is triggered during the autofill operation.
diff --git a/third_party/blink/renderer/core/paint/box_fragment_painter.cc b/third_party/blink/renderer/core/paint/box_fragment_painter.cc
index 6e13fc0..3b05112 100644
--- a/third_party/blink/renderer/core/paint/box_fragment_painter.cc
+++ b/third_party/blink/renderer/core/paint/box_fragment_painter.cc
@@ -1732,6 +1732,12 @@
   }
 
   if (child_fragment.IsAtomicInline() || child_fragment.IsListMarker()) {
+    // Establish a display item fragment scope here, in case there are multiple
+    // fragment items for the same layout object. This is unusual for atomic
+    // inlines, but might happen e.g. if an text-overflow ellipsis is associated
+    // with the layout object.
+    ScopedDisplayItemFragment display_item_fragment(paint_info.context,
+                                                    item.FragmentId());
     PaintFragment(child_fragment, paint_info);
     return;
   }
diff --git a/third_party/blink/renderer/core/probe/core_probes.json5 b/third_party/blink/renderer/core/probe/core_probes.json5
index 8c74bc97..6b0b08bb 100644
--- a/third_party/blink/renderer/core/probe/core_probes.json5
+++ b/third_party/blink/renderer/core/probe/core_probes.json5
@@ -207,6 +207,7 @@
         "WebTransportCreated",
         "WebTransportConnectionEstablished",
         "WebTransportClosed",
+        "WillCreateP2PSocketUdp",
         "WillCreateWebSocket",
         "WillDispatchEventSourceEvent",
         "WillLoadXHR",
diff --git a/third_party/blink/renderer/core/probe/core_probes.pidl b/third_party/blink/renderer/core/probe/core_probes.pidl
index 51bff2c7..adbfc98 100644
--- a/third_party/blink/renderer/core/probe/core_probes.pidl
+++ b/third_party/blink/renderer/core/probe/core_probes.pidl
@@ -146,6 +146,7 @@
   void WebTransportCreated([Keep] ExecutionContext*, uint64_t transport_id, const KURL& request_url);
   void WebTransportConnectionEstablished(ExecutionContext*, uint64_t transport_id);
   void WebTransportClosed(ExecutionContext*, uint64_t transport_id);
+  void WillCreateP2PSocketUdp(ExecutionContext*, absl::optional<base::UnguessableToken>* devtools_token);
   /* This is for pre-BlinkGenPropertyTrees. TODO(wangxianzhu): Remove this function for BlinkGenPropertyTrees. */
   void LayerTreeDidChange(LocalFrame*);
   void LayerTreePainted(LocalFrame*);
diff --git a/third_party/blink/renderer/core/style/build.gni b/third_party/blink/renderer/core/style/build.gni
index f6e349f..f2a111bd5 100644
--- a/third_party/blink/renderer/core/style/build.gni
+++ b/third_party/blink/renderer/core/style/build.gni
@@ -54,6 +54,8 @@
   "ordered_named_grid_lines.h",
   "paint_images.h",
   "paint_order_array.h",
+  "position_try_options.cc",
+  "position_try_options.h",
   "quad_length_value.h",
   "reference_clip_path_operation.cc",
   "reference_clip_path_operation.h",
diff --git a/third_party/blink/renderer/core/style/position_try_options.cc b/third_party/blink/renderer/core/style/position_try_options.cc
new file mode 100644
index 0000000..888a6d0a
--- /dev/null
+++ b/third_party/blink/renderer/core/style/position_try_options.cc
@@ -0,0 +1,26 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/style/position_try_options.h"
+
+namespace blink {
+
+bool PositionTryOption::operator==(const PositionTryOption& other) const {
+  return tactic_ == other.tactic_ &&
+         base::ValuesEquivalent(position_try_name_, other.position_try_name_);
+}
+
+void PositionTryOption::Trace(Visitor* visitor) const {
+  visitor->Trace(position_try_name_);
+}
+
+bool PositionTryOptions::operator==(const PositionTryOptions& other) const {
+  return options_ == other.options_;
+}
+
+void PositionTryOptions::Trace(Visitor* visitor) const {
+  visitor->Trace(options_);
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/style/position_try_options.h b/third_party/blink/renderer/core/style/position_try_options.h
new file mode 100644
index 0000000..8c015e00
--- /dev/null
+++ b/third_party/blink/renderer/core/style/position_try_options.h
@@ -0,0 +1,73 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_POSITION_TRY_OPTIONS_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_POSITION_TRY_OPTIONS_H_
+
+#include "third_party/blink/renderer/core/style/scoped_css_name.h"
+
+namespace blink {
+
+enum class TryTactic {
+  kNone = 0,
+  kFlipBlock = 1 << 1,
+  kFlipInline = 1 << 2,
+  kFlipStart = 1 << 3,
+};
+
+using TryTacticFlags = unsigned;
+
+class CORE_EXPORT PositionTryOption {
+  DISALLOW_NEW();
+
+ public:
+  explicit PositionTryOption(TryTacticFlags tactic) : tactic_(tactic) {}
+  explicit PositionTryOption(const ScopedCSSName* name)
+      : position_try_name_(name) {}
+
+  bool HasTryTactic() const {
+    return tactic_ != static_cast<TryTacticFlags>(TryTactic::kNone);
+  }
+  TryTacticFlags GetTryTactic() const { return tactic_; }
+  const ScopedCSSName* GetPositionTryName() const { return position_try_name_; }
+
+  bool operator==(const PositionTryOption& other) const;
+
+  void Trace(Visitor* visitor) const;
+
+ private:
+  Member<const ScopedCSSName> position_try_name_;
+  TryTacticFlags tactic_ = static_cast<TryTacticFlags>(TryTactic::kNone);
+};
+
+class CORE_EXPORT PositionTryOptions
+    : public GarbageCollected<PositionTryOptions> {
+ public:
+  PositionTryOptions(HeapVector<PositionTryOption> options)
+      : options_(std::move(options)) {}
+
+  const HeapVector<PositionTryOption>& GetOptions() const { return options_; }
+  bool operator==(const PositionTryOptions& other) const;
+  void Trace(Visitor* visitor) const;
+
+ private:
+  HeapVector<PositionTryOption> options_;
+};
+
+}  // namespace blink
+
+namespace WTF {
+
+template <>
+struct VectorTraits<blink::PositionTryOption>
+    : VectorTraitsBase<blink::PositionTryOption> {
+  static const bool kCanClearUnusedSlotsWithMemset = true;
+  static const bool kCanInitializeWithMemset = true;
+  static const bool kCanMoveWithMemcpy = true;
+  static const bool kCanTraceConcurrently = true;
+};
+
+}  // namespace WTF
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_POSITION_TRY_OPTIONS_H_
diff --git a/third_party/blink/renderer/modules/peerconnection/DEPS b/third_party/blink/renderer/modules/peerconnection/DEPS
index 29c76081..a3c35cb 100644
--- a/third_party/blink/renderer/modules/peerconnection/DEPS
+++ b/third_party/blink/renderer/modules/peerconnection/DEPS
@@ -17,6 +17,7 @@
     # TODO(crbug.com/787254): Remove the use of base::CurrentThread.
     "+base/task/current_thread.h",
     "+base/threading/thread.h",
+    "+base/unguessable_token.h",
     "+base/values.h",
     "+crypto/openssl_util.h",
     "+components/webrtc/thread_wrapper.h",
diff --git a/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h b/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h
index c7f8bcb..e8d08ff 100644
--- a/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h
+++ b/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h
@@ -11,6 +11,7 @@
 #include <set>
 #include <vector>
 
+#include "base/unguessable_token.h"
 #include "third_party/blink/public/platform/web_vector.h"
 #include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -46,6 +47,13 @@
 namespace WTF {
 
 template <>
+struct CrossThreadCopier<absl::optional<base::UnguessableToken>>
+    : public CrossThreadCopierPassThrough<
+          absl::optional<base::UnguessableToken>> {
+  STATIC_ONLY(CrossThreadCopier);
+};
+
+template <>
 struct CrossThreadCopier<cricket::IceParameters>
     : public CrossThreadCopierPassThrough<cricket::IceParameters> {
   STATIC_ONLY(CrossThreadCopier);
diff --git a/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc b/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc
index a54310e..b71f97c 100644
--- a/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc
+++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc
@@ -12,7 +12,9 @@
 #include <vector>
 
 #include "base/feature_list.h"
+#include "base/functional/bind.h"
 #include "base/functional/callback.h"
+#include "base/functional/callback_forward.h"
 #include "base/functional/callback_helpers.h"
 #include "base/location.h"
 #include "base/logging.h"
@@ -24,6 +26,7 @@
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/time/time.h"
+#include "base/unguessable_token.h"
 #include "build/build_config.h"
 #include "components/webrtc/thread_wrapper.h"
 #include "crypto/openssl_util.h"
@@ -37,6 +40,7 @@
 #include "third_party/blink/public/common/peerconnection/webrtc_ip_handling_policy.h"
 #include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h"
 #include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/public/platform/web_url.h"
 #include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h"
 #include "third_party/blink/public/web/web_document.h"
@@ -44,14 +48,18 @@
 #include "third_party/blink/public/web/web_view.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/frame/dom_window.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/core/probe/core_probes.h"
 #include "third_party/blink/renderer/modules/mediastream/media_constraints.h"
+#include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_error_util.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h"
 #include "third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.h"
 #include "third_party/blink/renderer/platform/graphics/video_frame_sink_bundle.h"
 #include "third_party/blink/renderer/platform/heap/cross_thread_persistent.h"
+#include "third_party/blink/renderer/platform/heap/persistent.h"
 #include "third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h"
 #include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h"
 #include "third_party/blink/renderer/platform/p2p/empty_network_manager.h"
@@ -469,6 +477,8 @@
     PassKey)
     : Supplement(context),
       ExecutionContextLifecycleObserver(&context),
+      context_task_runner_(
+          context.GetTaskRunner(TaskType::kInternalMediaRealTime)),
       network_manager_(nullptr),
       p2p_socket_dispatcher_(P2PSocketDispatcher::From(context)) {
   // Initialize mojo pipe for encode/decode performance stats data collection.
@@ -656,6 +666,9 @@
         }
     )");
   socket_factory_ = std::make_unique<IpcPacketSocketFactory>(
+      WTF::CrossThreadBindRepeating(
+          &PeerConnectionDependencyFactory::DoGetDevtoolsToken,
+          WrapCrossThreadWeakPersistent(this)),
       p2p_socket_dispatcher_.Get(), traffic_annotation, /*batch_udp_packets=*/
       base::FeatureList::IsEnabled(features::kWebRtcSendPacketBatch));
 
@@ -727,6 +740,33 @@
   event->Signal();
 }
 
+void PeerConnectionDependencyFactory::DoGetDevtoolsToken(
+    base::OnceCallback<void(absl::optional<base::UnguessableToken>)> then) {
+  context_task_runner_->PostTaskAndReplyWithResult(
+      FROM_HERE,
+      ConvertToBaseOnceCallback(WTF::CrossThreadBindOnce(
+          [](PeerConnectionDependencyFactory* factory)
+              -> absl::optional<base::UnguessableToken> {
+            if (!factory) {
+              return absl::nullopt;
+            }
+            return factory->GetDevtoolsToken();
+          },
+          WrapCrossThreadWeakPersistent(this))),
+      std::move(then));
+}
+
+absl::optional<base::UnguessableToken>
+PeerConnectionDependencyFactory::GetDevtoolsToken() {
+  if (!GetExecutionContext()) {
+    return absl::nullopt;
+  }
+  CHECK(GetExecutionContext()->IsContextThread());
+  absl::optional<base::UnguessableToken> devtools_token;
+  probe::WillCreateP2PSocketUdp(GetExecutionContext(), &devtools_token);
+  return devtools_token;
+}
+
 bool PeerConnectionDependencyFactory::PeerConnectionFactoryCreated() {
   return !!pc_factory_;
 }
diff --git a/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h b/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h
index 22d1d85c..acaf6cdd 100644
--- a/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h
+++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h
@@ -7,6 +7,7 @@
 
 #include "base/feature_list.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread.h"
@@ -197,6 +198,11 @@
       base::WaitableEvent* event);
   void CleanupPeerConnectionFactory();
 
+  void DoGetDevtoolsToken(
+      base::OnceCallback<void(absl::optional<base::UnguessableToken>)> then);
+  absl::optional<base::UnguessableToken> GetDevtoolsToken();
+  scoped_refptr<base::SequencedTaskRunner> context_task_runner_;
+
   // network_manager_ must be deleted on the network thread. The network manager
   // uses |p2p_socket_dispatcher_|.
   std::unique_ptr<IpcNetworkManager> network_manager_;
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
index ff64e27..d984b24 100644
--- a/third_party/blink/renderer/platform/BUILD.gn
+++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1408,6 +1408,8 @@
     "text/date_time_format.cc",
     "text/date_time_format.h",
     "text/decode_escape_sequences.h",
+    "text/emoji_segmentation_category.h",
+    "text/emoji_segmentation_category_inline_header.h",
     "text/han_kerning_char_type.h",
     "text/hyphenation.cc",
     "text/hyphenation.h",
diff --git a/third_party/blink/renderer/platform/fonts/utf16_ragel_iterator.cc b/third_party/blink/renderer/platform/fonts/utf16_ragel_iterator.cc
index 8d0051a..6223729 100644
--- a/third_party/blink/renderer/platform/fonts/utf16_ragel_iterator.cc
+++ b/third_party/blink/renderer/platform/fonts/utf16_ragel_iterator.cc
@@ -5,61 +5,11 @@
 #include "third_party/blink/renderer/platform/fonts/utf16_ragel_iterator.h"
 
 #include "third_party/blink/renderer/platform/text/character.h"
+#include "third_party/blink/renderer/platform/text/emoji_segmentation_category_inline_header.h"
 #include "third_party/blink/renderer/platform/wtf/text/character_names.h"
 
 namespace blink {
 
-namespace {
-
-char EmojiSegmentationCategory(UChar32 codepoint) {
-  if (codepoint <= 0x7F) {
-    if (Character::IsEmojiKeycapBase(codepoint))
-      return UTF16RagelIterator::KEYCAP_BASE;
-    return UTF16RagelIterator::kMaxEmojiScannerCategory;
-  }
-  // For the grammar to work, we need to check for more specific character
-  // classes first, then expand towards more generic ones. So we match single
-  // characters and small ranges first, then return EMOJI and
-  // EMOJI_TEXT_PRESENTATION for the remaining ones.
-  if (codepoint == kCombiningEnclosingKeycapCharacter)
-    return UTF16RagelIterator::COMBINING_ENCLOSING_KEYCAP;
-  if (codepoint == kCombiningEnclosingCircleBackslashCharacter)
-    return UTF16RagelIterator::COMBINING_ENCLOSING_CIRCLE_BACKSLASH;
-  if (codepoint == kZeroWidthJoinerCharacter)
-    return UTF16RagelIterator::ZWJ;
-  if (codepoint == kVariationSelector15Character)
-    return UTF16RagelIterator::VS15;
-  if (codepoint == kVariationSelector16Character)
-    return UTF16RagelIterator::VS16;
-  if (codepoint == 0x1F3F4)
-    return UTF16RagelIterator::TAG_BASE;
-  if (Character::IsEmojiTagSequence(codepoint))
-    return UTF16RagelIterator::TAG_SEQUENCE;
-  if (codepoint == kCancelTag) {
-    // http://www.unicode.org/reports/tr51/#def_emoji_tag_sequence
-    // defines a TAG_TERM grammar rule for U+E007F CANCEL TAG.
-    return UTF16RagelIterator::TAG_TERM;
-  }
-  if (Character::IsEmojiModifierBase(codepoint))
-    return UTF16RagelIterator::EMOJI_MODIFIER_BASE;
-  if (Character::IsModifier(codepoint))
-    return UTF16RagelIterator::EMOJI_MODIFIER;
-  if (Character::IsRegionalIndicator(codepoint))
-    return UTF16RagelIterator::REGIONAL_INDICATOR;
-
-  if (Character::IsEmojiEmojiDefault(codepoint))
-    return UTF16RagelIterator::EMOJI_EMOJI_PRESENTATION;
-  if (Character::IsEmojiTextDefault(codepoint))
-    return UTF16RagelIterator::EMOJI_TEXT_PRESENTATION;
-  if (Character::IsEmoji(codepoint))
-    return UTF16RagelIterator::EMOJI;
-
-  // Ragel state machine will interpret unknown category as "any".
-  return UTF16RagelIterator::kMaxEmojiScannerCategory;
-}
-
-}  // namespace
-
 UTF16RagelIterator& UTF16RagelIterator::SetCursor(unsigned new_cursor) {
   CHECK_GE(new_cursor, 0u);
   CHECK_LT(new_cursor, buffer_size_);
@@ -71,7 +21,7 @@
 void UTF16RagelIterator::UpdateCachedCategory() {
   if (cursor_ >= buffer_size_)
     return;
-  cached_category_ = EmojiSegmentationCategory(Codepoint());
+  cached_category_ = GetEmojiSegmentationCategory(Codepoint());
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/fonts/utf16_ragel_iterator.h b/third_party/blink/renderer/platform/fonts/utf16_ragel_iterator.h
index 66aae47..b445eac 100644
--- a/third_party/blink/renderer/platform/fonts/utf16_ragel_iterator.h
+++ b/third_party/blink/renderer/platform/fonts/utf16_ragel_iterator.h
@@ -9,6 +9,7 @@
 
 #include "base/check_op.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/text/emoji_segmentation_category.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 
 namespace blink {
@@ -32,7 +33,7 @@
       : buffer_(buffer),
         buffer_size_(buffer_size),
         cursor_(cursor),
-        cached_category_(kMaxEmojiScannerCategory) {
+        cached_category_(EmojiSegmentationCategory::kMaxCategory) {
     UpdateCachedCategory();
   }
 
@@ -105,7 +106,7 @@
     return ret;
   }
 
-  UChar32 operator*() {
+  EmojiSegmentationCategory operator*() {
     CHECK(buffer_size_);
     return cached_category_;
   }
@@ -119,29 +120,6 @@
     return !(*this == other);
   }
 
-  // Must match the categories defined in third-party/emoji-segmenter/.
-  // TODO(drott): Add static asserts once emoji-segmenter is imported to
-  // third-party.
-  enum EmojiScannerCharacterClass {
-    EMOJI = 0,
-    EMOJI_TEXT_PRESENTATION = 1,
-    EMOJI_EMOJI_PRESENTATION = 2,
-    EMOJI_MODIFIER_BASE = 3,
-    EMOJI_MODIFIER = 4,
-    EMOJI_VS_BASE = 5,
-    REGIONAL_INDICATOR = 6,
-    KEYCAP_BASE = 7,
-    COMBINING_ENCLOSING_KEYCAP = 8,
-    COMBINING_ENCLOSING_CIRCLE_BACKSLASH = 9,
-    ZWJ = 10,
-    VS15 = 11,
-    VS16 = 12,
-    TAG_BASE = 13,
-    TAG_SEQUENCE = 14,
-    TAG_TERM = 15,
-    kMaxEmojiScannerCategory = 16
-  };
-
  private:
   UChar32 Codepoint() const {
     DCHECK_GT(buffer_size_, 0u);
@@ -155,7 +133,7 @@
   const UChar* buffer_;
   unsigned buffer_size_;
   unsigned cursor_;
-  unsigned char cached_category_;
+  EmojiSegmentationCategory cached_category_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/fonts/utf16_ragel_iterator_test.cc b/third_party/blink/renderer/platform/fonts/utf16_ragel_iterator_test.cc
index 9bbd27b..dd397cbf 100644
--- a/third_party/blink/renderer/platform/fonts/utf16_ragel_iterator_test.cc
+++ b/third_party/blink/renderer/platform/fonts/utf16_ragel_iterator_test.cc
@@ -32,24 +32,25 @@
   icu::UnicodeString class_examples_unicode_string =
       icu::UnicodeString::fromUTF32(class_examples_codepoints,
                                     std::size(class_examples_codepoints));
-  char categories[] = {UTF16RagelIterator::COMBINING_ENCLOSING_KEYCAP,
-                       UTF16RagelIterator::COMBINING_ENCLOSING_CIRCLE_BACKSLASH,
-                       UTF16RagelIterator::ZWJ,
-                       UTF16RagelIterator::VS15,
-                       UTF16RagelIterator::VS16,
-                       UTF16RagelIterator::TAG_BASE,
-                       UTF16RagelIterator::TAG_SEQUENCE,
-                       UTF16RagelIterator::TAG_TERM,
-                       UTF16RagelIterator::EMOJI_MODIFIER_BASE,
-                       UTF16RagelIterator::EMOJI_MODIFIER,
-                       UTF16RagelIterator::REGIONAL_INDICATOR,
-                       UTF16RagelIterator::KEYCAP_BASE,
-                       UTF16RagelIterator::EMOJI_EMOJI_PRESENTATION,
-                       UTF16RagelIterator::EMOJI_TEXT_PRESENTATION};
+  const EmojiSegmentationCategory categories[] = {
+      EmojiSegmentationCategory::COMBINING_ENCLOSING_KEYCAP,
+      EmojiSegmentationCategory::COMBINING_ENCLOSING_CIRCLE_BACKSLASH,
+      EmojiSegmentationCategory::ZWJ,
+      EmojiSegmentationCategory::VS15,
+      EmojiSegmentationCategory::VS16,
+      EmojiSegmentationCategory::TAG_BASE,
+      EmojiSegmentationCategory::TAG_SEQUENCE,
+      EmojiSegmentationCategory::TAG_TERM,
+      EmojiSegmentationCategory::EMOJI_MODIFIER_BASE,
+      EmojiSegmentationCategory::EMOJI_MODIFIER,
+      EmojiSegmentationCategory::REGIONAL_INDICATOR,
+      EmojiSegmentationCategory::KEYCAP_BASE,
+      EmojiSegmentationCategory::EMOJI_EMOJI_PRESENTATION,
+      EmojiSegmentationCategory::EMOJI_TEXT_PRESENTATION};
   UTF16RagelIterator ragel_iterator(
       reinterpret_cast<const UChar*>(class_examples_unicode_string.getBuffer()),
       class_examples_unicode_string.length());
-  for (char& category : categories) {
+  for (const EmojiSegmentationCategory& category : categories) {
     CHECK_EQ(category, *ragel_iterator);
     ragel_iterator++;
   }
@@ -80,15 +81,15 @@
       reinterpret_cast<const UChar*>(class_examples_unicode_string.getBuffer()),
       class_examples_unicode_string.length());
 
-  CHECK_EQ(*ragel_iterator, UTF16RagelIterator::VS15);
-  CHECK_EQ(*(ragel_iterator + 2), UTF16RagelIterator::VS15);
-  CHECK_EQ(*(ragel_iterator + 3), UTF16RagelIterator::VS16);
-  CHECK_EQ(*(ragel_iterator + 5), UTF16RagelIterator::VS16);
+  CHECK_EQ(*ragel_iterator, EmojiSegmentationCategory::VS15);
+  CHECK_EQ(*(ragel_iterator + 2), EmojiSegmentationCategory::VS15);
+  CHECK_EQ(*(ragel_iterator + 3), EmojiSegmentationCategory::VS16);
+  CHECK_EQ(*(ragel_iterator + 5), EmojiSegmentationCategory::VS16);
 
-  CHECK_EQ(*(ragel_iterator += 3), UTF16RagelIterator::VS16);
-  CHECK_EQ(*(ragel_iterator += 2), UTF16RagelIterator::VS16);
-  CHECK_EQ(*(ragel_iterator -= 4), UTF16RagelIterator::VS15);
-  CHECK_EQ(*(ragel_iterator += 1), UTF16RagelIterator::VS15);
+  CHECK_EQ(*(ragel_iterator += 3), EmojiSegmentationCategory::VS16);
+  CHECK_EQ(*(ragel_iterator += 2), EmojiSegmentationCategory::VS16);
+  CHECK_EQ(*(ragel_iterator -= 4), EmojiSegmentationCategory::VS15);
+  CHECK_EQ(*(ragel_iterator += 1), EmojiSegmentationCategory::VS15);
 
   ragel_iterator += 3;
 
@@ -96,10 +97,10 @@
   CHECK(ragel_iterator != ragel_iterator_begin);
   CHECK(ragel_iterator == ragel_iterator.end() - 1);
 
-  CHECK_EQ(*ragel_iterator, UTF16RagelIterator::VS16);
-  CHECK_EQ(*(ragel_iterator - 2), UTF16RagelIterator::VS16);
-  CHECK_EQ(*(ragel_iterator - 3), UTF16RagelIterator::VS15);
-  CHECK_EQ(*(ragel_iterator - 5), UTF16RagelIterator::VS15);
+  CHECK_EQ(*ragel_iterator, EmojiSegmentationCategory::VS16);
+  CHECK_EQ(*(ragel_iterator - 2), EmojiSegmentationCategory::VS16);
+  CHECK_EQ(*(ragel_iterator - 3), EmojiSegmentationCategory::VS15);
+  CHECK_EQ(*(ragel_iterator - 5), EmojiSegmentationCategory::VS15);
 }
 
 TEST(UTF16RagelIteratorTest, InvalidOperationOnEmpty) {
@@ -122,11 +123,12 @@
 
   CHECK_EQ(ragel_iterator.end().Cursor(), 8u);
 
-  CHECK_EQ(*ragel_iterator, UTF16RagelIterator::EMOJI_EMOJI_PRESENTATION);
+  CHECK_EQ(*ragel_iterator,
+           EmojiSegmentationCategory::EMOJI_EMOJI_PRESENTATION);
   CHECK_EQ(*(ragel_iterator.SetCursor(4)),
-           UTF16RagelIterator::EMOJI_EMOJI_PRESENTATION);
+           EmojiSegmentationCategory::EMOJI_EMOJI_PRESENTATION);
   CHECK_EQ(*(ragel_iterator.SetCursor(6)),
-           UTF16RagelIterator::EMOJI_TEXT_PRESENTATION);
+           EmojiSegmentationCategory::EMOJI_TEXT_PRESENTATION);
 
   EXPECT_DCHECK_DEATH(ragel_iterator.SetCursor(-1));
   EXPECT_DCHECK_DEATH(ragel_iterator.SetCursor(ragel_iterator.end().Cursor()));
diff --git a/third_party/blink/renderer/platform/p2p/ipc_socket_factory.cc b/third_party/blink/renderer/platform/p2p/ipc_socket_factory.cc
index e55567d0..02d5644 100644
--- a/third_party/blink/renderer/platform/p2p/ipc_socket_factory.cc
+++ b/third_party/blink/renderer/platform/p2p/ipc_socket_factory.cc
@@ -11,19 +11,25 @@
 #include <memory>
 
 #include "base/compiler_specific.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
 #include "base/logging.h"
 #include "base/memory/weak_ptr.h"
 #include "base/strings/stringprintf.h"
+#include "base/task/bind_post_task.h"
 #include "base/threading/thread_checker.h"
 #include "base/trace_event/trace_event.h"
+#include "base/unguessable_token.h"
 #include "components/webrtc/net_address_utils.h"
 #include "net/base/ip_address.h"
 #include "net/base/port_util.h"
 #include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h"
+#include "third_party/blink/renderer/platform/heap/cross_thread_persistent.h"
 #include "third_party/blink/renderer/platform/p2p/host_address_request.h"
 #include "third_party/blink/renderer/platform/p2p/socket_client_delegate.h"
 #include "third_party/blink/renderer/platform/p2p/socket_client_impl.h"
 #include "third_party/blink/renderer/platform/p2p/socket_dispatcher.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 #include "third_party/webrtc/api/async_dns_resolver.h"
@@ -112,14 +118,18 @@
   typedef std::list<InFlightPacketRecord> InFlightPacketList;
 
   // Always takes ownership of client even if initialization fails.
-  bool Init(P2PSocketDispatcher* dispatcher,
-            const net::NetworkTrafficAnnotationTag& traffic_annotation,
-            network::P2PSocketType type,
-            std::unique_ptr<P2PSocketClientImpl> client,
-            const rtc::SocketAddress& local_address,
-            uint16_t min_port,
-            uint16_t max_port,
-            const rtc::SocketAddress& remote_address);
+  bool Init(
+      P2PSocketDispatcher* dispatcher,
+      const net::NetworkTrafficAnnotationTag& traffic_annotation,
+      network::P2PSocketType type,
+      std::unique_ptr<P2PSocketClientImpl> client,
+      const rtc::SocketAddress& local_address,
+      uint16_t min_port,
+      uint16_t max_port,
+      const rtc::SocketAddress& remote_address,
+      WTF::CrossThreadFunction<void(
+          base::OnceCallback<void(absl::optional<base::UnguessableToken>)>)>&
+          devtools_token);
 
   // rtc::AsyncPacketSocket interface.
   rtc::SocketAddress GetLocalAddress() const override;
@@ -149,6 +159,17 @@
                       const base::TimeTicks& timestamp) override;
 
  private:
+  static void DoCreateSocket(
+      network::P2PSocketType type,
+      P2PSocketDispatcher* dispatcher,
+      net::IPEndPoint local_endpoint,
+      uint16_t min_port,
+      uint16_t max_port,
+      network::P2PHostAndIPEndPoint remote_info,
+      net::NetworkTrafficAnnotationTag traffic_annotation,
+      mojo::PendingRemote<network::mojom::blink::P2PSocketClient> remote,
+      mojo::PendingReceiver<network::mojom::blink::P2PSocket> receiver,
+      absl::optional<base::UnguessableToken> devtools_token);
   int SendToInternal(const void* pv,
                      size_t cb,
                      const rtc::SocketAddress& addr,
@@ -171,10 +192,6 @@
   // |in_flight_packet_records_|.
   void TraceSendThrottlingState() const;
 
-  void InitAcceptedTcp(std::unique_ptr<blink::P2PSocketClient> client,
-                       const rtc::SocketAddress& local_address,
-                       const rtc::SocketAddress& remote_address);
-
   int DoSetOption(network::P2PSocketOption option, int value);
 
   network::P2PSocketType type_;
@@ -183,7 +200,7 @@
   THREAD_CHECKER(thread_checker_);
 
   // Corresponding P2P socket client.
-  std::unique_ptr<blink::P2PSocketClient> client_;
+  std::unique_ptr<blink::P2PSocketClientImpl> client_;
 
   // Local address is allocated by the browser process, and the
   // renderer side doesn't know the address until it receives OnOpen()
@@ -305,12 +322,14 @@
     const rtc::SocketAddress& local_address,
     uint16_t min_port,
     uint16_t max_port,
-    const rtc::SocketAddress& remote_address) {
+    const rtc::SocketAddress& remote_address,
+    WTF::CrossThreadFunction<
+        void(base::OnceCallback<void(absl::optional<base::UnguessableToken>)>)>&
+        devtools_token_getter) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK_EQ(state_, kIsUninitialized);
 
   type_ = type;
-  auto* client_ptr = client.get();
   client_ = std::move(client);
   local_address_ = local_address;
   remote_address_ = remote_address;
@@ -341,29 +360,35 @@
   // Certificate will be tied to domain name not to IP address.
   network::P2PHostAndIPEndPoint remote_info(remote_address.hostname(),
                                             remote_endpoint);
-  dispatcher->GetP2PSocketManager()->CreateSocket(
-      type, local_endpoint, network::P2PPortRange(min_port, max_port),
-      remote_info, net::MutableNetworkTrafficAnnotationTag(traffic_annotation),
-      client_ptr->CreatePendingRemote(), client_ptr->CreatePendingReceiver());
 
-  client_ptr->Init(this);
+  devtools_token_getter.Run(base::BindPostTaskToCurrentDefault(WTF::BindOnce(
+      &IpcPacketSocket::DoCreateSocket, type_,
+      WrapCrossThreadPersistent(dispatcher), local_endpoint, min_port, max_port,
+      remote_info, traffic_annotation, client_->CreatePendingRemote(),
+      client_->CreatePendingReceiver())));
+
+  client_->Init(this);
 
   return true;
 }
 
-void IpcPacketSocket::InitAcceptedTcp(
-    std::unique_ptr<blink::P2PSocketClient> client,
-    const rtc::SocketAddress& local_address,
-    const rtc::SocketAddress& remote_address) {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  DCHECK_EQ(state_, kIsUninitialized);
+void IpcPacketSocket::DoCreateSocket(
+    network::P2PSocketType type,
+    P2PSocketDispatcher* dispatcher,
+    net::IPEndPoint local_endpoint,
+    uint16_t min_port,
+    uint16_t max_port,
+    network::P2PHostAndIPEndPoint remote_info,
+    net::NetworkTrafficAnnotationTag traffic_annotation,
+    mojo::PendingRemote<network::mojom::blink::P2PSocketClient> remote,
+    mojo::PendingReceiver<network::mojom::blink::P2PSocket> receiver,
+    absl::optional<base::UnguessableToken> devtools_token) {
+  CHECK(dispatcher);
 
-  client_ = std::move(client);
-  local_address_ = local_address;
-  remote_address_ = remote_address;
-  state_ = kIsOpen;
-  TraceSendThrottlingState();
-  client_->SetDelegate(this);
+  dispatcher->GetP2PSocketManager()->CreateSocket(
+      type, local_endpoint, network::P2PPortRange(min_port, max_port),
+      remote_info, net::MutableNetworkTrafficAnnotationTag(traffic_annotation),
+      devtools_token, std::move(remote), std::move(receiver));
 }
 
 // rtc::AsyncPacketSocket interface.
@@ -765,10 +790,14 @@
 }  // namespace
 
 IpcPacketSocketFactory::IpcPacketSocketFactory(
+    WTF::CrossThreadFunction<
+        void(base::OnceCallback<void(absl::optional<base::UnguessableToken>)>)>
+        devtools_token_getter,
     P2PSocketDispatcher* socket_dispatcher,
     const net::NetworkTrafficAnnotationTag& traffic_annotation,
     bool batch_udp_packets)
-    : batch_udp_packets_(batch_udp_packets),
+    : devtools_token_getter_(std::move(devtools_token_getter)),
+      batch_udp_packets_(batch_udp_packets),
       socket_dispatcher_(socket_dispatcher),
       traffic_annotation_(traffic_annotation) {}
 
@@ -783,9 +812,11 @@
   auto socket_client =
       std::make_unique<P2PSocketClientImpl>(batch_udp_packets_);
   std::unique_ptr<IpcPacketSocket> socket(new IpcPacketSocket());
+
   if (!socket->Init(socket_dispatcher, traffic_annotation_,
                     network::P2P_SOCKET_UDP, std::move(socket_client),
-                    local_address, min_port, max_port, rtc::SocketAddress())) {
+                    local_address, min_port, max_port, rtc::SocketAddress(),
+                    devtools_token_getter_)) {
     return nullptr;
   }
   return socket.release();
@@ -831,7 +862,7 @@
   std::unique_ptr<IpcPacketSocket> socket(new IpcPacketSocket());
   if (!socket->Init(socket_dispatcher, traffic_annotation_, type,
                     std::move(socket_client), local_address, 0, 0,
-                    remote_address)) {
+                    remote_address, devtools_token_getter_)) {
     return nullptr;
   }
   return socket.release();
diff --git a/third_party/blink/renderer/platform/p2p/ipc_socket_factory.h b/third_party/blink/renderer/platform/p2p/ipc_socket_factory.h
index 7ee43ff..72eb895 100644
--- a/third_party/blink/renderer/platform/p2p/ipc_socket_factory.h
+++ b/third_party/blink/renderer/platform/p2p/ipc_socket_factory.h
@@ -7,9 +7,11 @@
 
 #include <stdint.h>
 
+#include "base/unguessable_token.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "third_party/blink/renderer/platform/heap/cross_thread_persistent.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
 #include "third_party/webrtc/api/packet_socket_factory.h"
 
 namespace blink {
@@ -26,6 +28,9 @@
 class IpcPacketSocketFactory : public rtc::PacketSocketFactory {
  public:
   PLATFORM_EXPORT explicit IpcPacketSocketFactory(
+      WTF::CrossThreadFunction<void(
+          base::OnceCallback<void(absl::optional<base::UnguessableToken>)>)>
+          devtools_token_getter,
       P2PSocketDispatcher* socket_dispatcher,
       const net::NetworkTrafficAnnotationTag& traffic_annotation,
       bool batch_udp_packets);
@@ -52,6 +57,9 @@
       override;
 
  private:
+  WTF::CrossThreadFunction<void(
+      base::OnceCallback<void(absl::optional<base::UnguessableToken>)>)>
+      devtools_token_getter_;
   const bool batch_udp_packets_;
 
   // `P2PSocketDispatcher` is owned by the main thread, and must be accessed in
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index e2a8df6..5440876 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -689,7 +689,7 @@
     {
       name: "CompressionDictionaryTransport",
       base_feature: "none",
-      origin_trial_feature_name: "CompressionDictionaryTransportForTest",
+      origin_trial_feature_name: "CompressionDictionaryTransportV2",
       origin_trial_allows_third_party: true,
       public: true,
     },
diff --git a/third_party/blink/renderer/platform/text/emoji_segmentation_category.h b/third_party/blink/renderer/platform/text/emoji_segmentation_category.h
new file mode 100644
index 0000000..8e09b47
--- /dev/null
+++ b/third_party/blink/renderer/platform/text/emoji_segmentation_category.h
@@ -0,0 +1,46 @@
+// Copyright 2019 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_EMOJI_SEGMENTATION_CATEGORY_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_EMOJI_SEGMENTATION_CATEGORY_H_
+
+#include <cstdint>
+
+namespace blink {
+
+// Must match the categories defined in
+// `third-party/emoji-segmenter/src/emoji_presentation_scanner.rl`.
+enum class EmojiSegmentationCategory : uint8_t {
+  EMOJI = 0,
+  EMOJI_TEXT_PRESENTATION = 1,
+  EMOJI_EMOJI_PRESENTATION = 2,
+  EMOJI_MODIFIER_BASE = 3,
+  EMOJI_MODIFIER = 4,
+  EMOJI_VS_BASE = 5,
+  REGIONAL_INDICATOR = 6,
+  KEYCAP_BASE = 7,
+  COMBINING_ENCLOSING_KEYCAP = 8,
+  COMBINING_ENCLOSING_CIRCLE_BACKSLASH = 9,
+  ZWJ = 10,
+  VS15 = 11,
+  VS16 = 12,
+  TAG_BASE = 13,
+  TAG_SEQUENCE = 14,
+  TAG_TERM = 15,
+
+  kMaxCategory = 16
+};
+
+// These operators are needed for the generated code at
+// `third_party/emoji-segmenter`.
+inline bool operator<(EmojiSegmentationCategory a, uint8_t b) {
+  return static_cast<uint8_t>(a) < b;
+}
+inline bool operator>(EmojiSegmentationCategory a, uint8_t b) {
+  return static_cast<uint8_t>(a) > b;
+}
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_EMOJI_SEGMENTATION_CATEGORY_H_
diff --git a/third_party/blink/renderer/platform/text/emoji_segmentation_category_inline_header.h b/third_party/blink/renderer/platform/text/emoji_segmentation_category_inline_header.h
new file mode 100644
index 0000000..ab390e5
--- /dev/null
+++ b/third_party/blink/renderer/platform/text/emoji_segmentation_category_inline_header.h
@@ -0,0 +1,81 @@
+// Copyright 2019 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_EMOJI_SEGMENTATION_CATEGORY_INLINE_HEADER_H_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_EMOJI_SEGMENTATION_CATEGORY_INLINE_HEADER_H_
+
+#include "third_party/blink/renderer/platform/text/character.h"
+#include "third_party/blink/renderer/platform/text/emoji_segmentation_category.h"
+
+namespace blink {
+
+namespace {
+
+EmojiSegmentationCategory GetEmojiSegmentationCategory(UChar32 codepoint) {
+  if (codepoint <= 0x7F) {
+    if (Character::IsEmojiKeycapBase(codepoint)) {
+      return EmojiSegmentationCategory::KEYCAP_BASE;
+    }
+    return EmojiSegmentationCategory::kMaxCategory;
+  }
+
+  // For the grammar to work, we need to check for more specific character
+  // classes first, then expand towards more generic ones. So we match single
+  // characters and small ranges first, then return EMOJI and
+  // EMOJI_TEXT_PRESENTATION for the remaining ones.
+  if (codepoint == kCombiningEnclosingKeycapCharacter) {
+    return EmojiSegmentationCategory::COMBINING_ENCLOSING_KEYCAP;
+  }
+  if (codepoint == kCombiningEnclosingCircleBackslashCharacter) {
+    return EmojiSegmentationCategory::COMBINING_ENCLOSING_CIRCLE_BACKSLASH;
+  }
+  if (codepoint == kZeroWidthJoinerCharacter) {
+    return EmojiSegmentationCategory::ZWJ;
+  }
+  if (codepoint == kVariationSelector15Character) {
+    return EmojiSegmentationCategory::VS15;
+  }
+  if (codepoint == kVariationSelector16Character) {
+    return EmojiSegmentationCategory::VS16;
+  }
+  if (codepoint == 0x1F3F4) {
+    return EmojiSegmentationCategory::TAG_BASE;
+  }
+  if (Character::IsEmojiTagSequence(codepoint)) {
+    return EmojiSegmentationCategory::TAG_SEQUENCE;
+  }
+  if (codepoint == kCancelTag) {
+    // http://www.unicode.org/reports/tr51/#def_emoji_tag_sequence
+    // defines a TAG_TERM grammar rule for U+E007F CANCEL TAG.
+    return EmojiSegmentationCategory::TAG_TERM;
+  }
+  if (Character::IsEmojiModifierBase(codepoint)) {
+    return EmojiSegmentationCategory::EMOJI_MODIFIER_BASE;
+  }
+  if (Character::IsModifier(codepoint)) {
+    return EmojiSegmentationCategory::EMOJI_MODIFIER;
+  }
+  if (Character::IsRegionalIndicator(codepoint)) {
+    return EmojiSegmentationCategory::REGIONAL_INDICATOR;
+  }
+
+  if (Character::IsEmojiEmojiDefault(codepoint)) {
+    return EmojiSegmentationCategory::EMOJI_EMOJI_PRESENTATION;
+  }
+  if (Character::IsEmojiTextDefault(codepoint)) {
+    return EmojiSegmentationCategory::EMOJI_TEXT_PRESENTATION;
+  }
+  if (Character::IsEmoji(codepoint)) {
+    return EmojiSegmentationCategory::EMOJI;
+  }
+
+  // Ragel state machine will interpret unknown category as "any".
+  return EmojiSegmentationCategory::kMaxCategory;
+}
+
+}  // namespace
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_EMOJI_SEGMENTATION_CATEGORY_INLINE_HEADER_H_
diff --git a/third_party/blink/web_tests/ChromeTestExpectations b/third_party/blink/web_tests/ChromeTestExpectations
index d40b321..d7e1d5b 100644
--- a/third_party/blink/web_tests/ChromeTestExpectations
+++ b/third_party/blink/web_tests/ChromeTestExpectations
@@ -48,7 +48,6 @@
 crbug.com/1499775 external/wpt/webdriver/tests/bidi/browsing_context/locate_nodes/max_node_count.py [ Failure ]
 crbug.com/1499775 external/wpt/webdriver/tests/bidi/browsing_context/locate_nodes/ownership.py [ Failure ]
 crbug.com/1499775 external/wpt/webdriver/tests/bidi/browsing_context/locate_nodes/start_nodes.py [ Failure ]
-crbug.com/1499775 external/wpt/webdriver/tests/bidi/input/perform_actions/pointer_mouse_multiclick.py [ Failure ]
 
 # Gardener 2023-12-19
 crbug.com/1512897 external/wpt/webdriver/tests/bidi/network/combined/network_events.py [ Failure ]
diff --git a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/parsing/position-try-options-computed.html b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/parsing/position-try-options-computed.html
new file mode 100644
index 0000000..d6423c16
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/parsing/position-try-options-computed.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Anchor Positioning Test: Computed position-try-options</title>
+<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#position-try-options">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+<script src="/css/support/inheritance-testcommon.js"></script>
+<div id="container">
+  <div id="target"></div>
+</div>
+<script>
+  test_computed_value("position-try-options", "none");
+  test_computed_value("position-try-options", "flip-block");
+  test_computed_value("position-try-options", "flip-inline");
+  test_computed_value("position-try-options", "flip-start");
+  test_computed_value("position-try-options", "flip-block, flip-inline");
+  test_computed_value("position-try-options", "--foo, --bar");
+  test_computed_value("position-try-options", "flip-start flip-inline flip-block", "flip-block flip-inline flip-start");
+
+  assert_not_inherited("position-try-options", "none", "flip-inline");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/parsing/position-try-options-parsing.html b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/parsing/position-try-options-parsing.html
new file mode 100644
index 0000000..dfc9997
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/parsing/position-try-options-parsing.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Anchor Positioning Test: Parsing of position-try-options</title>
+<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#position-try-options">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+<div id="target"></div>
+<script>
+  test_valid_value("position-try-options", "initial");
+  test_valid_value("position-try-options", "inherit");
+  test_valid_value("position-try-options", "unset");
+  test_valid_value("position-try-options", "revert");
+  test_valid_value("position-try-options", "none");
+  test_valid_value("position-try-options", "flip-block");
+  test_valid_value("position-try-options", "flip-start, flip-block");
+  test_valid_value("position-try-options", "flip-start flip-inline, flip-block");
+  test_valid_value("position-try-options", "flip-start, flip-start");
+  test_valid_value("position-try-options", "flip-block, --foo");
+  test_valid_value("position-try-options", "--bar, flip-block flip-start");
+  test_valid_value("position-try-options", "--foo, --bar, --baz");
+
+  test_invalid_value("position-try-options", "none, flip-start");
+  test_invalid_value("position-try-options", "flip-block flip-block");
+  test_invalid_value("position-try-options", "flip-block --foo");
+  test_invalid_value("position-try-options", "--foo --bar");
+  test_invalid_value("position-try-options", "-foo");
+  test_invalid_value("position-try-options", "foo");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-highlight-api/highlight-pseudo-computed-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-highlight-api/highlight-pseudo-computed-expected.txt
index 33d56087..ea64085 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-highlight-api/highlight-pseudo-computed-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-highlight-api/highlight-pseudo-computed-expected.txt
@@ -1,23 +1,23 @@
 This is a testharness.js-based test.
 [FAIL] getComputedStyle() for ::highlight(foo): should not return a style.
-  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 393
+  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 394
 [FAIL] getComputedStyle() for ::highlight(foo)) should not return a style.
-  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 393
+  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 394
 [FAIL] getComputedStyle() for ::highlight(foo)( should not return a style.
-  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 393
+  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 394
 [FAIL] getComputedStyle() for ::highlight should not return a style.
-  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 393
+  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 394
 [FAIL] getComputedStyle() for ::highlight(foo)(foo) should not return a style.
-  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 393
+  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 394
 [FAIL] getComputedStyle() for ::highlight(foo)() should not return a style.
-  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 393
+  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 394
 [FAIL] getComputedStyle() for :::highlight(foo) should not return a style.
-  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 393
+  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 394
 [FAIL] getComputedStyle() for ::highlight(foo). should not return a style.
-  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 393
+  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 394
 [FAIL] getComputedStyle() for ::highlight(foo,bar) should not return a style.
-  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 393
+  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 394
 [FAIL] getComputedStyle() for ::highlight(foo bar) should not return a style.
-  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 393
+  assert_equals: Invalid pseudo identifiers should not return a style. expected 0 but got 394
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/ellipsis-with-image-crash.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/ellipsis-with-image-crash.html
new file mode 100644
index 0000000..42a18d0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/ellipsis-with-image-crash.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://issues.chromium.org/issues/41493875">
+<style>
+  #ellipsis {
+    overflow: clip;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    width: 18ch;
+  }
+  img {
+    width: 10ch;
+  }
+  .ib {
+    display: inline-block;
+    width: 10ch;
+    height: 10px;
+  }
+</style>
+<div id="ellipsis">
+  <span style="border-top:1px solid;">
+    x<br>
+    <img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="><div class="ib"></div>
+  </span>
+</div>
diff --git a/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-listing-expected.txt b/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-listing-expected.txt
index 78bd72c..1cfb9c4 100644
--- a/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-listing-expected.txt
+++ b/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-listing-expected.txt
@@ -295,6 +295,7 @@
 position: static
 position-fallback: none
 position-fallback-bounds: normal
+position-try-options: none
 position-try-order: normal
 r: 0px
 resize: none
diff --git a/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-without-renderer-listing-expected.txt b/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-without-renderer-listing-expected.txt
index b72ca50..7a1a29b 100644
--- a/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-without-renderer-listing-expected.txt
+++ b/third_party/blink/web_tests/fast/css/getComputedStyle/computed-style-without-renderer-listing-expected.txt
@@ -295,6 +295,7 @@
 position: static
 position-fallback: none
 position-fallback-bounds: normal
+position-try-options: none
 position-try-order: normal
 r: 0px
 resize: none
diff --git a/third_party/blink/web_tests/platform/linux-chrome/external/wpt/webdriver/tests/bidi/browsing_context/create/background-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/webdriver/tests/bidi/browsing_context/create/background-expected.txt
index 39ad282e..af16edc 100644
--- a/third_party/blink/web_tests/platform/linux-chrome/external/wpt/webdriver/tests/bidi/browsing_context/create/background-expected.txt
+++ b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/webdriver/tests/bidi/browsing_context/create/background-expected.txt
@@ -1,6 +1,6 @@
 This is a wdspec test.
 [FAIL] test_background[True-tab]
-  AssertionError: assert 'hidden' == 'visible'
+  assert True != True
 [FAIL] test_background[True-window]
   assert True != True
 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/linux-chrome/external/wpt/webdriver/tests/bidi/browsing_context/print/context-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/webdriver/tests/bidi/browsing_context/print/context-expected.txt
index 23f81074..6c89514c 100644
--- a/third_party/blink/web_tests/platform/linux-chrome/external/wpt/webdriver/tests/bidi/browsing_context/print/context-expected.txt
+++ b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/webdriver/tests/bidi/browsing_context/print/context-expected.txt
@@ -1,6 +1,4 @@
 This is a wdspec test.
 [FAIL] test_page_with_iframe
   AssertionError: assert {'type': 'array', 'value': [{'type': 'string', 'value': 'TestIframe'}]} == {'type': 'array', 'value': [{'type': 'string', 'value': 'Iframe'}]}
-[FAIL] test_context_origin[cross_origin]
-  webdriver.bidi.error.UnknownErrorException: unknown error ('Page.printToPDF' wasn't found)
 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/linux-chrome/external/wpt/webdriver/tests/bidi/external/permissions/set_permission/set_permission-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/webdriver/tests/bidi/external/permissions/set_permission/set_permission-expected.txt
index a9bce72..07691a7 100644
--- a/third_party/blink/web_tests/platform/linux-chrome/external/wpt/webdriver/tests/bidi/external/permissions/set_permission/set_permission-expected.txt
+++ b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/webdriver/tests/bidi/external/permissions/set_permission/set_permission-expected.txt
@@ -1,6 +1,12 @@
 This is a wdspec test.
+[FAIL] test_set_permission
+  webdriver.bidi.error.UnknownCommandException: unknown command (Unknown command 'permissions.setPermission'.)
+[FAIL] test_set_permission_insecure_context
+  webdriver.bidi.error.UnknownCommandException: unknown command (Unknown command 'permissions.setPermission'.)
+[FAIL] test_set_permission_new_context
+  webdriver.bidi.error.UnknownCommandException: unknown command (Unknown command 'permissions.setPermission'.)
 [FAIL] test_set_permission_origin_unknown[UNKNOWN]
-  AssertionError: assert 'denied' == 'prompt'
+  webdriver.bidi.error.UnknownCommandException: unknown command (Unknown command 'permissions.setPermission'.)
 [FAIL] test_set_permission_origin_unknown[]
-  AssertionError: assert 'denied' == 'prompt'
+  webdriver.bidi.error.UnknownCommandException: unknown command (Unknown command 'permissions.setPermission'.)
 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/linux-chrome/external/wpt/webdriver/tests/bidi/network/auth_required/unsubscribe-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/webdriver/tests/bidi/network/auth_required/unsubscribe-expected.txt
deleted file mode 100644
index 520a5594..0000000
--- a/third_party/blink/web_tests/platform/linux-chrome/external/wpt/webdriver/tests/bidi/network/auth_required/unsubscribe-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a wdspec test.
-[FAIL] test_unsubscribe
-  webdriver.bidi.error.UnknownErrorException: unknown error (net::ERR_INVALID_AUTH_CREDENTIALS)
-Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/linux-chrome/external/wpt/webdriver/tests/classic/fullscreen_window/fullscreen-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/webdriver/tests/classic/fullscreen_window/fullscreen-expected.txt
index d702263..78dc1d7 100644
--- a/third_party/blink/web_tests/platform/linux-chrome/external/wpt/webdriver/tests/classic/fullscreen_window/fullscreen-expected.txt
+++ b/third_party/blink/web_tests/platform/linux-chrome/external/wpt/webdriver/tests/classic/fullscreen_window/fullscreen-expected.txt
@@ -1,10 +1,12 @@
 This is a wdspec test.
+[FAIL] test_response_payload
+  assert False
 [FAIL] test_fullscreen_from_normal_window
-  assert (1600, 1200) == (800, 600)
+  assert False
 [FAIL] test_fullscreen_from_maximized_window
-  assert (1600, 1200) == (800, 600)
+  assert not True
 [FAIL] test_fullscreen_from_minimized_window
-  assert (1600, 1200) == (800, 600)
+  assert False
 [FAIL] test_fullscreen_twice_is_idempotent
-  assert (1600, 1200) == (800, 600)
+  assert False
 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/svg/css/getComputedStyle-listing-expected.txt b/third_party/blink/web_tests/svg/css/getComputedStyle-listing-expected.txt
index bb18232..74770a27d 100644
--- a/third_party/blink/web_tests/svg/css/getComputedStyle-listing-expected.txt
+++ b/third_party/blink/web_tests/svg/css/getComputedStyle-listing-expected.txt
@@ -295,6 +295,7 @@
 position: static
 position-fallback: none
 position-fallback-bounds: normal
+position-try-options: none
 position-try-order: normal
 r: 0px
 resize: none
diff --git a/third_party/blink/web_tests/webexposed/css-properties-as-js-properties-expected.txt b/third_party/blink/web_tests/webexposed/css-properties-as-js-properties-expected.txt
index fafdef5..ee864ff2 100644
--- a/third_party/blink/web_tests/webexposed/css-properties-as-js-properties-expected.txt
+++ b/third_party/blink/web_tests/webexposed/css-properties-as-js-properties-expected.txt
@@ -357,6 +357,7 @@
 position
 positionFallback
 positionFallbackBounds
+positionTryOptions
 positionTryOrder
 prefix
 quotes
diff --git a/third_party/blink/web_tests/webexposed/css-property-listing-expected.txt b/third_party/blink/web_tests/webexposed/css-property-listing-expected.txt
index 0db264d..020adda 100644
--- a/third_party/blink/web_tests/webexposed/css-property-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/css-property-listing-expected.txt
@@ -312,6 +312,7 @@
     position
     position-fallback
     position-fallback-bounds
+    position-try-options
     position-try-order
     quotes
     r
diff --git a/third_party/perfetto b/third_party/perfetto
index 6821c955..9b78d80d 160000
--- a/third_party/perfetto
+++ b/third_party/perfetto
@@ -1 +1 @@
-Subproject commit 6821c955bdf682556ec4828a174a9cd916d0a02a
+Subproject commit 9b78d80da79be8d58590a2c686d66748161a77ff
diff --git a/third_party/skia b/third_party/skia
index fe4aa8a3..59943f4 160000
--- a/third_party/skia
+++ b/third_party/skia
@@ -1 +1 @@
-Subproject commit fe4aa8a3ea5380f02ba16568299b2d11a2c0a41e
+Subproject commit 59943f4e92b9728e8bac10903e195c8b9a037365
diff --git a/third_party/webrtc b/third_party/webrtc
index fe6178e..cea1c0b 160000
--- a/third_party/webrtc
+++ b/third_party/webrtc
@@ -1 +1 @@
-Subproject commit fe6178ef7d7f4f25ce93253bdda0b7daae0769a6
+Subproject commit cea1c0b9a91be940ec801ab84a7ca3b52e9fc930
diff --git a/third_party/wpt_tools/README.chromium b/third_party/wpt_tools/README.chromium
index 8098a46..80edfaf 100644
--- a/third_party/wpt_tools/README.chromium
+++ b/third_party/wpt_tools/README.chromium
@@ -1,7 +1,7 @@
 Name: web-platform-tests - Test Suites for Web Platform specifications
 Short Name: wpt
 URL: https://github.com/web-platform-tests/wpt/
-Version: 09de1c20d1d31f66bb7174c896f0a63fb41b59b4
+Version: 014486aedc1ca357b9409ca9ef7a0dfd32e30258
 License: LICENSES FOR W3C TEST SUITES (https://www.w3.org/Consortium/Legal/2008/03-bsd-license.html)
 Security Critical: no
 Shipped: no
diff --git a/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/modules/browser.py b/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/modules/browser.py
index 8c5a29a5..2de4fb1 100644
--- a/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/modules/browser.py
+++ b/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/modules/browser.py
@@ -1,4 +1,4 @@
-from typing import Any, Mapping, MutableMapping
+from typing import Any, Mapping, MutableMapping, Optional
 
 from ._module import BidiModule, command
 
@@ -34,7 +34,7 @@
 
     @command
     def remove_user_context(
-        self, user_context: str
+        self, user_context: Optional[str] = None
     ) -> Mapping[str, Any]:
         params: MutableMapping[str, Any] = {}
 
diff --git a/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/modules/network.py b/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/modules/network.py
index 30daa4c..f0a2a5b 100644
--- a/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/modules/network.py
+++ b/third_party/wpt_tools/wpt/tools/webdriver/webdriver/bidi/modules/network.py
@@ -21,52 +21,6 @@
 NetworkBytesValue = Union[NetworkStringValue, NetworkBase64Value]
 
 
-class CookieHeader(Dict[str, Any]):
-    def __init__(self, name: str, value: NetworkBytesValue):
-        dict.__init__(self, name=name, value=value)
-
-
-class Header(Dict[str, Any]):
-    def __init__(self, name: str, value: NetworkBytesValue):
-        dict.__init__(self, name=name, value=value)
-
-
-class SetCookieHeader(Dict[str, Any]):
-    def __init__(
-        self,
-        name: str,
-        value: NetworkBytesValue,
-        domain: Optional[str] = None,
-        expiry: Optional[str] = None,
-        http_only: Optional[bool] = None,
-        max_age: Optional[int] = None,
-        path: Optional[str] = None,
-        same_site: Optional[str] = None,
-        secure: Optional[bool] = None,
-    ):
-        dict.__init__(self, name=name, value=value)
-
-        if domain is not None:
-            self["domain"] = domain
-
-        if expiry is not None:
-            self["expiry"] = expiry
-
-        if http_only is not None:
-            self["httpOnly"] = http_only
-
-        if max_age is not None:
-            self["maxAge"] = max_age
-
-        if path is not None:
-            self["path"] = path
-
-        if same_site is not None:
-            self["sameSite"] = same_site
-
-        if secure is not None:
-            self["secure"] = secure
-
 
 class URLPatternPattern(Dict[str, Any]):
     def __init__(
@@ -142,60 +96,39 @@
     @command
     def continue_request(self,
                          request: str,
-                         body: Optional[NetworkBytesValue] = None,
-                         cookies: Optional[List[CookieHeader]] = None,
-                         headers: Optional[List[Header]] = None,
                          method: Optional[str] = None,
                          url: Optional[str] = None) -> Mapping[str, Any]:
         params: MutableMapping[str, Any] = {
             "request": request,
         }
 
-        if body is not None:
-            params["body"] = body
-
-        if cookies is not None:
-            params["cookies"] = cookies
-
-        if headers is not None:
-            params["headers"] = headers
-
         if method is not None:
             params["method"] = method
 
         if url is not None:
             params["url"] = url
 
+        # TODO: Add support for missing parameters: body, cookies, headers
+
         return params
 
     @command
     def continue_response(
             self,
             request: str,
-            cookies: Optional[List[SetCookieHeader]] = None,
-            credentials: Optional[AuthCredentials] = None,
-            headers: Optional[List[Header]] = None,
             reason_phrase: Optional[str] = None,
             status_code: Optional[int] = None) -> Mapping[str, Any]:
         params: MutableMapping[str, Any] = {
             "request": request,
         }
 
-        if cookies is not None:
-            params["cookies"] = cookies
-
-        if credentials is not None:
-            params["credentials"] = credentials
-
-        if headers is not None:
-            params["headers"] = headers
-
         if reason_phrase is not None:
             params["reasonPhrase"] = reason_phrase
 
         if status_code is not None:
             params["statusCode"] = status_code
 
+        # TODO: Add support for missing parameters: body, credentials, headers
 
         return params
 
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/browsers/chrome.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/browsers/chrome.py
index 05f8146..4669ec4 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/browsers/chrome.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/browsers/chrome.py
@@ -139,18 +139,19 @@
     if kwargs["enable_experimental"]:
         chrome_options["args"].extend(["--enable-experimental-web-platform-features"])
 
+    new_headless_mode = ("--headless=new" in kwargs.get("binary_args", []))
+
+    # Pass the --headless flag to Chrome if WPT's own --headless flag was set
+    # or if we're running print reftests because of crbug.com/753118
+    if ((kwargs["headless"] or test_type == "print-reftest") and
+        "--headless" not in chrome_options["args"] and not new_headless_mode):
+        chrome_options["args"].append("--headless")
+
     # Copy over any other flags that were passed in via `--binary-arg`
     for arg in kwargs.get("binary_args", []):
         if arg not in chrome_options["args"]:
             chrome_options["args"].append(arg)
 
-    # Pass the --headless=new flag to Chrome if WPT's own --headless flag was
-    # set. '--headless' should always mean the new headless mode, as the old
-    # headless mode is not used anyway.
-    if kwargs["headless"] and ("--headless=new" not in chrome_options["args"] and
-                               "--headless" not in chrome_options["args"]):
-        chrome_options["args"].append("--headless=new")
-
     if test_type == "wdspec":
         executor_kwargs["binary_args"] = chrome_options["args"]
 
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/base.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/base.py
index 763b6fcb..7119c0b0 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/base.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/base.py
@@ -90,9 +90,9 @@
         """Convert a JSON result into a (TestResult, [SubtestResult]) tuple"""
         result_url, status, message, stack, subtest_results = result
         assert result_url == test.url, (f"Got results from {result_url}, expected {test.url}")
-        harness_result = test.make_result(self.harness_codes[status], message, extra=extra, stack=stack)
+        harness_result = test.result_cls(self.harness_codes[status], message, extra=extra, stack=stack)
         return (harness_result,
-                [test.make_subtest_result(st_name, self.test_codes[st_status], st_message, st_stack)
+                [test.subtest_result_cls(st_name, self.test_codes[st_status], st_message, st_stack)
                  for st_name, st_status, st_message, st_stack in subtest_results])
 
 
@@ -152,7 +152,7 @@
 def reftest_result_converter(self, test, result):
     extra = result.get("extra", {})
     _ensure_hash_in_reftest_screenshots(extra)
-    return (test.make_result(
+    return (test.result_cls(
         result["status"],
         result["message"],
         extra=extra,
@@ -165,14 +165,14 @@
     if subtest_data is None:
         subtest_data = []
 
-    harness_result = test.make_result(*harness_data)
-    subtest_results = [test.make_subtest_result(*item) for item in subtest_data]
+    harness_result = test.result_cls(*harness_data)
+    subtest_results = [test.subtest_result_cls(*item) for item in subtest_data]
 
     return (harness_result, subtest_results)
 
 
 def crashtest_result_converter(self, test, result):
-    return test.make_result(**result), []
+    return test.result_cls(**result), []
 
 
 class ExecutorException(Exception):
@@ -352,7 +352,7 @@
         if message:
             message += "\n"
         message += exception_string
-        return test.make_result(status, message), []
+        return test.result_cls(status, message), []
 
     def wait(self):
         return self.protocol.base.wait()
@@ -648,7 +648,7 @@
         if success:
             return self.convert_result(test, data)
 
-        return (test.make_result(*data), [])
+        return (test.result_cls(*data), [])
 
     def do_wdspec(self, path, timeout):
         session_config = {"host": self.browser.host,
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorchrome.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorchrome.py
index f564147..7a54eb0 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorchrome.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorchrome.py
@@ -46,7 +46,7 @@
                         status = result["status"]
                         if status == "PASS":
                             status = "OK"
-                        harness_result = test.make_result(status, result["message"])
+                        harness_result = test.result_cls(status, result["message"])
                         # Don't report subtests.
                         return harness_result, []
                     # `crashtest` statuses are a subset of `(print-)reftest`
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorcontentshell.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorcontentshell.py
index 82a6aebc..5c4068c 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorcontentshell.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorcontentshell.py
@@ -213,14 +213,14 @@
     """Converts our TimeoutError and CrashError exceptions into test results.
     """
     if isinstance(exception, TimeoutError):
-        return (test.make_result("EXTERNAL-TIMEOUT", errors), [])
+        return (test.result_cls("EXTERNAL-TIMEOUT", errors), [])
     if isinstance(exception, CrashError):
-        return (test.make_result("CRASH", errors), [])
+        return (test.result_cls("CRASH", errors), [])
     if isinstance(exception, LeakError):
         # TODO: the internal error is to force a restart, but it doesn't correctly
         # describe what the issue is. Need to find a way to return a "FAIL",
         # and restart the content_shell after the test run.
-        return (test.make_result("INTERNAL-ERROR", errors), [])
+        return (test.result_cls("INTERNAL-ERROR", errors), [])
     raise exception
 
 
@@ -312,7 +312,7 @@
                                                                timeout_for_test(self, test))
             errors = self.protocol.content_shell_errors.read_errors()
             if not text:
-                return (test.make_result("ERROR", errors), [])
+                return (test.result_cls("ERROR", errors), [])
 
             result_url, status, message, stack, subtest_results = json.loads(text)
             if result_url != test.url:
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executormarionette.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executormarionette.py
index a5bf61d..21be5e85 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executormarionette.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executormarionette.py
@@ -979,7 +979,7 @@
         if success:
             return self.convert_result(test, data, extra=extra)
 
-        return (test.make_result(extra=extra, *data), [])
+        return (test.result_cls(extra=extra, *data), [])
 
     def do_testharness(self, protocol, url, timeout):
         parent_window = protocol.testharness.close_old_windows(self.last_environment["protocol"])
@@ -1277,7 +1277,7 @@
         if success:
             return self.convert_result(test, data)
 
-        return (test.make_result(extra=extra, *data), [])
+        return (test.result_cls(extra=extra, *data), [])
 
     def do_crashtest(self, protocol, url, timeout):
         if self.protocol.coverage.is_enabled:
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorselenium.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorselenium.py
index cf5ac2a..128e6480 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorselenium.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorselenium.py
@@ -369,7 +369,7 @@
         if success:
             return self.convert_result(test, data)
 
-        return (test.make_result(*data), [])
+        return (test.result_cls(*data), [])
 
     def do_testharness(self, protocol, url, timeout):
         format_map = {"url": strip_server(url)}
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorservo.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorservo.py
index 9c938b6..dd1ea1a 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorservo.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorservo.py
@@ -136,10 +136,10 @@
                     result = self.convert_result(test, self.result_data)
                 else:
                     self.proc.wait()
-                    result = (test.make_result("CRASH", None), [])
+                    result = (test.result_cls("CRASH", None), [])
                     proc_is_running = False
             else:
-                result = (test.make_result("TIMEOUT", None), [])
+                result = (test.result_cls("TIMEOUT", None), [])
 
             if proc_is_running:
                 if self.pause_after_test:
@@ -312,7 +312,7 @@
         if success:
             return self.convert_result(test, data)
 
-        return (test.make_result(*data), [])
+        return (test.result_cls(*data), [])
 
     def do_crashtest(self, protocol, url, timeout):
         self.command = self.build_servo_command(self.test, extra_args=["-x"])
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorservodriver.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorservodriver.py
index 5d7d55f..0a939c5 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorservodriver.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorservodriver.py
@@ -201,7 +201,7 @@
         if success:
             return self.convert_result(test, data)
 
-        return (test.make_result(*data), [])
+        return (test.result_cls(*data), [])
 
     def do_testharness(self, session, url, timeout):
         session.url = url
@@ -257,15 +257,15 @@
             result = self.implementation.run_test(test)
             return self.convert_result(test, result)
         except OSError:
-            return test.make_result("CRASH", None), []
+            return test.result_cls("CRASH", None), []
         except TimeoutError:
-            return test.make_result("TIMEOUT", None), []
+            return test.result_cls("TIMEOUT", None), []
         except Exception as e:
             message = getattr(e, "message", "")
             if message:
                 message += "\n"
             message += traceback.format_exc()
-            return test.make_result("INTERNAL-ERROR", message), []
+            return test.result_cls("INTERNAL-ERROR", message), []
 
     def screenshot(self, test, viewport_size, dpi, page_ranges):
         # https://github.com/web-platform-tests/wpt/issues/7135
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorwebdriver.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorwebdriver.py
index b49b9e2b..05a26bc 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorwebdriver.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorwebdriver.py
@@ -586,7 +586,7 @@
         if success:
             return self.convert_result(test, data)
 
-        return (test.make_result(*data), [])
+        return (test.result_cls(*data), [])
 
     def do_testharness(self, protocol, url, timeout):
         # The previous test may not have closed its old windows (if something
@@ -752,7 +752,7 @@
         if success:
             return self.convert_result(test, data)
 
-        return (test.make_result(*data), [])
+        return (test.result_cls(*data), [])
 
     def do_crashtest(self, protocol, url, timeout):
         protocol.base.load(url)
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/testrunner.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/testrunner.py
index 28d06f8..63f856d1 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/testrunner.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/testrunner.py
@@ -663,9 +663,9 @@
         self.inject_message(
             "test_ended",
             test,
-            (test.make_result("EXTERNAL-TIMEOUT",
-                              "TestRunner hit external timeout "
-                              "(this may indicate a hang)"), []),
+            (test.result_cls("EXTERNAL-TIMEOUT",
+                             "TestRunner hit external timeout "
+                             "(this may indicate a hang)"), []),
         )
 
     def test_ended(self, test, results):
@@ -691,8 +691,8 @@
         for result in test_results:
             if test.disabled(result.name):
                 continue
-            expected = result.expected
-            known_intermittent = result.known_intermittent
+            expected = test.expected(result.name)
+            known_intermittent = test.known_intermittent(result.name)
             is_unexpected = expected != result.status and result.status not in known_intermittent
             is_expected_notrun = (expected == "NOTRUN" or "NOTRUN" in known_intermittent)
 
@@ -728,8 +728,8 @@
                                     stack=result.stack,
                                     subsuite=self.state.subsuite)
 
-        expected = file_result.expected
-        known_intermittent = file_result.known_intermittent
+        expected = test.expected()
+        known_intermittent = test.known_intermittent()
         status = file_result.status
 
         if self.browser.check_crash(test.id) and status != "CRASH":
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wpttest.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wpttest.py
index 2e3fd97..6df1c4cf 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wpttest.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wpttest.py
@@ -4,7 +4,7 @@
 import sys
 from abc import ABC
 from collections import defaultdict
-from typing import Any, ClassVar, Dict, Optional, Set, Type
+from typing import Any, ClassVar, Dict, Optional, Type
 from urllib.parse import urljoin
 
 from .wptmanifest.parser import atoms
@@ -14,9 +14,6 @@
 
 
 class Result(ABC):
-    default_expected: ClassVar[str]
-    statuses: Set[str]
-
     def __init__(self,
                  status,
                  message,
@@ -28,7 +25,7 @@
             raise ValueError("Unrecognised status %s" % status)
         self.status = status
         self.message = message
-        self.expected = expected if expected is not None else self.default_expected
+        self.expected = expected
         self.known_intermittent = known_intermittent if known_intermittent is not None else []
         self.extra = extra if extra is not None else {}
         self.stack = stack
@@ -241,25 +238,6 @@
     def __ne__(self, other):
         return not self.__eq__(other)
 
-    def make_result(self,
-                    status,
-                    message,
-                    expected=None,
-                    extra=None,
-                    stack=None,
-                    known_intermittent=None):
-        if expected is None:
-            expected = self.expected()
-            known_intermittent = self.known_intermittent()
-        return self.result_cls(status, message, expected, extra, stack, known_intermittent)
-
-    def make_subtest_result(self, name, status, message, stack=None, expected=None,
-                            known_intermittent=None):
-        if expected is None:
-            expected = self.expected(name)
-            known_intermittent = self.known_intermittent(name)
-        return self.subtest_result_cls(name, status, message, stack, expected, known_intermittent)
-
     def update_metadata(self, metadata=None):
         if metadata is None:
             metadata = {}
diff --git a/tools/clang/iterator_checker/CMakeLists.txt b/tools/clang/iterator_checker/CMakeLists.txt
new file mode 100644
index 0000000..1287ce5
--- /dev/null
+++ b/tools/clang/iterator_checker/CMakeLists.txt
@@ -0,0 +1,23 @@
+# This plugin is the only one depending on the clangAnalysisFlowSensitive
+# library, so it is not built inside /tools/clang/plugin/, but uses its own
+# directory. This is similar to the blink_gc_plugin.
+
+# Clang doesn't support loadable modules on Windows. Unfortunately, building
+# the plugin as a static library and linking clang against it doesn't work.
+# Since clang doesn't reference any symbols in our static library, the linker
+# strips it out completely.
+#
+# Instead we add our sources directly into clang:
+# - Adding sources into target created from different directory is allowed by
+#   default since CMake 3.1.
+# - Adding link libraries into target created from different directory is
+#   allowed by default since CMake 3.13.
+cmake_minimum_required(VERSION 3.13)
+
+target_sources(clang PRIVATE IteratorChecker.cpp)
+target_link_libraries(clang PRIVATE clangAnalysisFlowSensitive)
+
+cr_add_test(iterator_checker_test
+  python3 tests/test.py
+  ${CMAKE_BINARY_DIR}/bin/clang
+)
diff --git a/tools/clang/iterator_checker/DIR_METADATA b/tools/clang/iterator_checker/DIR_METADATA
new file mode 100644
index 0000000..0f2e8d8
--- /dev/null
+++ b/tools/clang/iterator_checker/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "Tools"
+}
diff --git a/tools/clang/iterator_checker/IteratorChecker.cpp b/tools/clang/iterator_checker/IteratorChecker.cpp
new file mode 100644
index 0000000..421a316
--- /dev/null
+++ b/tools/clang/iterator_checker/IteratorChecker.cpp
@@ -0,0 +1,1124 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include <cstdint>
+#include <memory>
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/OperationKinds.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
+#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
+#include "clang/Analysis/FlowSensitive/NoopLattice.h"
+#include "clang/Analysis/FlowSensitive/Value.h"
+#include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h"
+#include "clang/Frontend/FrontendPluginRegistry.h"
+#include "clang/Tooling/Transformer/Stencil.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+
+// This clang plugin check for iterators used after they have been
+// invalidated.
+//
+// Pre-existing bugs found: https://crbug.com/1421293
+
+namespace {
+
+const char kInvalidIteratorUsage[] =
+    "[iterator-checker] Potentially invalid iterator used.";
+
+const char kInvalidIteratorComparison[] =
+    "[iterator-checker] Potentially invalid iterator comparison.";
+
+// To understand C++ code, we need a way to encode what is an iterator and what
+// are the functions that might invalidate them.
+//
+// The Clang frontend supports several source-level annotations in the form of
+// GCC-style attributes and pragmas that can help make using the Clang Static
+// Analyzer useful. We aim to provide support for those annotations. For now, we
+// hard code those for "known" interesting classes.
+// TODO(https://crbug.com/1455371) Support source-level annotations.
+enum Annotation : uint8_t {
+  kNone = 0,
+
+  // Annotate function returning an iterator.
+  kReturnIterator = 1 << 0,
+
+  // Annotate function returning an "end" iterator.
+  // The distinction with `kReturnIterator` is important because we need to
+  // special case its iterator creation.
+  kReturnEndIterator = 1 << 1,
+
+  // Annotate function returning a pair of iterators.
+  // TODO(https://crbug.com/1455371) Not yet implemented.
+  kReturnIteratorPair = 1 << 2,
+
+  // Annotate function invalidating the iterator in its arguments.
+  kInvalidateArgs = 1 << 3,
+
+  // Annotate function invalidating every iterators.
+  kInvalidateAll = 1 << 4,
+};
+
+static llvm::DenseMap<llvm::StringRef, uint8_t> g_functions_annotations = {
+    {"std::begin", Annotation::kReturnIterator},
+    {"std::cbegin", Annotation::kReturnIterator},
+    {"std::end", Annotation::kReturnEndIterator},
+    {"std::cend", Annotation::kReturnEndIterator},
+    {"std::next", Annotation::kReturnIterator},
+    {"std::prev", Annotation::kReturnIterator},
+    {"std::find", Annotation::kReturnIterator},
+    // TODO(https://crbug.com/1455371) Add additional functions.
+};
+
+static llvm::DenseMap<llvm::StringRef, llvm::DenseMap<llvm::StringRef, uint8_t>>
+    g_member_function_annotations = {
+        {
+            "std::vector",
+            {
+                {"append_range", Annotation::kInvalidateAll},
+                {"assign", Annotation::kInvalidateAll},
+                {"assign_range", Annotation::kInvalidateAll},
+                {"back", Annotation::kNone},
+                {"begin", Annotation::kReturnIterator},
+                {"capacity", Annotation::kNone},
+                {"cbegin", Annotation::kReturnIterator},
+                {"cend", Annotation::kReturnEndIterator},
+                {"clear", Annotation::kInvalidateAll},
+                {"crbegin", Annotation::kReturnIterator},
+                {"crend", Annotation::kReturnIterator},
+                {"data", Annotation::kNone},
+                {"emplace",
+                 Annotation::kInvalidateAll | Annotation::kInvalidateAll},
+                {"emplace_back", Annotation::kInvalidateAll},
+                {"empty", Annotation::kNone},
+                {"end", Annotation::kReturnEndIterator},
+                {"erase",
+                 Annotation::kReturnIterator | Annotation::kInvalidateAll},
+                {"front", Annotation::kNone},
+                {"insert",
+                 Annotation::kInvalidateAll | Annotation::kReturnIterator},
+                {"insert_range",
+                 Annotation::kInvalidateAll | Annotation::kReturnIterator},
+                {"max_size", Annotation::kNone},
+                {"pop_back", Annotation::kInvalidateAll},
+                {"push_back", Annotation::kInvalidateAll},
+                {"rbegin", Annotation::kReturnIterator},
+                {"rend", Annotation::kReturnIterator},
+                {"reserve", Annotation::kInvalidateAll},
+                {"resize", Annotation::kInvalidateAll},
+                {"shrink_to_fit", Annotation::kInvalidateAll},
+                {"size", Annotation::kNone},
+                {"swap", Annotation::kNone},
+            },
+        },
+        {
+            "std::unordered_set",
+            {
+                {"begin", Annotation::kReturnIterator},
+                {"cbegin", Annotation::kReturnIterator},
+                {"end", Annotation::kReturnEndIterator},
+                {"cend", Annotation::kReturnEndIterator},
+                {"clear", Annotation::kInvalidateAll},
+                {"insert",
+                 Annotation::kInvalidateAll | Annotation::kReturnIteratorPair},
+                {"emplace",
+                 Annotation::kInvalidateAll | Annotation::kReturnIteratorPair},
+                {"emplace_hint",
+                 Annotation::kInvalidateAll | Annotation::kReturnIterator},
+                {"erase",
+                 Annotation::kInvalidateArgs | Annotation::kReturnIterator},
+                {"extract", Annotation::kInvalidateArgs},
+                {"find", Annotation::kReturnIterator},
+                // TODO(https://crbug.com/1455371) Add additional functions.
+            },
+        },
+        {
+            "WTF::Vector",
+            {
+                {"begin", Annotation::kReturnIterator},
+                {"rbegin", Annotation::kReturnIterator},
+                {"end", Annotation::kReturnEndIterator},
+                {"rend", Annotation::kReturnEndIterator},
+                {"clear", Annotation::kInvalidateAll},
+                {"shrink_to_fit", Annotation::kInvalidateAll},
+                {"push_back", Annotation::kInvalidateAll},
+                {"emplace_back", Annotation::kInvalidateAll},
+                {"insert", Annotation::kInvalidateAll},
+                {"InsertAt", Annotation::kInvalidateAll},
+                {"InsertVector", Annotation::kInvalidateAll},
+                {"push_front", Annotation::kInvalidateAll},
+                {"PrependVector", Annotation::kInvalidateAll},
+                {"EraseAt", Annotation::kInvalidateAll},
+                {"erase",
+                 Annotation::kInvalidateAll | Annotation::kReturnIterator},
+                // `pop_back` invalidates only the iterator pointed to the last
+                // element, but we have no way to track it.
+                {"pop_back", Annotation::kNone},
+                // TODO(https://crbug.com/1455371) Add additional functions.
+            },
+        },
+        {
+            "std::deque",
+            {
+                {"begin", Annotation::kReturnIterator},
+                {"cbegin", Annotation::kReturnIterator},
+                {"rbegin", Annotation::kReturnIterator},
+                {"end", Annotation::kReturnEndIterator},
+                {"cend", Annotation::kReturnEndIterator},
+                {"rend", Annotation::kReturnEndIterator},
+                {"clear", Annotation::kInvalidateAll},
+                {"shrink_to_fit", Annotation::kInvalidateAll},
+                {"insert",
+                 Annotation::kInvalidateAll | Annotation::kReturnIterator},
+                {"emplace",
+                 Annotation::kInvalidateAll | Annotation::kReturnIterator},
+                {"erase",
+                 Annotation::kInvalidateAll | Annotation::kReturnIterator},
+                {"push_back", Annotation::kInvalidateAll},
+                {"emplace_back", Annotation::kInvalidateAll},
+                {"push_front", Annotation::kInvalidateAll},
+                {"emplace_front", Annotation::kInvalidateAll},
+                // TODO(https://crbug.com/1455371) Add additional functions.
+            },
+        },
+};
+
+llvm::raw_ostream& DebugStream() {
+  // Updates to llvm::outs() to get debugs logs.
+  return llvm::nulls();
+}
+
+llvm::raw_ostream& InfoStream() {
+  // Updates to llvm::outs() to get info logs.
+  return llvm::nulls();
+}
+
+// In DataflowAnalysis, we associate to every C++ prvalue:
+//
+// - A RecordStorageLocation:
+//   This will be used to reference the actual location of the values being used
+//   during the analysis. For example, in `auto it = std::begin(cont)`, it will
+//   be assigned a RecordStorageLocation.
+//
+// - Some fields:
+//   Those are just one-to-one mapping with the actual record type being
+//   modeled.
+//
+// - Some synthetic fields:
+//   Those are the essence of how dataflow analysis work. Those fields are not
+//   actually mapped to existing fields in the record type, but are ones that we
+//   use in order to perform the analysis. For instance, in this analysis, those
+//   fields are:
+//   - `is_valid` - This field is used to store the iterator validity.
+//   - `is_end` - Stores whether the current iterator points to the end
+//   iterator.
+//
+// We also keep track of the `iterator` -> `container` mapping in order to
+// invalidate iterators when necessary.
+
+clang::dataflow::BoolValue* GetSyntheticFieldWithname(
+    llvm::StringRef name,
+    const clang::dataflow::Environment& env,
+    const clang::dataflow::Value& iterator) {
+  auto* record = clang::cast_or_null<clang::dataflow::RecordValue>(
+      const_cast<clang::dataflow::Value*>(&iterator));
+  auto& loc = record->getLoc();
+  auto& field_loc = loc.getSyntheticField(name);
+  return clang::cast_or_null<clang::dataflow::BoolValue>(
+      env.getValue(field_loc));
+}
+
+clang::dataflow::BoolValue* GetIsValid(const clang::dataflow::Environment& env,
+                                       const clang::dataflow::Value& iterator) {
+  return GetSyntheticFieldWithname("is_valid", env, iterator);
+}
+
+clang::dataflow::BoolValue* GetIsEnd(const clang::dataflow::Environment& env,
+                                     const clang::dataflow::Value& iterator) {
+  return GetSyntheticFieldWithname("is_end", env, iterator);
+}
+
+void SetSyntheticFieldWithName(llvm::StringRef name,
+                               clang::dataflow::Environment& env,
+                               const clang::dataflow::Value& val,
+                               clang::dataflow::BoolValue& res) {
+  auto* record = clang::cast_or_null<clang::dataflow::RecordValue>(
+      const_cast<clang::dataflow::Value*>(&val));
+  auto& loc = record->getLoc();
+  auto& field_loc = loc.getSyntheticField(name);
+  env.setValue(field_loc, res);
+}
+
+void SetIsValid(clang::dataflow::Environment& env,
+                const clang::dataflow::Value& val,
+                clang::dataflow::BoolValue& res) {
+  SetSyntheticFieldWithName("is_valid", env, val, res);
+}
+
+void SetIsEnd(clang::dataflow::Environment& env,
+              const clang::dataflow::Value& val,
+              clang::dataflow::BoolValue& res) {
+  SetSyntheticFieldWithName("is_end", env, val, res);
+}
+
+const clang::dataflow::Formula& ForceBoolValue(
+    clang::dataflow::Environment& env,
+    const clang::Expr& expr) {
+  auto* value = env.get<clang::dataflow::BoolValue>(expr);
+  if (value != nullptr) {
+    return value->formula();
+  }
+
+  value = &env.makeAtomicBoolValue();
+  env.setValue(expr, *value);
+  return value->formula();
+}
+
+// We don't use DataflowAnalysis lattices. Hence why the NoopLattice. Instead,
+// we use the WatchedLiteralsSolver and populate different `Environment` with
+// `Values`. The DataFlowAnalysis will iterate up until it can't make new
+// deductions:
+// - The `transfer` function updates an environment after executing one more
+//   instructions.
+// - The `merge` function merge together the environments from two code
+//   diverging code paths. For instance the `if` and `for` loop.
+class InvalidIteratorAnalysis
+    : public clang::dataflow::DataflowAnalysis<InvalidIteratorAnalysis,
+                                               clang::dataflow::NoopLattice> {
+ public:
+  InvalidIteratorAnalysis(const clang::FunctionDecl* func,
+                          clang::DiagnosticsEngine& diagnostic)
+      : DataflowAnalysis(func->getASTContext()), diagnostic_(diagnostic) {}
+
+  // Used by DataflowAnalysis template.
+  clang::dataflow::NoopLattice initialElement() const {
+    return clang::dataflow::NoopLattice();
+  }
+
+  // Used by DataflowAnalysis template.
+  void transfer(const clang::CFGElement& elt,
+                clang::dataflow::NoopLattice& state,
+                clang::dataflow::Environment& env) {
+    if (auto cfg_stmt = elt.getAs<clang::CFGStmt>()) {
+      Transfer(*cfg_stmt->getStmt(), env);
+    }
+  }
+
+  // Used by DataflowAnalysis template.
+  bool merge(clang::QualType type,
+             const clang::dataflow::Value& val1,
+             const clang::dataflow::Environment& env1,
+             const clang::dataflow::Value& val2,
+             const clang::dataflow::Environment& env2,
+             clang::dataflow::Value& merged_val,
+             clang::dataflow::Environment& merged_env) final {
+    if (!IsIterator(type)) {
+      return true;
+    }
+
+    auto* container1 = GetContainerValue(env1, val1);
+    auto* container2 = GetContainerValue(env2, val2);
+    DebugStream() << "HERE: " << DebugString(env1, val1);
+    DebugStream() << "HERE: " << DebugString(env2, val2);
+    if (container1 != container2) {
+      // See tests/iterator-with-multiple-container.cpp
+      // TODO(https://crbug.com/1455371) Ban iterator associated with multiple
+      // containers.
+      UnsetContainerValue(merged_env, merged_val);
+      return true;
+    }
+
+    SetContainerValue(merged_env, merged_val, *container1);
+    return true;
+  }
+
+  llvm::StringMap<clang::QualType> GetSyntheticFields(clang::QualType Type) {
+    return llvm::StringMap<clang::QualType>{
+        {"is_valid", getASTContext().BoolTy},
+        {"is_end", getASTContext().BoolTy},
+    };
+  }
+
+ private:
+  // Stmt: https://clang.llvm.org/doxygen/classclang_1_1Stmt.html
+  void Transfer(const clang::Stmt& stmt, clang::dataflow::Environment& env) {
+    if (auto* decl_stmt = clang::dyn_cast<clang::DeclStmt>(&stmt)) {
+      Transfer(*decl_stmt, env);
+      return;
+    }
+
+    if (auto* value_stmt = clang::dyn_cast<clang::ValueStmt>(&stmt)) {
+      Transfer(*value_stmt, env);
+      return;
+    }
+  }
+
+  // DeclStmt: https://clang.llvm.org/doxygen/classclang_1_1DeclStmt.html
+  void Transfer(const clang::DeclStmt& declaration_statement,
+                clang::dataflow::Environment& env) {
+    for (auto* decl : declaration_statement.decls()) {
+      if (auto* var_decl = clang::dyn_cast<clang::VarDecl>(decl)) {
+        Transfer(*var_decl, env);
+      }
+    }
+  }
+
+  // VarDecl: https://clang.llvm.org/doxygen/classclang_1_1VarDecl.html
+  void Transfer(const clang::VarDecl& var_decl,
+                clang::dataflow::Environment& env) {}
+
+  // ValueStmt: https://clang.llvm.org/doxygen/classclang_1_1ValueStmt.html
+  void Transfer(const clang::ValueStmt& value_stmt,
+                clang::dataflow::Environment& env) {
+    if (auto* expr = clang::dyn_cast<clang::Expr>(&value_stmt)) {
+      Transfer(*expr, env);
+    }
+  }
+
+  // Expr: https://clang.llvm.org/doxygen/classclang_1_1Expr.html
+  void Transfer(const clang::Expr& expr, clang::dataflow::Environment& env) {
+    if (auto* call_expr = clang::dyn_cast<clang::CallExpr>(&expr)) {
+      Transfer(*call_expr, env);
+      return;
+    }
+
+    if (auto* ctor = clang::dyn_cast<clang::CXXConstructExpr>(&expr)) {
+      Transfer(*ctor, env);
+      return;
+    }
+
+    if (auto* cast_expr = clang::dyn_cast<clang::CastExpr>(&expr)) {
+      Transfer(*cast_expr, env);
+      return;
+    }
+
+    //  TODO(https://crbug.com/1455371): Add support for operator[]
+    //  (ArraySubscriptExpr)
+  }
+
+  void Transfer(const clang::CXXConstructExpr& expr,
+                clang::dataflow::Environment& env) {
+    if (!IsIterator(expr.getType().getCanonicalType())) {
+      return;
+    }
+
+    const clang::CXXConstructorDecl* ctor = expr.getConstructor();
+    assert(ctor != nullptr);
+
+    if (ctor->isCopyOrMoveConstructor()) {
+      auto* it = UnwrapAsIterator(expr.getArg(0), env);
+      assert(it);
+
+      env.setValue(expr, *it);
+    }
+  }
+
+  // CallExpr: https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html
+  void Transfer(const clang::CallExpr& callexpr,
+                clang::dataflow::Environment& env) {
+    TransferCallExprCommon(callexpr, env);
+
+    if (auto* expr = clang::dyn_cast<clang::CXXMemberCallExpr>(&callexpr)) {
+      Transfer(*expr, env);
+      return;
+    }
+
+    if (auto* expr = clang::dyn_cast<clang::CXXOperatorCallExpr>(&callexpr)) {
+      Transfer(*expr, env);
+      return;
+    }
+  }
+
+  void TransferCallExprCommon(const clang::CallExpr& expr,
+                              clang::dataflow::Environment& env) {
+    auto* callee = expr.getDirectCallee();
+    if (!callee) {
+      return;
+    }
+
+    // If the function is known to return an iterator and we can associate it
+    // with a known container, then we deduce the resulting expression is itself
+    // an iterator:
+    std::string callee_name = callee->getQualifiedNameAsString();
+    auto it = g_functions_annotations.find(callee_name);
+    if (it == g_functions_annotations.end()) {
+      return;
+    }
+
+    if (!(it->second & Annotation::kReturnIterator) &&
+        !(it->second & Annotation::kReturnEndIterator)) {
+      return;
+    }
+
+    bool is_end = (it->second & Annotation::kReturnEndIterator) != 0;
+    clang::dataflow::Value* iterator = UnwrapAsIterator(expr.getArg(0), env);
+    clang::dataflow::Value* container = iterator
+                                            ? GetContainerValue(env, *iterator)
+                                            : env.getValue(*expr.getArg(0));
+
+    if (!iterator && !container) {
+      return;
+    }
+
+    TransferCallReturningIterator(
+        &expr, *container,
+        is_end ? env.getBoolLiteralValue(false) : env.makeAtomicBoolValue(),
+        is_end ? env.getBoolLiteralValue(true) : env.makeAtomicBoolValue(),
+        env);
+  }
+
+  void TransferCallReturningIterator(const clang::CallExpr* expr,
+                                     clang::dataflow::Value& container,
+                                     clang::dataflow::BoolValue& is_valid,
+                                     clang::dataflow::BoolValue& is_end,
+                                     clang::dataflow::Environment& env) {
+    clang::dataflow::RecordStorageLocation* loc = nullptr;
+    if (expr->isPRValue()) {
+      loc = &env.getResultObjectLocation(*expr);
+    } else {
+      loc = env.get<clang::dataflow::RecordStorageLocation>(*expr);
+      if (loc == nullptr) {
+        loc = &clang::cast<clang::dataflow::RecordStorageLocation>(
+            env.createStorageLocation(*expr));
+        env.setStorageLocation(*expr, *loc);
+      }
+    }
+    assert(loc);
+    auto& value = CreateIteratorValue(loc->getType(), env, *loc, container,
+                                      is_valid, is_end);
+    if (expr->isPRValue()) {
+      env.setValue(*expr, value);
+    }
+  }
+
+  // CXXMemberCallExpr:
+  // https://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html
+  void Transfer(const clang::CXXMemberCallExpr& callexpr,
+                clang::dataflow::Environment& env) {
+    auto* callee = callexpr.getDirectCallee();
+    if (!callee) {
+      return;
+    }
+
+    const std::string callee_type = clang::cast<clang::CXXMethodDecl>(callee)
+                                        ->getParent()
+                                        ->getQualifiedNameAsString();
+    auto container_annotations =
+        g_member_function_annotations.find(callee_type);
+    if (container_annotations == g_member_function_annotations.end()) {
+      return;
+    }
+
+    const std::string callee_name = callee->getNameAsString();
+    auto method_annotation = container_annotations->second.find(callee_name);
+    if (method_annotation == container_annotations->second.end()) {
+      return;
+    }
+
+    const uint8_t annotation = method_annotation->second;
+    assert(!(annotation & Annotation::kReturnIterator) ||
+           !(annotation & Annotation::kReturnIteratorPair));
+
+    auto* container = env.getValue(*callexpr.getImplicitObjectArgument());
+    if (!container) {
+      return;
+    }
+
+    if (annotation & Annotation::kReturnIterator ||
+        annotation & Annotation::kReturnEndIterator) {
+      TransferCallReturningIterator(&callexpr, *container,
+                                    annotation & Annotation::kReturnEndIterator
+                                        ? env.getBoolLiteralValue(false)
+                                        : env.makeAtomicBoolValue(),
+                                    annotation & Annotation::kReturnEndIterator
+                                        ? env.getBoolLiteralValue(true)
+                                        : env.makeAtomicBoolValue(),
+                                    env);
+    }
+
+    if (annotation & Annotation::kReturnIteratorPair) {
+      //  TODO(https://crbug.com/1455371): Iterator pair are not yet supported.
+    }
+
+    if (annotation & Annotation::kInvalidateArgs) {
+      bool found_iterator = false;
+
+      // TODO(https://crbug.com/1455371): Invalid every arguments.
+      for (unsigned i = 0; i < callexpr.getNumArgs(); i++) {
+        if (auto* iterator = UnwrapAsIterator(callexpr.getArg(i), env)) {
+          InfoStream() << "INVALIDATING ONE: " << DebugString(env, *iterator)
+                       << '\n';
+          InvalidateIterator(env, *iterator);
+          found_iterator = true;
+        }
+      }
+
+      if (!found_iterator) {
+        // If we cannot get the iterator from the argument, then let's
+        // invalidate everything instead:
+        InfoStream() << "INVALIDATING MANY: Container: " << container << '\n';
+        InvalidateContainer(env, *container);
+        return;
+      }
+    }
+
+    if (annotation & Annotation::kInvalidateAll) {
+      InfoStream() << "INVALIDATING MANY: Container: " << container << '\n';
+      InvalidateContainer(env, *container);
+      return;
+    }
+  }
+
+  // CXXOperatorCallExpr:
+  // https://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html
+  void Transfer(const clang::CXXOperatorCallExpr& expr,
+                clang::dataflow::Environment& env) {
+    // Those are operations of the form:
+    //   - `*it`
+    //   - `it->`
+    if (expr.getOperator() == clang::OverloadedOperatorKind::OO_Star ||
+        expr.getOperator() == clang::OverloadedOperatorKind::OO_Arrow) {
+      assert(expr.getNumArgs() >= 1);
+      TransferExpressionAccessForDeref(expr.getArg(0), env);
+      return;
+    }
+
+    // Those are operations of the form:
+    //   - `it += [integer]`
+    //   - `it -= [integer]`
+    if (expr.getOperator() == clang::OverloadedOperatorKind::OO_PlusEqual ||
+        expr.getOperator() == clang::OverloadedOperatorKind::OO_MinusEqual) {
+      assert(expr.getNumArgs() == 2);
+
+      // Once all the features are developed, this should really be a
+      // TransferExpressionAccessForDeref here, but the current error rate
+      // would be too high as for now.
+      TransferExpressionAccessForCheck(expr.getArg(0), env);
+
+      // The result of this operation is another iterator.
+      if (auto* iterator = UnwrapAsIterator(expr.getArg(0), env)) {
+        CloneIterator(&expr, *iterator, env);
+      }
+      return;
+    }
+
+    // Those are operations of the form:
+    //   - `it + [integer]`
+    //   - `it - [integer]`
+    //   - `[integer] + it`
+    //   - `[integer] - it`
+    if (expr.getOperator() == clang::OverloadedOperatorKind::OO_Plus ||
+        expr.getOperator() == clang::OverloadedOperatorKind::OO_Minus) {
+      // This can happen for classes representing numerical values for example.
+      // e.g. const Decimal d = 3; -d;
+      if (expr.getNumArgs() < 2) {
+        return;
+      }
+
+      // Once all the features are developed, this should really be a
+      // TransferExpressionAccessForDeref here, but the current error rate
+      // would be too high as for now.
+      TransferExpressionAccessForCheck(expr.getArg(0), env);
+      TransferExpressionAccessForCheck(expr.getArg(1), env);
+
+      // Adding/Substracing one iterator with an integer results in a new
+      // iterator expression of the same type.
+      auto deduce_return_value = [&](const clang::Expr* a,
+                                     const clang::Expr* b) {
+        clang::dataflow::Value* iterator = UnwrapAsIterator(a, env);
+        if (!iterator || !b->getType()->isIntegerType()) {
+          return;
+        }
+
+        CloneIterator(&expr, *iterator, env);
+      };
+
+      deduce_return_value(expr.getArg(0), expr.getArg(1));
+      deduce_return_value(expr.getArg(1), expr.getArg(0));
+      return;
+    }
+
+    // Those are operations of the form:
+    //   - `it = [expr]`
+    if (expr.getOperator() == clang::OverloadedOperatorKind::OO_Equal) {
+      // Just record the potentially new iterator.
+      auto* lhs = UnwrapAsIterator(&expr, env);
+      auto* rhs = UnwrapAsIterator(expr.getArg(1), env);
+
+      if (lhs) {
+        assert(rhs);
+        SetContainerValue(env, *lhs, *GetContainerValue(env, *rhs));
+      }
+      return;
+    }
+
+    // Those are operations of the form:
+    //   - `it != [expr]`
+    //   - `it == [expr]`
+    if (expr.getOperator() == clang::OverloadedOperatorKind::OO_EqualEqual ||
+        expr.getOperator() == clang::OverloadedOperatorKind::OO_ExclaimEqual) {
+      assert(expr.getNumArgs() >= 2);
+
+      TransferExpressionAccessForCheck(expr.getArg(0), env);
+      TransferExpressionAccessForCheck(expr.getArg(1), env);
+      clang::dataflow::Value* lhs_it = UnwrapAsIterator(expr.getArg(0), env);
+      clang::dataflow::Value* rhs_it = UnwrapAsIterator(expr.getArg(1), env);
+      if (!lhs_it || !rhs_it) {
+        return;
+      }
+      DebugStream() << DebugString(env, *lhs_it) << '\n';
+      DebugStream() << DebugString(env, *rhs_it) << '\n';
+      if (GetContainerValue(env, *lhs_it) != GetContainerValue(env, *rhs_it)) {
+        diagnostic_.Report(
+            expr.getSourceRange().getBegin(),
+            diagnostic_.getCustomDiagID(clang::DiagnosticsEngine::Level::Error,
+                                        kInvalidIteratorComparison));
+      }
+      const auto& formula = ForceBoolValue(env, expr);
+      auto& arena = env.arena();
+      if (expr.getOperator() == clang::OverloadedOperatorKind::OO_EqualEqual) {
+        TransferIteratorsEquality(env, formula, lhs_it, rhs_it);
+        TransferIteratorsInequality(env, arena.makeNot(formula), lhs_it,
+                                    rhs_it);
+      } else {
+        TransferIteratorsInequality(env, formula, lhs_it, rhs_it);
+        TransferIteratorsEquality(env, arena.makeNot(formula), lhs_it, rhs_it);
+      }
+      return;
+    }
+
+    // Those are operations of the form:
+    //   - `it--`
+    //   - `it++`
+    if (expr.getOperator() == clang::OverloadedOperatorKind::OO_PlusPlus ||
+        expr.getOperator() == clang::OverloadedOperatorKind::OO_MinusMinus) {
+      assert(expr.getNumArgs());
+      TransferExpressionAccessForDeref(expr.getArg(0), env);
+
+      // The result of this operation is another iterator.
+      if (auto* iterator = UnwrapAsIterator(expr.getArg(0), env)) {
+        CloneIterator(&expr, *iterator, env);
+      }
+
+      return;
+    }
+    // TODO(https://crbug.com/1455371) Handle other kinds of operators.
+  }
+
+  // CastExpr: https://clang.llvm.org/doxygen/classclang_1_1CastExpr.html
+  void Transfer(const clang::CastExpr& value_stmt,
+                clang::dataflow::Environment& env) {
+    if (auto* expr = clang::dyn_cast<clang::ImplicitCastExpr>(&value_stmt)) {
+      Transfer(*expr, env);
+    }
+  }
+
+  // ImplicitCastExpr:
+  // https://clang.llvm.org/doxygen/classclang_1_1ImplicitCastExpr.html
+  void Transfer(const clang::ImplicitCastExpr& expr,
+                clang::dataflow::Environment& env) {
+    if (expr.getCastKind() == clang::CastKind::CK_LValueToRValue) {
+      TransferExpressionAccessForDeref(expr.getSubExpr(), env);
+    }
+  }
+
+  void TransferIteratorsEquality(clang::dataflow::Environment& env,
+                                 const clang::dataflow::Formula& formula,
+                                 clang::dataflow::Value* lhs,
+                                 clang::dataflow::Value* rhs) {
+    auto& arena = env.arena();
+    // If we know that lhs and rhs are equal, we can imply that:
+    // 1. lhs->is_valid == rhs->is_valid
+    // 2. lhs->is_end == rhs->is_end
+    // Indeed, in the following scenario:
+    //   if (it == std::end(vec)) {}
+    // entering the `if` block means that it is the end iterator as well.
+    env.assume(arena.makeImplies(
+        formula, arena.makeEquals(GetIsValid(env, *lhs)->formula(),
+                                  GetIsValid(env, *rhs)->formula())));
+    env.assume(arena.makeImplies(
+        formula, arena.makeEquals(GetIsEnd(env, *lhs)->formula(),
+                                  GetIsEnd(env, *rhs)->formula())));
+  }
+
+  void TransferIteratorsInequality(clang::dataflow::Environment& env,
+                                   const clang::dataflow::Formula& formula,
+                                   clang::dataflow::Value* lhs,
+                                   clang::dataflow::Value* rhs) {
+    auto& arena = env.arena();
+    // This is a bit trickier, because inequality doesn't really give us
+    // generic information on the validities of the iterators, except:
+    // 1. lhs->is_end => rhs->is_valid
+    // 2. rhs->is_end => lhs->is_valid
+    env.assume(arena.makeImplies(
+        arena.makeAnd(formula, GetIsEnd(env, *lhs)->formula()),
+        GetIsValid(env, *rhs)->formula()));
+    env.assume(arena.makeImplies(
+        arena.makeAnd(formula, GetIsEnd(env, *rhs)->formula()),
+        GetIsValid(env, *lhs)->formula()));
+  }
+
+  // This validates that the iterator at `expr` is allowed to be "checked"
+  // against. If not, we issue an error.
+  void TransferExpressionAccessForCheck(const clang::Expr* expr,
+                                        clang::dataflow::Environment& env) {
+    clang::dataflow::Value* iterator = UnwrapAsIterator(expr, env);
+    if (!iterator) {
+      return;
+    }
+
+    // If the iterator was never invalidated in any of the parent environments,
+    // then we allow it to be checked against another iterator, since it means
+    // the iterator is still potentially valid.
+    if (env.allows(GetIsValid(env, *iterator)->formula())) {
+      return;
+    }
+
+    // We always allow the end iterator to be checked, otherwise we wouldn't be
+    // able to make iterators valid.
+    if (env.proves(GetIsEnd(env, *iterator)->formula())) {
+      return;
+    }
+
+    TransferExpressionAccessForDeref(expr, env);
+  }
+
+  // This validates that the iterator at `expr` is allowed to be dereferenced.
+  // In other words, the iterator **must** be valid or we issue an error.
+  void TransferExpressionAccessForDeref(const clang::Expr* expr,
+                                        clang::dataflow::Environment& env) {
+    clang::dataflow::Value* iterator = UnwrapAsIterator(expr, env);
+    if (!iterator) {
+      return;
+    }
+
+    bool is_valid = env.proves(GetIsValid(env, *iterator)->formula());
+
+    DebugStream() << "[ACCESS] " << DebugString(env, *iterator) << '\n';
+
+    if (is_valid) {
+      return;
+    }
+
+    diagnostic_.Report(
+        expr->getSourceRange().getBegin(),
+        diagnostic_.getCustomDiagID(clang::DiagnosticsEngine::Level::Error,
+                                    kInvalidIteratorUsage));
+  }
+
+  // This invalidates all the iterators previously created by this container in
+  // the current environment.
+  void InvalidateContainer(clang::dataflow::Environment& env,
+                           clang::dataflow::Value& container) {
+    for (auto& p : iterator_to_container_) {
+      if (p.second != &container) {
+        continue;
+      }
+      auto* value = env.getValue(*p.first);
+      if (!value) {
+        continue;
+      }
+      DebugStream() << DebugString(env, *value) << '\n';
+
+      SetIsValid(env, *value, env.getBoolLiteralValue(false));
+    }
+  }
+
+  // This invalidates the iterator `iterator` in the current environment.
+  void InvalidateIterator(clang::dataflow::Environment& env,
+                          clang::dataflow::Value& iterator) {
+    SetIsValid(env, iterator, env.getBoolLiteralValue(false));
+  }
+
+  clang::dataflow::Value& CreateIteratorValue(
+      clang::QualType type,
+      clang::dataflow::Environment& env,
+      clang::dataflow::RecordStorageLocation& Loc,
+      clang::dataflow::Value& container,
+      clang::dataflow::BoolValue& is_valid,
+      clang::dataflow::BoolValue& is_end) {
+    iterator_types_mapping_.insert(type.getCanonicalType());
+    auto& iterator = env.create<clang::dataflow::RecordValue>(Loc);
+    env.setValue(Loc, iterator);
+    PopulateIteratorValue(&iterator, container, is_valid, is_end, env);
+    return iterator;
+  }
+
+  void PopulateIteratorValue(clang::dataflow::Value* value,
+                             clang::dataflow::Value& container,
+                             clang::dataflow::BoolValue& is_valid,
+                             clang::dataflow::BoolValue& is_end,
+                             clang::dataflow::Environment& env) {
+    assert(clang::isa<clang::dataflow::RecordValue>(*value));
+    SetContainerValue(env, *value, container);
+    SetIsValid(env, *value, is_valid);
+    SetIsEnd(env, *value, is_end);
+  }
+
+  void CloneIterator(const clang::CallExpr* expr,
+                     clang::dataflow::Value& iterator,
+                     clang::dataflow::Environment& env) {
+    auto* container = GetContainerValue(env, iterator);
+    TransferCallReturningIterator(expr, *container, env.makeAtomicBoolValue(),
+                                  env.makeAtomicBoolValue(), env);
+  }
+
+  const clang::Expr* Unwrap(const clang::Expr* E) {
+    if (auto* implicitcast = clang::dyn_cast<clang::ImplicitCastExpr>(E)) {
+      return implicitcast->getSubExpr();  // Is this an iterator implicit cast?
+    }
+
+    if (auto* construct = clang::dyn_cast<clang::CXXConstructExpr>(E)) {
+      // If the iterator is default constructed, we do not track it since we
+      // can't link it to a container or anything. However, if it gets copy
+      // assigned from an actually tracked iterator, we'll be able to track it
+      // back.
+      if (construct->getNumArgs()) {
+        // Is this an iterator constructor being invoked?
+        return construct->getArg(0);
+      }
+    }
+
+    return nullptr;
+  }
+
+  // This method walks the given expression and tries to find an iterator tied
+  // to it.
+  clang::dataflow::Value* UnwrapAsIterator(
+      const clang::Expr* expr,
+      const clang::dataflow::Environment& env) {
+    while (expr) {
+      if (expr->isGLValue()) {
+        auto* loc = env.getStorageLocation(*expr);
+        if (loc) {
+          clang::dataflow::Value* value = env.getValue(*expr);
+          if (IsIterator(loc->getType().getCanonicalType())) {
+            return value;
+          }
+        }
+      }
+
+      expr = Unwrap(expr);
+    }
+    return nullptr;
+  }
+
+  // Gets the container value for the given iterator value.
+  clang::dataflow::Value* GetContainerValue(
+      const clang::dataflow::Environment& env,
+      const clang::dataflow::Value& iterator) {
+    assert(clang::isa<clang::dataflow::RecordValue>(iterator));
+    auto& record = clang::cast<clang::dataflow::RecordValue>(iterator);
+    auto& loc = record.getLoc();
+    if (!iterator_to_container_.count(&loc)) {
+      return nullptr;
+    }
+    return iterator_to_container_[&loc];
+  }
+
+  void SetContainerValue(const clang::dataflow::Environment& env,
+                         const clang::dataflow::Value& iterator,
+                         clang::dataflow::Value& container) {
+    auto& record = clang::cast<clang::dataflow::RecordValue>(iterator);
+    auto& storage = record.getLoc();
+    iterator_to_container_[&storage] = &container;
+  }
+
+  void UnsetContainerValue(const clang::dataflow::Environment& env,
+                           const clang::dataflow::Value& iterator) {
+    auto& record = clang::cast<clang::dataflow::RecordValue>(iterator);
+    auto& storage = record.getLoc();
+    iterator_to_container_.erase(&storage);
+  }
+
+  // Returns whether the currently handled value is an iterator.
+  bool IsIterator(clang::QualType type) {
+    return iterator_types_mapping_.count(type.getCanonicalType()) != 0;
+  }
+
+  // Dumps some debugging information about the iterator. Caller is responsible
+  // of ensuring `iterator` is actually an iterator.
+  std::string DebugString(const clang::dataflow::Environment& env,
+                          const clang::dataflow::Value& iterator) {
+    auto* container = GetContainerValue(env, iterator);
+    std::string res;
+    const auto& formula = GetIsValid(env, iterator)->formula();
+    const bool is_valid = env.proves(formula);
+    const bool is_invalid = env.proves(env.arena().makeNot(formula));
+    llvm::StringRef status = is_valid     ? "VALID"
+                             : is_invalid ? "INVALID"
+                                          : "MAYBE_INVALID";
+
+    llvm::raw_string_ostream(res) << &iterator << " (container: " << container
+                                  << " status: " << status << ")";
+    return res;
+  }
+
+  // The diagnostic engine that will issue potential errors.
+  clang::DiagnosticsEngine& diagnostic_;
+
+  // The iterator types found along the way.
+  // This part is kind of tricky for now, because we'd like to hard code these.
+  // Unfortunately, since we aim at handling multiple iterator types, we can't
+  // really do it statically, so we need to store the types while we encounter
+  // them.
+  llvm::DenseSet<clang::QualType> iterator_types_mapping_;
+
+  // Iterator to container map. This allows us to invalidate all iterators in
+  // case this is needed.
+  llvm::DenseMap<clang::dataflow::StorageLocation*, clang::dataflow::Value*>
+      iterator_to_container_;
+};
+
+class IteratorInvalidationCheck
+    : public clang::ast_matchers::MatchFinder::MatchCallback {
+ public:
+  // The checks will performed on every function implemented in the main file.
+  void Register(clang::ast_matchers::MatchFinder& finder) {
+    using namespace clang::ast_matchers;
+    finder.addMatcher(
+        functionDecl(isExpansionInMainFile(), isDefinition(), hasBody(stmt()))
+            .bind("fun"),
+        this);
+  }
+
+  // clang::ast_matchers::MatchFinder::MatchCallback implementation:
+  void run(const clang::ast_matchers::MatchFinder::MatchResult& result) final {
+    if (result.SourceManager->getDiagnostics().hasUncompilableErrorOccurred()) {
+      return;
+    }
+
+    const auto* func = result.Nodes.getNodeAs<clang::FunctionDecl>("fun");
+    assert(func);
+    if (!Supported(*func)) {
+      return;
+    }
+
+    InfoStream() << "[FUNCTION] " << func->getQualifiedNameAsString() << '\n';
+    auto control_flow_context = clang::dataflow::ControlFlowContext::build(
+        *func, *func->getBody(), *result.Context);
+    if (!control_flow_context) {
+      llvm::report_fatal_error(control_flow_context.takeError());
+      return;
+    }
+
+    auto solver = std::make_unique<clang::dataflow::WatchedLiteralsSolver>();
+    clang::dataflow::DataflowAnalysisContext analysis_context(
+        std::move(solver));
+    clang::dataflow::Environment environment(analysis_context, *func);
+
+    InvalidIteratorAnalysis analysis(func,
+                                     result.SourceManager->getDiagnostics());
+
+    analysis_context.setSyntheticFieldCallback(
+        std::bind(&InvalidIteratorAnalysis::GetSyntheticFields, &analysis,
+                  std::placeholders::_1));
+
+    auto analysis_result =
+        runDataflowAnalysis(*control_flow_context, analysis, environment);
+    if (!analysis_result) {
+      // just ignore that for now!
+      handleAllErrors(analysis_result.takeError(),
+                      [](const llvm::StringError& E) {});
+    }
+  }
+
+  bool Supported(const clang::FunctionDecl& func) {
+    if (func.isTemplated()) {
+      return false;
+    }
+
+    if (auto* method = clang::dyn_cast<clang::CXXMethodDecl>(&func)) {
+      return Supported(*method);
+    }
+
+    return true;
+  }
+
+  bool Supported(const clang::CXXMethodDecl& method) {
+    const clang::CXXRecordDecl* record_declaration = method.getParent();
+    if (record_declaration && record_declaration->isLambda()) {
+      return false;
+    }
+
+    if (method.isStatic()) {
+      return true;
+    }
+
+    if (method.getThisType()->isDependentType()) {
+      return false;
+    }
+
+    if (method.getParent()->isTemplateDecl()) {
+      return false;
+    }
+
+    if (method.getThisType()->isUnionType()) {
+      return false;
+    }
+
+    // Ignore methods of unions and structs that contain an union.
+    std::vector<clang::QualType> type_stack;
+    type_stack.push_back(method.getThisType());
+    while (!type_stack.empty()) {
+      clang::QualType type = type_stack.back();
+      type_stack.pop_back();
+
+      if (type->isUnionType()) {
+        return false;
+      }
+
+      if (clang::CXXRecordDecl* cpp_record = type->getAsCXXRecordDecl()) {
+        for (auto f : cpp_record->fields()) {
+          type_stack.push_back(f->getType());
+        }
+      }
+    }
+
+    return true;
+  }
+};
+
+class IteratorInvalidationConsumer : public clang::ASTConsumer {
+ public:
+  IteratorInvalidationConsumer(clang::CompilerInstance& instance) {}
+
+  void HandleTranslationUnit(clang::ASTContext& context) final {
+    IteratorInvalidationCheck checker;
+    clang::ast_matchers::MatchFinder match_finder;
+    checker.Register(match_finder);
+    match_finder.matchAST(context);
+  }
+};
+
+class IteratorInvalidationPluginAction : public clang::PluginASTAction {
+ public:
+  IteratorInvalidationPluginAction() = default;
+
+ private:
+  // clang::PluginASTAction implementation:
+  std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(
+      clang::CompilerInstance& instance,
+      llvm::StringRef ref) final {
+    llvm::EnablePrettyStackTrace();
+    return std::make_unique<IteratorInvalidationConsumer>(instance);
+  }
+
+  PluginASTAction::ActionType getActionType() final {
+    return CmdlineBeforeMainAction;
+  }
+
+  bool ParseArgs(const clang::CompilerInstance&,
+                 const std::vector<std::string>& args) final {
+    return true;
+  }
+};
+
+static clang::FrontendPluginRegistry::Add<IteratorInvalidationPluginAction> X(
+    "iterator-checker",
+    "Check c++ iterator misuse");
+
+}  // namespace
diff --git a/tools/clang/iterator_checker/OWNERS b/tools/clang/iterator_checker/OWNERS
new file mode 100644
index 0000000..22c36f3
--- /dev/null
+++ b/tools/clang/iterator_checker/OWNERS
@@ -0,0 +1,2 @@
+arthursonzogni@chromium.org
+paulsemel@chromium.org
diff --git a/tools/clang/iterator_checker/README.md b/tools/clang/iterator_checker/README.md
new file mode 100644
index 0000000..fff7771f
--- /dev/null
+++ b/tools/clang/iterator_checker/README.md
@@ -0,0 +1,66 @@
+# Clang IteratorChecker
+
+> Note for developers:
+> FlowSensitive is a fast evolving framework, and thus some breaking changes
+> are regularly introduced. The current state of this plugin works against
+> `llvmorg-18.0.0`.
+
+This clang plugin aims at detecting iterator use-after-invalidation bugs using
+the clang-tidy dataflow framework FlowSensitive.
+
+For instance:
+```cpp
+  for (auto* it = container->begin(); it != container->end();) {
+    if (it->block_end <= block_offset) {
+      // should be it = container->erase(it);
+      container->erase(it);
+    } else {
+      ++it;
+    }
+  }
+}
+```
+It is not valid using `++it` in the second branch of the loop after if
+`container->erase(it)` was called on the first branch. See real code
+[example](https://chromium-review.googlesource.com/c/chromium/src/+/4306699).
+
+
+## Build
+
+Clang is built using CMake. To run cmake, this script can be used:
+```bash
+  ./tools/clang/scripts/build.py     \
+    --without-android                \
+    --without-fuchsia                \
+    --extra-tools iterator_checker
+```
+
+The build directory is created into: `third_party/llvm-build/Release+Asserts/`
+and you can build it again using:
+```bash
+  ninja -C third_party/llvm-build/Release+Asserts/
+```
+
+
+## Run the tests
+
+```bash
+	./tools/clang/iterator_checker/tests/test.py \
+    $(pwd)/third_party/llvm-build/Release+Asserts/bin/clang
+```
+
+
+## Using the plugin
+
+The procedure is mostly the same as for the other clang plugins in chrome. What
+you need to do is to basically add the following [in a GN file](https://source.chromium.org/chromium/chromium/src/+/main:build/config/clang/BUILD.gn)
+(depending what you want the plugin to be used for).
+
+```bash
+cflags += [
+  "-Xclang",
+  "-add-plugin",
+  "-Xclang",
+  "iterator-checker",
+]
+```
\ No newline at end of file
diff --git a/tools/clang/iterator_checker/tests/inter-container-iterator-comparison.cpp b/tools/clang/iterator_checker/tests/inter-container-iterator-comparison.cpp
new file mode 100644
index 0000000..93f0bbd
--- /dev/null
+++ b/tools/clang/iterator_checker/tests/inter-container-iterator-comparison.cpp
@@ -0,0 +1,44 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include <algorithm>
+#include <vector>
+
+// Checks that comparison between valid iterators but from different containers
+// triggers an error.
+void ValidIteratorsWithDifferentContainers() {
+  std::vector<int> v1, v2;
+
+  auto it1 = v1.begin();
+  auto it2 = v2.begin();
+
+  if (it1 == v1.end() || it2 == v2.end()) {
+    return;
+  }
+
+  // Iterators are now valid, because we checked them against the `end`
+  // iterator.
+  *it1;
+  *it2;
+
+  // Wrong comparison, those iterators are not coming from the same container.
+  if (it1 == it2) {
+    return;
+  }
+}
+
+// Checks that iterators checked against the wrong `end` iterator triggers an
+// error.
+void WrongEndIteratorCheck() {
+  std::vector<int> v1, v2;
+
+  // Wrong comparison, iterators are not from the same containers.
+  if (v1.begin() != v2.end()) {
+    return;
+  }
+
+  auto it = v1.begin();
+  if (it != v2.end()) {
+    return;
+  }
+}
diff --git a/tools/clang/iterator_checker/tests/inter-container-iterator-comparison.txt b/tools/clang/iterator_checker/tests/inter-container-iterator-comparison.txt
new file mode 100644
index 0000000..6fa515f
--- /dev/null
+++ b/tools/clang/iterator_checker/tests/inter-container-iterator-comparison.txt
@@ -0,0 +1,10 @@
+inter-container-iterator-comparison.cpp:25:7: error: [iterator-checker] Potentially invalid iterator comparison.
+  if (it1 == it2) {
+      ^
+inter-container-iterator-comparison.cpp:36:7: error: [iterator-checker] Potentially invalid iterator comparison.
+  if (v1.begin() != v2.end()) {
+      ^
+inter-container-iterator-comparison.cpp:41:7: error: [iterator-checker] Potentially invalid iterator comparison.
+  if (it != v2.end()) {
+      ^
+3 errors generated.
diff --git a/tools/clang/iterator_checker/tests/iterator-with-multiple-container.cpp b/tools/clang/iterator_checker/tests/iterator-with-multiple-container.cpp
new file mode 100644
index 0000000..91c5a16
--- /dev/null
+++ b/tools/clang/iterator_checker/tests/iterator-with-multiple-container.cpp
@@ -0,0 +1,110 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include <algorithm>
+#include <vector>
+
+bool Bool();
+
+void MergeWithDifferentContainerValuesIteratorUnchecked() {
+  std::vector<int> v1 = {1, 10, 100};
+  std::vector<int> v2 = {1, 10, 100};
+  std::vector<int> v3 = {1, 10, 100};
+
+  auto it = std::find(v1.begin(), v1.end(), 10);
+
+  if (Bool()) {
+    it = std::find(v2.begin(), v2.end(), 10);
+  } else {
+    it = std::find(v3.begin(), v3.end(), 10);
+  }
+
+  v1.clear();
+
+  // As for now, the tool doesn't handle well merges with different container
+  // values. see https://crbug.com/1455371.
+  // However, since the iterator was never checked against `end`, accessing it
+  // is still considered invalid.
+  *it = 20;
+}
+
+void MergeWithDifferentContainerValueIteratorChecked() {
+  std::vector<int> v1 = {1, 10, 100};
+  std::vector<int> v2 = {1, 10, 100};
+  std::vector<int> v3 = {1, 10, 100};
+
+  auto it = std::find(v1.begin(), v1.end(), 10);
+
+  if (Bool()) {
+    it = std::find(v2.begin(), v2.end(), 10);
+    if (it == std::end(v2)) {
+      return;
+    }
+  } else {
+    it = std::find(v3.begin(), v3.end(), 10);
+    if (it == std::end(v3)) {
+      return;
+    }
+  }
+
+  v1.clear();
+
+  // This is in practice valid, because it can only be true here.
+  // Although the tool does well on this case, the fact that multiple
+  // containers are being used for the same iterator above means that the tool
+  // is lucky.
+  *it = 20;
+}
+
+void MergeWithDifferentContainersInvalidateAll() {
+  std::vector<int> v1 = {1, 10, 100};
+  std::vector<int> v2 = {1, 10, 100};
+
+  auto it = std::find(v1.begin(), v1.end(), 10);
+
+  if (Bool()) {
+    it = std::find(v2.begin(), v2.end(), 10);
+    if (it == std::end(v2)) {
+      return;
+    }
+  } else {
+    it = std::find(v1.begin(), v1.end(), 10);
+    if (it == std::end(v1)) {
+      return;
+    }
+  }
+
+  v1.clear();
+
+  // This should be invalid, but the tool lost track of the container in the
+  // merge above.
+  *it = 20;
+}
+
+void MergeWithSameContainerValueIteratorChecked() {
+  std::vector<int> v1 = {1, 10, 100};
+  std::vector<int> v2 = {1, 10, 100};
+  std::vector<int> v3 = {1, 10, 100};
+
+  auto it = std::find(v1.begin(), v1.end(), 10);
+
+  if (Bool()) {
+    it = std::find(v1.begin(), v1.end(), 10);
+    if (it == std::end(v1)) {
+      return;
+    }
+  } else {
+    it = std::find(v1.begin(), v1.end(), 10);
+    if (it == std::end(v1)) {
+      return;
+    }
+  }
+
+  // it is valid here because we would have returned from the function in the
+  // previous conditional blocks if not.
+  *it;
+  v1.clear();
+
+  // it just got invalidated by `v1.clear()`.
+  *it = 20;
+}
diff --git a/tools/clang/iterator_checker/tests/iterator-with-multiple-container.txt b/tools/clang/iterator_checker/tests/iterator-with-multiple-container.txt
new file mode 100644
index 0000000..2f91795
--- /dev/null
+++ b/tools/clang/iterator_checker/tests/iterator-with-multiple-container.txt
@@ -0,0 +1,10 @@
+iterator-with-multiple-container.cpp:28:4: error: [iterator-checker] Potentially invalid iterator used.
+  *it = 20;
+   ^
+iterator-with-multiple-container.cpp:81:4: error: [iterator-checker] Potentially invalid iterator used.
+  *it = 20;
+   ^
+iterator-with-multiple-container.cpp:109:4: error: [iterator-checker] Potentially invalid iterator used.
+  *it = 20;
+   ^
+3 errors generated.
diff --git a/tools/clang/iterator_checker/tests/iterator-with-multiple-container.txt.actual b/tools/clang/iterator_checker/tests/iterator-with-multiple-container.txt.actual
new file mode 100644
index 0000000..2f91795
--- /dev/null
+++ b/tools/clang/iterator_checker/tests/iterator-with-multiple-container.txt.actual
@@ -0,0 +1,10 @@
+iterator-with-multiple-container.cpp:28:4: error: [iterator-checker] Potentially invalid iterator used.
+  *it = 20;
+   ^
+iterator-with-multiple-container.cpp:81:4: error: [iterator-checker] Potentially invalid iterator used.
+  *it = 20;
+   ^
+iterator-with-multiple-container.cpp:109:4: error: [iterator-checker] Potentially invalid iterator used.
+  *it = 20;
+   ^
+3 errors generated.
diff --git a/tools/clang/iterator_checker/tests/merge-condition-basic.cpp b/tools/clang/iterator_checker/tests/merge-condition-basic.cpp
new file mode 100644
index 0000000..27118c5f
--- /dev/null
+++ b/tools/clang/iterator_checker/tests/merge-condition-basic.cpp
@@ -0,0 +1,115 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include <algorithm>
+#include <vector>
+
+bool A();
+bool B();
+
+void SameConditionInvalidatesThenValidatesIterator() {
+  std::vector<int> container = {1, 2, 3};
+  auto it = container.begin() + 1;
+  if (it == container.end()) {
+    return;
+  }
+
+  const bool a = A();
+
+  if (a) {
+    container.clear();
+  }
+
+  if (a) {
+    container.push_back(1);
+    container.push_back(2);
+    it = container.begin() + 1;
+    if (it == std::end(container)) {
+      return;
+    }
+  }
+
+  // This is valid because although the container was invalidated in the first
+  // `if(a)` block, the second one reassigns the iterator and ensures that it
+  // is different than `end`. Since the same check is made at the very
+  // beginning of the function, the iterator is logically valid at this point
+  // of the execution.
+  *it = 10;
+}
+
+void SameConditionUncheckedIterator() {
+  std::vector<int> container = {1, 2, 3};
+  auto it = container.begin() + 1;
+  if (it == std::end(container)) {
+    return;
+  }
+
+  const bool a = A();
+
+  if (a) {
+    container.clear();
+  }
+
+  if (!a) {
+    container.push_back(1);
+    container.push_back(2);
+    it = container.begin() + 1;
+  }
+
+  // This is invalid because although the iterator is getting reassigned in the
+  // second `a` conditional block, it is not checked against the `end` iterator.
+  *it = 10;  // Invalid.
+}
+
+void DifferentConditionsWithCheckedIterator() {
+  std::vector<int> container = {1, 2, 3};
+  auto it = container.begin() + 1;
+  if (it == std::end(container)) {
+    return;
+  }
+
+  const bool a = A();
+  const bool b = B();
+
+  if (a && b) {
+    container.clear();
+  }
+
+  if (a || b) {
+    container.push_back(1);
+    container.push_back(2);
+    it = container.begin() + 1;
+    if (it == std::end(container)) {
+      return;
+    }
+  }
+
+  // Valid since in all cases it is checked against the `end` iterator.
+  *it = 10;
+}
+
+void DifferentConditionsWithUncheckedIterator() {
+  std::vector<int> container = {1, 2, 3};
+  auto it = container.begin() + 1;
+  if (it == std::end(container)) {
+    return;
+  }
+
+  const bool a = A();
+  const bool b = B();
+
+  if (a && b) {
+    container.clear();
+  }
+
+  if (a || b) {
+    container.push_back(1);
+    container.push_back(2);
+    it = container.begin() + 1;
+  }
+
+  // Invalid. The difference with `DifferentConditionsWithCheckedIterator` is
+  // that we do not check the iterator in the last `if` block, hence we can't
+  // ensure that the iterator is valid.
+  *it = 10;
+}
diff --git a/tools/clang/iterator_checker/tests/merge-condition-basic.txt b/tools/clang/iterator_checker/tests/merge-condition-basic.txt
new file mode 100644
index 0000000..1731951
--- /dev/null
+++ b/tools/clang/iterator_checker/tests/merge-condition-basic.txt
@@ -0,0 +1,7 @@
+merge-condition-basic.cpp:61:4: error: [iterator-checker] Potentially invalid iterator used.
+  *it = 10;  // Invalid.
+   ^
+merge-condition-basic.cpp:114:4: error: [iterator-checker] Potentially invalid iterator used.
+  *it = 10;
+   ^
+2 errors generated.
diff --git a/tools/clang/iterator_checker/tests/simple-invalid-iterators.cpp b/tools/clang/iterator_checker/tests/simple-invalid-iterators.cpp
new file mode 100644
index 0000000..079b76f
--- /dev/null
+++ b/tools/clang/iterator_checker/tests/simple-invalid-iterators.cpp
@@ -0,0 +1,31 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include <vector>
+
+void IteratorUsedAfterErase(std::vector<int>& v) {
+  auto it = std::begin(v);
+  for (; it != std::end(v); ++it) {
+    // Note that this access is valid, because we theoretically always check it
+    // against `end` before going here.
+    if (*it > 3) {
+      // Calling `erase` invalidates `it`, and the next loop iteration will use
+      // it via `++it`.
+      // To fix this error:
+      // it = v.erase(it);
+      v.erase(it);
+    }
+  }
+}
+
+void IteratorUsedAfterPushBack(std::vector<int>& v) {
+  auto it = std::begin(v);
+  // Note that `*it == 3` is valid here because we first checked it against
+  // `end`.
+  if (it != std::end(v) && *it == 3) {
+    // Similarly here, push_back invalidates all the previous iterators.
+    v.push_back(4);
+  }
+  // Invalid because we might have entered the condition block.
+  ++it;
+}
diff --git a/tools/clang/iterator_checker/tests/simple-invalid-iterators.txt b/tools/clang/iterator_checker/tests/simple-invalid-iterators.txt
new file mode 100644
index 0000000..91eb4a32
--- /dev/null
+++ b/tools/clang/iterator_checker/tests/simple-invalid-iterators.txt
@@ -0,0 +1,9 @@
+simple-invalid-iterators.cpp:8:31: error: [iterator-checker] Potentially invalid iterator used.
+  for (; it != std::end(v); ++it) {
+                              ^
+simple-invalid-iterators.cpp:8:31: error: [iterator-checker] Potentially invalid iterator used.
+simple-invalid-iterators.cpp:8:31: error: [iterator-checker] Potentially invalid iterator used.
+simple-invalid-iterators.cpp:30:5: error: [iterator-checker] Potentially invalid iterator used.
+  ++it;
+    ^
+4 errors generated.
diff --git a/tools/clang/iterator_checker/tests/simple-std-find.cpp b/tools/clang/iterator_checker/tests/simple-std-find.cpp
new file mode 100644
index 0000000..a598725
--- /dev/null
+++ b/tools/clang/iterator_checker/tests/simple-std-find.cpp
@@ -0,0 +1,23 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include <algorithm>
+#include <vector>
+
+void IteratorCheckedAfterFind(const std::vector<int>& v) {
+  auto it = std::find(std::begin(v), std::end(v), 3);
+  if (it != std::end(v)) {
+    // Fine because it was checked against `end`.
+    *it;
+  }
+}
+
+void IteratorCheckedAfterFindThenErased(std::vector<int> v) {
+  auto it = std::find(std::begin(v), std::end(v), 3);
+  if (it != std::end(v)) {
+    v.erase(it);
+  }
+  // Invalid because we might have entered the `if` block and invalidated this
+  // iterator.
+  *it;
+}
diff --git a/tools/clang/iterator_checker/tests/simple-std-find.txt b/tools/clang/iterator_checker/tests/simple-std-find.txt
new file mode 100644
index 0000000..22b37ba
--- /dev/null
+++ b/tools/clang/iterator_checker/tests/simple-std-find.txt
@@ -0,0 +1,4 @@
+simple-std-find.cpp:22:4: error: [iterator-checker] Potentially invalid iterator used.
+  *it;
+   ^
+1 error generated.
diff --git a/tools/clang/iterator_checker/tests/test.py b/tools/clang/iterator_checker/tests/test.py
new file mode 100755
index 0000000..8d589ccb
--- /dev/null
+++ b/tools/clang/iterator_checker/tests/test.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+# Copyright 2024 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import argparse
+import os
+import subprocess
+import sys
+
+script_dir = os.path.dirname(os.path.realpath(__file__))
+tool_dir = os.path.abspath(os.path.join(script_dir, '../../pylib'))
+sys.path.insert(0, tool_dir)
+
+from clang import plugin_testing
+
+
+class IteratorCheckerPluginTest(plugin_testing.ClangPluginTest):
+  """Test harness for the Blink GC plugin."""
+
+  def __init__(self, *args, **kwargs):
+    super(IteratorCheckerPluginTest, self).__init__(*args, **kwargs)
+
+  def AdjustClangArguments(self, clang_cmd):
+    pass
+
+  def ProcessOneResult(self, test_name, actual):
+    return super(IteratorCheckerPluginTest,
+                 self).ProcessOneResult(test_name, actual)
+
+
+def main():
+  parser = argparse.ArgumentParser()
+  parser.add_argument(
+      '--reset-results',
+      action='store_true',
+      help='If specified, overwrites the expected results in place.')
+  parser.add_argument('clang_path', help='The path to the clang binary.')
+  args = parser.parse_args()
+
+  dir_name = os.path.dirname(os.path.realpath(__file__))
+
+  num_failures = IteratorCheckerPluginTest(dir_name, args.clang_path,
+                                           'iterator-checker',
+                                           args.reset_results).Run()
+
+  return num_failures
+
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index f9b82cb..a692ff9 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -34981,6 +34981,9 @@
 </action>
 
 <action name="Signin_Signin_FromCloudPrint">
+  <obsolete>
+    Removed by clean-up in M123 but was deprecated even long before that.
+  </obsolete>
   <owner>gogerald@chromium.org</owner>
   <description>
     Recorded on sign in start from access point
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 5ef5b54..63dfba00 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -26347,6 +26347,7 @@
   <int value="781" label="inset-area"/>
   <int value="782" label="view-transition-class"/>
   <int value="783" label="position-try-order"/>
+  <int value="784" label="position-try-options"/>
 </enum>
 
 <enum name="MediaEncryptionType">
diff --git a/tools/metrics/histograms/expand_owners.py b/tools/metrics/histograms/expand_owners.py
index b05636f..e4c5f74 100644
--- a/tools/metrics/histograms/expand_owners.py
+++ b/tools/metrics/histograms/expand_owners.py
@@ -201,17 +201,20 @@
 def _ComponentFromDirmd(json_data, subpath):
   """Returns the component for a subpath based on dirmd output.
 
-  Returns an empty string if no component can be extracted
+  Returns an empty string if no component can be extracted.
 
   Args:
     json_data: json object output from dirmd.
     subpath: The subpath for the directory being queried, e.g. src/storage'.
   """
+  dirmd = json_data.get('dirs', {}).get(subpath, {})
+  # If a public Buganizer component is listed, return its component ID.
+  if buganizer_component := dirmd.get('buganizerPublic',
+                                      {}).get('componentId', ''):
+    return buganizer_component
   # If no component exists for the directory, or if METADATA migration is
   # incomplete there will be no component information.
-  return json_data.get('dirs', {}).get(subpath,
-                                       {}).get('monorail',
-                                               {}).get('component', '')
+  return dirmd.get('monorail', {}).get('component', '')
 
 
 # Memoize decorator from: https://stackoverflow.com/a/1988826
@@ -229,13 +232,15 @@
 
 @Memoize
 def _ExtractComponentViaDirmd(path):
-  """Returns the component for monorail issues at the given path.
+  """Returns the component for Buganizer issues at the given path.
 
-  Examples are 'Blink>Storage>FileAPI' and 'UI'.
+  Examples are '1287811' for Buganizer and 'UI>Shell>Launcher' for Monorail.
 
   Uses dirmd in third_party/depot_tools to parse metadata and walk parent
   directories up to the top level of the repo.
 
+  Returns a Monorail component if no Buganizer component can be extracted.
+
   Returns an empty string if no component can be extracted.
 
   Args:
@@ -358,9 +363,9 @@
 
   If the text of an owner node is an OWNERS file path, then this node is
   replaced by owner nodes for the emails derived from the OWNERS file. If a
-  component, e.g. UI>GFX, can be derived from the OWNERS file or an OWNERS file
+  component, e.g. 1287811, can be derived from the OWNERS file or an OWNERS file
   in a higher-level directory, then a component tag will be added to the
-  histogram, e.g. <component>UI&gt;GFX</component>.
+  histogram, e.g. <component>1287811</component>.
 
   Args:
     histograms: The DOM Element whose descendants may be updated.
diff --git a/tools/metrics/histograms/expand_owners_unittest.py b/tools/metrics/histograms/expand_owners_unittest.py
index 632842b6..3e8dcde 100644
--- a/tools/metrics/histograms/expand_owners_unittest.py
+++ b/tools/metrics/histograms/expand_owners_unittest.py
@@ -66,8 +66,11 @@
 
   def setUp(self):
     super(ExpandOwnersTest, self).setUp()
+    # Create the temporary directory in tools/ so that the tests won't be
+    # affected by tools/metrics/DIR_METADATA.
+    # TODO(arielzhang): Check if there's a better way to handle this.
     self.temp_dir = tempfile.mkdtemp(
-        dir=os.path.abspath(os.path.join(os.path.dirname(__file__))))
+        dir=os.path.abspath(os.path.join(os.path.dirname(__file__) + '/../..')))
 
     # The below construction is used rather than __file__.endswith() because
     # the file extension could be .py or .pyc.
@@ -133,6 +136,63 @@
     expand_owners.ExpandHistogramsOWNERS(histograms)
     self.assertMultiLineEqual(histograms.toxml(), expected_histograms.toxml())
 
+  def testExpandOwnersUsesBuganizerOverMonorail(self):
+    """Checks that DIR_METADATA is used if available"""
+    with open(os.path.join(self.temp_dir, 'DIR_METADATA'), "w+") as md:
+      md.write("\n".join([
+          'monorail {', 'component: "Bees"', '}', 'buganizer_public {',
+          'component_id:123456', '}'
+      ]))
+    absolute_path = _MakeOwnersFile('simple_OWNERS', self.temp_dir)
+    with open(absolute_path, 'w') as owners_file:
+      owners_file.write('\n'.join(['amy@chromium.org', 'rae@chromium.org']))
+    self.maxDiff = None
+    src_relative_path = _GetSrcRelativePath(absolute_path)
+    histograms = xml.dom.minidom.parseString("""
+<histograms>
+
+<histogram name="Caffeination" units="mg">
+  <owner>joe@chromium.org</owner>
+  <owner>{path}</owner>
+  <summary>I like coffee.</summary>
+</histogram>
+
+<histogram name="Maple.Syrup" units="units">
+  <owner>joe@chromium.org</owner>
+  <owner>{path}</owner>
+  <owner>kim@chromium.org</owner>
+  <summary>I like maple syrup, too.</summary>
+</histogram>
+
+</histograms>
+""".format(path=src_relative_path))
+
+    expected_histograms = xml.dom.minidom.parseString("""
+<histograms>
+
+<histogram name="Caffeination" units="mg">
+  <owner>joe@chromium.org</owner>
+  <owner>amy@chromium.org</owner>
+  <owner>rae@chromium.org</owner>
+  <summary>I like coffee.</summary>
+  <component>123456</component>
+</histogram>
+
+<histogram name="Maple.Syrup" units="units">
+  <owner>joe@chromium.org</owner>
+  <owner>amy@chromium.org</owner>
+  <owner>rae@chromium.org</owner>
+  <owner>kim@chromium.org</owner>
+  <summary>I like maple syrup, too.</summary>
+  <component>123456</component>
+</histogram>
+
+</histograms>
+""")
+
+    expand_owners.ExpandHistogramsOWNERS(histograms)
+    self.assertMultiLineEqual(histograms.toxml(), expected_histograms.toxml())
+
   @mock.patch('expand_owners._ExtractComponentViaDirmd')
   def testExpandOwnersWithSimpleOWNERSFilePath(self, mock_dirmd_extract):
     """Checks that OWNERS files are expanded."""
diff --git a/tools/metrics/histograms/metadata/cros_audio/OWNERS b/tools/metrics/histograms/metadata/cros_audio/OWNERS
index 2c65f4fc..3808ece 100644
--- a/tools/metrics/histograms/metadata/cros_audio/OWNERS
+++ b/tools/metrics/histograms/metadata/cros_audio/OWNERS
@@ -2,4 +2,5 @@
 
 # Prefer sending CLs to the owners listed below.
 # Use chromium-metrics-reviews@google.com as a backup.
-gavinwill@chromium.org
\ No newline at end of file
+gavinwill@chromium.org
+zhangwenyu@google.com
\ No newline at end of file
diff --git a/tools/metrics/histograms/metadata/cros_audio/histograms.xml b/tools/metrics/histograms/metadata/cros_audio/histograms.xml
index eeb24272..338f691 100644
--- a/tools/metrics/histograms/metadata/cros_audio/histograms.xml
+++ b/tools/metrics/histograms/metadata/cros_audio/histograms.xml
@@ -61,7 +61,7 @@
 
 <histogram name="ChromeOS.CrosAudioConfig.DeviceChange"
     enum="AudioDeviceChange" expires_after="2024-06-30">
-  <owner>gavinwill@chromium.org</owner>
+  <owner>zhangwenyu@google.com</owner>
   <owner>cros-peripherals@google.com</owner>
   <summary>
     Recorded when the user changes either the input or output audio device from
@@ -72,7 +72,7 @@
 
 <histogram name="ChromeOS.CrosAudioConfig.InputDeviceTypeChangedTo"
     enum="AudioDeviceType" expires_after="2024-06-30">
-  <owner>gavinwill@chromium.org</owner>
+  <owner>zhangwenyu@google.com</owner>
   <owner>cros-peripherals@google.com</owner>
   <summary>
     Records the type of device selected when the user changes the input audio
@@ -83,7 +83,7 @@
 
 <histogram name="ChromeOS.CrosAudioConfig.InputGainSetTo" units="%"
     expires_after="2024-06-30">
-  <owner>gavinwill@chromium.org</owner>
+  <owner>zhangwenyu@google.com</owner>
   <owner>cros-peripherals@google.com</owner>
   <summary>
     Records the input gain set by the user from a WebUI, such as the OS Audio
@@ -95,7 +95,7 @@
 
 <histogram name="ChromeOS.CrosAudioConfig.InputMuteStateChange"
     enum="AudioMuteButtonAction" expires_after="2024-06-30">
-  <owner>gavinwill@chromium.org</owner>
+  <owner>zhangwenyu@google.com</owner>
   <owner>cros-peripherals@google.com</owner>
   <summary>
     Recorded when the user changes the input audio mute state from a WebUI, such
@@ -105,7 +105,7 @@
 
 <histogram name="ChromeOS.CrosAudioConfig.NoiseCancellationEnabled"
     enum="BooleanEnabled" expires_after="2024-06-30">
-  <owner>gavinwill@chromium.org</owner>
+  <owner>zhangwenyu@google.com</owner>
   <owner>cros-peripherals@google.com</owner>
   <summary>
     Recorded when the user enables/disables noise cancellation from a WebUI,
@@ -115,7 +115,7 @@
 
 <histogram name="ChromeOS.CrosAudioConfig.OutputDeviceTypeChangedTo"
     enum="AudioDeviceType" expires_after="2024-06-30">
-  <owner>gavinwill@chromium.org</owner>
+  <owner>zhangwenyu@google.com</owner>
   <owner>cros-peripherals@google.com</owner>
   <summary>
     Records the type of device selected when the user changes the output audio
@@ -126,7 +126,7 @@
 
 <histogram name="ChromeOS.CrosAudioConfig.OutputMuteStateChange"
     enum="AudioMuteButtonAction" expires_after="2024-06-30">
-  <owner>gavinwill@chromium.org</owner>
+  <owner>zhangwenyu@google.com</owner>
   <owner>cros-peripherals@google.com</owner>
   <summary>
     Recorded when the user changes the output audio mute state from a WebUI,
@@ -136,7 +136,7 @@
 
 <histogram name="ChromeOS.CrosAudioConfig.OutputVolumeSetTo" units="%"
     expires_after="2024-06-30">
-  <owner>gavinwill@chromium.org</owner>
+  <owner>zhangwenyu@google.com</owner>
   <owner>cros-peripherals@google.com</owner>
   <summary>
     Records the output volume set by the user from a WebUI, such as the OS Audio
diff --git a/tools/metrics/histograms/metadata/signin/enums.xml b/tools/metrics/histograms/metadata/signin/enums.xml
index 1f255ca9..17c633e 100644
--- a/tools/metrics/histograms/metadata/signin/enums.xml
+++ b/tools/metrics/histograms/metadata/signin/enums.xml
@@ -361,7 +361,7 @@
   <int value="10" label="Avatar bubble sign in"/>
   <int value="11" label="Profile picker"/>
   <int value="12" label="Devices page"/>
-  <int value="13" label="Cloud print"/>
+  <int value="13" label="(obsolete) Cloud print"/>
   <int value="14" label="(obsolete) Content area"/>
   <int value="15" label="Signin promo"/>
   <int value="16" label="Recent tabs"/>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 4ed0202..ab38396 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,24 +5,24 @@
             "full_remote_path": "perfetto-luci-artifacts/v42.0/linux-arm64/trace_processor_shell"
         },
         "win": {
-            "hash": "db063bbed4ddda62cdf181242abeb02fa44ce049",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/6821c955bdf682556ec4828a174a9cd916d0a02a/trace_processor_shell.exe"
+            "hash": "e18d4233630bb5be75250d161756fa286d65ba71",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/f82e76bda590f95122db33491eb3d46012bd4352/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "46739eeb4b8f2a65a8a0aac57743767e6407f7bb",
             "full_remote_path": "perfetto-luci-artifacts/v42.0/linux-arm/trace_processor_shell"
         },
         "mac": {
-            "hash": "4c06710a5566077117ad084bcf92bb8955c2931e",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/6821c955bdf682556ec4828a174a9cd916d0a02a/trace_processor_shell"
+            "hash": "3451ae61d92dbf355168605b6e60c7b1030fdd95",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/f82e76bda590f95122db33491eb3d46012bd4352/trace_processor_shell"
         },
         "mac_arm64": {
             "hash": "789f24a091d50faafdd5d7c5096bb923d073f138",
             "full_remote_path": "perfetto-luci-artifacts/v42.0/mac-arm64/trace_processor_shell"
         },
         "linux": {
-            "hash": "c17caab00d94d8c803df62c76920f29c529de4d4",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/6821c955bdf682556ec4828a174a9cd916d0a02a/trace_processor_shell"
+            "hash": "2b3fbcdf11ac7cc617228e95dddea344eb639d13",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/f82e76bda590f95122db33491eb3d46012bd4352/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/v8 b/v8
index 4892aa3..7ac55f9 160000
--- a/v8
+++ b/v8
@@ -1 +1 @@
-Subproject commit 4892aa3e774cdd84597e696d57b4468a6ae3d77f
+Subproject commit 7ac55f9a5e28715fdcc8b0b2a1b49aa6dd5b1ce9