diff --git a/DEPS b/DEPS
index cb76c48..b4e0ae8 100644
--- a/DEPS
+++ b/DEPS
@@ -240,7 +240,7 @@
   # luci-go CIPD package version.
   # Make sure the revision is uploaded by infra-packagers builder.
   # https://ci.chromium.org/p/infra-internal/g/infra-packagers/console
-  'luci_go': 'git_revision:ef84eaf5160dadce3d98b8a2e4aa658dd2c0a7f1',
+  'luci_go': 'git_revision:7e34add007600430452e65b281863bb4fbeb25c8',
 
   # This can be overridden, e.g. with custom_vars, to build clang from HEAD
   # instead of downloading the prebuilt pinned revision.
@@ -291,19 +291,19 @@
   # 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': 'c839822533995cd97f48192847ba454aa0957927',
+  'src_internal_revision': '084cdb580c74879a21896f9edc873f29e11803a4',
   # 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': 'cdd82125aabea8e9970f42b0fb55d104bc371520',
+  'skia_revision': 'd30c79cd9594d24c87235250346dfa6b8503c28a',
   # 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': 'c7e3044597527a99e33d7f08695ac0229c8d8da1',
+  'v8_revision': 'e26dcb68002a524d342cbac01e8e605dbea7e18a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '214a48c41a84799cdf7cf821fcb0e3a0fccd2b11',
+  'angle_revision': '9635df8e92696c1434a7f2c5c4ea7dde84c38a6a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -327,7 +327,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling googletest
   # and whatever else without interference from each other.
-  'googletest_revision': '32f9f4c82afa4249af66b55278df15c16b3031ea',
+  'googletest_revision': '373af2e3df71599b87a40ce0e37164523849166b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling lighttpd
   # and whatever else without interference from each other.
@@ -359,7 +359,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': 'daf42e3671a72fa6ea1ba1ef380b8fb40d7d0fe2',
+  'catapult_revision': '4e4076a0d7a836b779a094989e911a65b2a3c1ee',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling CrossBench
   # and whatever else without interference from each other.
@@ -383,7 +383,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': 'a69b76e797b9aba0440520be85f0752fe35e965e',
+  'devtools_frontend_revision': 'ef0e719ca66bdf3c3a8767c3b4b981f4c56ba835',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -407,7 +407,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': 'b322a3577d95635eec4b4279de18431f119e3e5e',
+  'dawn_revision': 'fcda4f3d4b8c77aa0c0234d6abe629364949db97',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -487,7 +487,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'libcxxabi_revision':    '00a175050b73903b2f00e460dd2c9751c4a0fd88',
+  'libcxxabi_revision':    'a6c815c69d55ec59d020abde636754d120b402ad',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -511,7 +511,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling llvm-libc
   # and whatever else without interference from each other.
-  'llvm_libc_revision':    'f24be5deb774fae412aae70877b47fa6fcf19d28',
+  'llvm_libc_revision':    '14ca6ad7d68c47a6b7c18d53a6c69d4fa3a27571',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling llvm-libc
   # and whatever else without interference from each other.
@@ -1182,7 +1182,7 @@
       'packages': [
           {
               'package': 'chromium/chrome/android/orderfiles/arm',
-              'version': 'LqEg53v50eg9OuVMCBD3ax3vYIa3PBs3c2Psrj6vsdYC',
+              'version': 'Myl163LX4xFosaiPWynzJvHnP2jWfn8HbPJ88yn_-dsC',
           },
       ],
       'condition': 'checkout_android',
@@ -1193,7 +1193,7 @@
       'packages': [
           {
               'package': 'chromium/chrome/android/orderfiles/arm64',
-              'version': '0WGQl_tlTi3EqkZ6H410yKCWWDiJ5IpykczR1x2beDwC',
+              'version': 'YNOdYfVyT5LI8aVIB8LUq4vqVurAHF5OI8VODkXSqBYC',
           },
       ],
       'condition': 'checkout_android',
@@ -1538,7 +1538,7 @@
       'packages': [
         {
           'package': 'chromium/third_party/enterprise_companion/chromium_win_x86',
-          'version': 'h8g0yIIyshzWrg2JojtMw7z1pRNoUQ5tJjKCGIz0ROkC',
+          'version': 'bmWZhX8X6ts1zPyxR5wBsyH5oyOT_rwKCFOj_2T-pPkC',
         },
       ],
   },
@@ -1549,7 +1549,7 @@
       'packages': [
         {
           'package': 'chromium/third_party/enterprise_companion/chromium_win_x86_64',
-          'version': 'cNq4Dk8bbF32XJqeLas9nTuIYpfyhY4pBMxrA8G-U7kC',
+          'version': '2PhrcwVkpGd15JoMSEtAuutsK9zw3urK7WdhxcDIsHUC',
         },
       ],
   },
@@ -1585,7 +1585,7 @@
     'packages': [
       {
         'package': 'chromium/chrome/test/data/variations/cipd',
-        'version': 'ESdJyQgCzXxF795Ba4FD1bN0cV7CLD-YTpPPZHmS3eEC',
+        'version': 'GPoBHfUE3qghK-T3OzCySaxIlvXXBkEtoyqmyYU1kR4C',
       },
     ],
     'dep_type': 'cipd',
@@ -1596,7 +1596,7 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    '0e2e94e036bdbd47b362c54b645e6da30ad2c932',
+    'ab634f9586da5bb34ba75ca89615831c01b594a3',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
@@ -2079,7 +2079,7 @@
     Var('chromium_git') + '/chromium/web-tests.git' + '@' + Var('crossbench_web_tests_revision'),
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '1b44e27e7d4c63dfe83d10ed01d23824536e9811',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '6d019469b47bf20f564f6c1b2d7a1283a7d51efa',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
@@ -3056,7 +3056,7 @@
       'packages': [
         {
           'package': 'skia/tools/goldctl/mac-amd64',
-          'version': 'e7Uq2XB1IRBbp3a32o4m4yyU-eHdxmQ-2Kcp464UUoQC',
+          'version': 'gECkp6m7EgFK5h0fXBiVoC1n_YrAow0_1gxVnsvbQhgC',
         },
       ],
       'dep_type': 'cipd',
@@ -3686,7 +3686,7 @@
 
   'src/components/optimization_guide/internal': {
       'url': Var('chrome_git') + '/chrome/components/optimization_guide.git' + '@' +
-        'dd2a4751e727af7bf8fb5baa1fb52e070f354c17',
+        '34545b579229b4993a3f0ea5a1046b34e305a2aa',
       'condition': 'checkout_src_internal',
   },
 
@@ -3752,7 +3752,7 @@
 
   'src/ios_internal':  {
       'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' +
-        '66f62a3e6eaa6a83cdb803293328c40ab5db35aa',
+        '45e7e3004508820d06e4e208db56518783d89492',
       'condition': 'checkout_ios and checkout_src_internal',
   },
 
diff --git a/android_webview/browser/metrics/aw_metrics_service_client.cc b/android_webview/browser/metrics/aw_metrics_service_client.cc
index a4efe9d..b6369aeb 100644
--- a/android_webview/browser/metrics/aw_metrics_service_client.cc
+++ b/android_webview/browser/metrics/aw_metrics_service_client.cc
@@ -11,17 +11,7 @@
 #include "android_webview/common/aw_features.h"
 #include "base/android/callback_android.h"
 #include "base/android/jni_android.h"
-#include "base/android/jni_string.h"
-#include "base/base_paths_android.h"
-#include "base/feature_list.h"
-#include "base/files/file_util.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/persistent_histogram_allocator.h"
-#include "base/path_service.h"
-#include "base/task/task_traits.h"
-#include "base/task/thread_pool.h"
 #include "base/time/time.h"
-#include "base/trace_event/trace_event.h"
 #include "components/metrics/metrics_pref_names.h"
 #include "components/metrics/metrics_service.h"
 #include "components/prefs/pref_service.h"
@@ -62,8 +52,6 @@
 
 }  // namespace
 
-const base::TimeDelta kRecordAppDataDirectorySizeDelay = base::Seconds(10);
-
 AwMetricsServiceClient::Delegate::Delegate() = default;
 AwMetricsServiceClient::Delegate::~Delegate() = default;
 
@@ -98,36 +86,8 @@
   return !used_to_sample_in;
 }
 
-// Used below in AwMetricsServiceClient::OnMetricsStart.
-void RecordAppDataDirectorySize() {
-  TRACE_EVENT_BEGIN0("android_webview", "RecordAppDataDirectorySize");
-  base::TimeTicks start_time = base::TimeTicks::Now();
-
-  base::FilePath app_data_dir;
-  base::PathService::Get(base::DIR_ANDROID_APP_DATA, &app_data_dir);
-  int64_t bytes = base::ComputeDirectorySize(app_data_dir);
-  // Record size up to 100MB
-  base::UmaHistogramCounts100000("Android.WebView.AppDataDirectory.Size",
-                                 bytes / 1024);
-
-  base::UmaHistogramMediumTimes(
-      "Android.WebView.AppDataDirectory.TimeToComputeSize",
-      base::TimeTicks::Now() - start_time);
-  TRACE_EVENT_END0("android_webview", "RecordAppDataDirectorySize");
-}
-
 void AwMetricsServiceClient::OnMetricsStart() {
   delegate_->AddWebViewAppStateObserver(this);
-  if (base::FeatureList::IsEnabled(
-          android_webview::features::kWebViewRecordAppDataDirectorySize) &&
-      IsReportingEnabled()) {
-    // Calculating directory size can be fairly expensive, so only do this when
-    // we are certain that the UMA histogram will be logged to the server.
-    base::ThreadPool::PostDelayedTask(
-        FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
-        base::BindOnce(&RecordAppDataDirectorySize),
-        kRecordAppDataDirectorySizeDelay);
-  }
 }
 
 void AwMetricsServiceClient::OnAppStateChanged(
diff --git a/android_webview/browser/metrics/aw_metrics_service_client.h b/android_webview/browser/metrics/aw_metrics_service_client.h
index 536e24a..14623e47 100644
--- a/android_webview/browser/metrics/aw_metrics_service_client.h
+++ b/android_webview/browser/metrics/aw_metrics_service_client.h
@@ -20,12 +20,6 @@
 
 namespace android_webview {
 
-// The amount of delay before calculating and recording the app data directory
-// size, intended for avoiding IO contention when an app is initializing.
-//
-// Visible for testing.
-extern const base::TimeDelta kRecordAppDataDirectorySizeDelay;
-
 // AwMetricsServiceClient is a singleton which manages WebView metrics
 // collection.
 //
diff --git a/android_webview/browser/metrics/aw_metrics_service_client_unittest.cc b/android_webview/browser/metrics/aw_metrics_service_client_unittest.cc
index f109951ab..7789fb0 100644
--- a/android_webview/browser/metrics/aw_metrics_service_client_unittest.cc
+++ b/android_webview/browser/metrics/aw_metrics_service_client_unittest.cc
@@ -14,7 +14,6 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/test/test_simple_task_runner.h"
-#include "base/time/time.h"
 #include "base/version.h"
 #include "components/metrics/content/subprocess_metrics_provider.h"
 #include "components/metrics/metrics_switches.h"
@@ -80,18 +79,13 @@
   AwMetricsServiceTestClient* GetClient() { return client_.get(); }
   TestingPrefServiceSimple* GetPrefs() { return prefs_.get(); }
 
-  void TriggerDelayedRecordAppDataDirectorySize() {
-    task_environment_.FastForwardBy(kRecordAppDataDirectorySizeDelay);
-  }
-
  private:
   // Needed since starting metrics reporting triggers code that uses content::
   // objects.
   content::TestContentClientInitializer test_content_initializer_;
   // Needed since starting metrics reporting triggers code that expects to be
-  // running on the browser UI thread. Also needed for its FastForwardBy method.
-  content::BrowserTaskEnvironment task_environment_{
-      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+  // running on the browser UI thread.
+  content::BrowserTaskEnvironment task_environment_;
   scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
   std::unique_ptr<TestingPrefServiceSimple> prefs_;
   std::unique_ptr<AwMetricsServiceTestClient> client_;
@@ -99,71 +93,6 @@
 
 }  // namespace
 
-TEST_F(
-    AwMetricsServiceClientTest,
-    TestAppDataDirectorySize_RecordedIfFeatureEnabledConsentGrantedAndInSample) {
-  base::test::ScopedFeatureList scoped_list;
-  scoped_list.InitAndEnableFeature(
-      android_webview::features::kWebViewRecordAppDataDirectorySize);
-  base::HistogramTester histogram_tester;
-
-  GetClient()->SetInSample(true);
-  GetClient()->SetHaveMetricsConsent(true, true);
-  TriggerDelayedRecordAppDataDirectorySize();
-
-  histogram_tester.ExpectTotalCount("Android.WebView.AppDataDirectory.Size", 1);
-  histogram_tester.ExpectTotalCount(
-      "Android.WebView.AppDataDirectory.TimeToComputeSize", 1);
-}
-
-TEST_F(AwMetricsServiceClientTest,
-       TestAppDataDirectorySize_NotRecordedIfFeatureDisabled) {
-  base::test::ScopedFeatureList scoped_list;
-  scoped_list.InitAndDisableFeature(
-      android_webview::features::kWebViewRecordAppDataDirectorySize);
-  base::HistogramTester histogram_tester;
-
-  GetClient()->SetInSample(true);
-  GetClient()->SetHaveMetricsConsent(true, true);
-  TriggerDelayedRecordAppDataDirectorySize();
-
-  histogram_tester.ExpectTotalCount("Android.WebView.AppDataDirectory,Size", 0);
-  histogram_tester.ExpectTotalCount(
-      "Android.WebView.AppDataDirectory.TimeToComputeSize", 0);
-}
-
-TEST_F(AwMetricsServiceClientTest,
-       TestAppDataDirectorySize_NotRecordedIfConsentNotGranted) {
-  base::test::ScopedFeatureList scoped_list;
-  scoped_list.InitAndEnableFeature(
-      android_webview::features::kWebViewRecordAppDataDirectorySize);
-  base::HistogramTester histogram_tester;
-
-  GetClient()->SetInSample(true);
-  GetClient()->SetHaveMetricsConsent(true, false);
-  TriggerDelayedRecordAppDataDirectorySize();
-
-  histogram_tester.ExpectTotalCount("Android.WebView.AppDataDirectory.Size", 0);
-  histogram_tester.ExpectTotalCount(
-      "Android.WebView.AppDataDirectory.TimeToComputeSize", 0);
-}
-
-TEST_F(AwMetricsServiceClientTest,
-       TestAppDataDirectorySize_NotRecordedIfNotInSample) {
-  base::test::ScopedFeatureList scoped_list;
-  scoped_list.InitAndEnableFeature(
-      android_webview::features::kWebViewRecordAppDataDirectorySize);
-  base::HistogramTester histogram_tester;
-
-  GetClient()->SetInSample(false);
-  GetClient()->SetHaveMetricsConsent(true, true);
-  TriggerDelayedRecordAppDataDirectorySize();
-
-  histogram_tester.ExpectTotalCount("Android.WebView.AppDataDirectory.Size", 0);
-  histogram_tester.ExpectTotalCount(
-      "Android.WebView.AppDataDirectory.TimeToComputeSize", 0);
-}
-
 TEST_F(AwMetricsServiceClientTest,
        TestShouldApplyMetricsFilteringFeatureOn_AllMetrics) {
   // Both metrics consent and app consent true;
diff --git a/android_webview/common/aw_features.cc b/android_webview/common/aw_features.cc
index 5125141..e811c1b1 100644
--- a/android_webview/common/aw_features.cc
+++ b/android_webview/common/aw_features.cc
@@ -97,12 +97,6 @@
              "WebViewMuteAudio",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
-// Whether to record size of the embedding app's data directory to the UMA
-// histogram Android.WebView.AppDataDirectorySize.
-BASE_FEATURE(kWebViewRecordAppDataDirectorySize,
-             "WebViewRecordAppDataDirectorySize",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
 // A Feature used for WebView variations tests. Not used in production. Please
 // do not clean up this stale feature: we intentionally keep this feature flag
 // around for testing purposes.
diff --git a/android_webview/common/aw_features.h b/android_webview/common/aw_features.h
index d267f591..9d03b3c 100644
--- a/android_webview/common/aw_features.h
+++ b/android_webview/common/aw_features.h
@@ -30,7 +30,6 @@
 BASE_DECLARE_FEATURE(kWebViewMediaIntegrityApiBlinkExtension);
 BASE_DECLARE_FEATURE(kWebViewMixedContentAutoupgrades);
 BASE_DECLARE_FEATURE(kWebViewMuteAudio);
-BASE_DECLARE_FEATURE(kWebViewRecordAppDataDirectorySize);
 BASE_DECLARE_FEATURE(kWebViewRenderDocument);
 BASE_DECLARE_FEATURE(kWebViewTestFeature);
 BASE_DECLARE_FEATURE(kWebViewUseMetricsUploadService);
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 782a0d3..f5493f80 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
@@ -433,9 +433,6 @@
                 NetworkServiceFeatures.DEPRECATE_UNLOAD_BY_ALLOW_LIST,
                 "Unload Deprecation respects a list of allowed origins."),
         Flag.baseFeature(
-                AwFeatures.WEBVIEW_RECORD_APP_DATA_DIRECTORY_SIZE,
-                "Record the size of the embedding app's data directory"),
-        Flag.baseFeature(
                 BlinkFeatures.THREADED_PRELOAD_SCANNER,
                 "If enabled, the HTMLPreloadScanner will run on a worker thread."),
         Flag.baseFeature(
@@ -1075,6 +1072,34 @@
         Flag.baseFeature(
                 VizFeatures.NO_LATE_BEGIN_FRAMES,
                 "Enables not sending BeginFrameArgs late when a client begins observing them."),
+        Flag.baseFeature(
+                BaseFeatures.BACKGROUND_NOT_PERCEPTIBLE_BINDING,
+                "Enable boosting the importance of renderers without boosting their CPU priority."),
+        Flag.baseFeature(
+                "CleanupToBeNormalTermination",
+                "Process terminated by RenderProcessHost::Cleanup() is marked as "
+                        + "normal_termination."),
+        Flag.baseFeature(
+                "KeepChildProcessAfterIPCReset",
+                "When enabled, child process will not terminate itself when IPC is reset."),
+        Flag.baseFeature(
+                "StrictHighRankProcessLRU",
+                "Enable stricter management of the Android process LRU state to ensure that"
+                        + " high-rank processes are always more recent than low-rank processes."),
+        Flag.baseFeature(
+                BaseFeatures.UPDATE_STATE_BEFORE_UNBINDING,
+                "Update child process binding state before unbinding."),
+        Flag.baseFeature(
+                ContentFeatures.GROUP_REBINDING_FOR_GROUP_IMPORTANCE,
+                "Apply consecutive service group importance changes with a single service rebind"
+                        + " call."),
+        Flag.baseFeature(
+                BaseFeatures.USE_SHARED_REBIND_SERVICE_CONNECTION,
+                "Use a shared service connection to apply service group importance changes."),
+        Flag.baseFeature(
+                "ReloadHiddenTabsWithActiveCrashedSubframes",
+                "Restricts reloading of hidden tabs with crashed subframes to only happen for "
+                        + "active subframes."),
         // Add new commandline switches and features above. The final entry should have a
         // trailing comma for cleaner diffs.
     };
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java
index eb570b3c5..16e6f9a 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwAutofillTest.java
@@ -2669,10 +2669,7 @@
                                         new int[][] {
                                             {FieldType.CREDIT_CARD_NAME_FULL},
                                             {FieldType.CREDIT_CARD_NUMBER},
-                                            {
-                                                FieldType.CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR,
-                                                FieldType.CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR,
-                                            },
+                                            {FieldType.CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR},
                                             {FieldType.CREDIT_CARD_VERIFICATION_CODE}
                                         }));
 
@@ -2736,7 +2733,7 @@
                 "CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR",
                 viewStructure.getChild(2).getHtmlInfo().getAttribute("computed-autofill-hints"));
         assertEquals(
-                "CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR,CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR",
+                "CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR",
                 viewStructure
                         .getChild(2)
                         .getHtmlInfo()
diff --git a/ash/annotator/annotation_source_watcher.cc b/ash/annotator/annotation_source_watcher.cc
index 1282991..35c0013 100644
--- a/ash/annotator/annotation_source_watcher.cc
+++ b/ash/annotator/annotation_source_watcher.cc
@@ -36,14 +36,12 @@
   capture_mode_controller_ = nullptr;
 }
 
-void AnnotationSourceWatcher::NotifyMarkerClicked(aura::Window* current_root) {
-  // TODO(b/342104047): implement functionality
-}
 void AnnotationSourceWatcher::NotifyMarkerEnabled(aura::Window* current_root) {
-  // TODO(b/342104047): implement functionality
+  annotator_controller_->RegisterView(current_root);
+  annotator_controller_->CreateAnnotationOverlayForMarkerMode(current_root);
 }
 void AnnotationSourceWatcher::NotifyMarkerDisabled() {
-  // TODO(b/342104047): implement functionality
+  annotator_controller_->DisableAnnotator();
 }
 
 void AnnotationSourceWatcher::OnRecordingStarted(aura::Window* current_root) {
diff --git a/ash/annotator/annotation_source_watcher.h b/ash/annotator/annotation_source_watcher.h
index 7ad257e..d25e5d7 100644
--- a/ash/annotator/annotation_source_watcher.h
+++ b/ash/annotator/annotation_source_watcher.h
@@ -35,7 +35,6 @@
   AnnotationSourceWatcher& operator=(const AnnotationSourceWatcher&) = delete;
   ~AnnotationSourceWatcher() override;
 
-  void NotifyMarkerClicked(aura::Window* current_root);
   void NotifyMarkerEnabled(aura::Window* current_root);
   void NotifyMarkerDisabled();
 
diff --git a/ash/annotator/annotator_controller.cc b/ash/annotator/annotator_controller.cc
index 3e98c5bc..73257f4 100644
--- a/ash/annotator/annotator_controller.cc
+++ b/ash/annotator/annotator_controller.cc
@@ -9,6 +9,7 @@
 #include "ash/annotator/annotations_overlay_controller.h"
 #include "ash/annotator/annotator_metrics.h"
 #include "ash/capture_mode/capture_mode_controller.h"
+#include "ash/constants/ash_features.h"
 #include "ash/projector/projector_metrics.h"
 #include "ash/public/cpp/annotator/annotations_overlay_view.h"
 #include "ash/public/cpp/annotator/annotator_tool.h"
@@ -16,6 +17,7 @@
 #include "ash/system/status_area_widget.h"
 #include "ash/webui/annotator/public/cpp/annotator_client.h"
 #include "base/check.h"
+#include "base/feature_list.h"
 #include "ui/aura/window.h"
 #include "ui/gfx/geometry/rect_f.h"
 
@@ -137,6 +139,7 @@
     ToggleAnnotatorCanvas();
     annotator_enabled_ = !annotator_enabled_;
     UpdateAnnotationTrayAccessibleName(annotator_enabled_);
+    NotifyStateChanged();
     // TODO(b/342104047): Decouple from projector metrics.
     RecordToolbarMetrics(ProjectorToolbar::kMarkerTool);
   }
@@ -144,6 +147,7 @@
 
 void AnnotatorController::DisableAnnotator() {
   ResetTools();
+  NotifyStateChanged();
   if (current_root_) {
     UnregisterView(current_root_);
   }
@@ -166,6 +170,11 @@
   }
 }
 
+void AnnotatorController::CreateAnnotationOverlayForMarkerMode(
+    aura::Window* window) {
+  CreateAnnotationOverlayForWindow(window, std::nullopt);
+}
+
 void AnnotatorController::SetToolClient(AnnotatorClient* client) {
   client_ = client;
 }
@@ -200,6 +209,14 @@
   return client_->CreateAnnotationsOverlayView();
 }
 
+void AnnotatorController::AddObserver(AnnotatorObserver* observer) {
+  observers_.AddObserver(observer);
+}
+
+void AnnotatorController::RemoveObserver(AnnotatorObserver* observer) {
+  observers_.RemoveObserver(observer);
+}
+
 void AnnotatorController::UpdateTrayEnabledState() {
   if (auto* annotation_tray = GetAnnotationTrayForRoot(current_root_)) {
     annotation_tray->SetTrayEnabled(GetAnnotatorAvailability());
@@ -208,12 +225,16 @@
 
 void AnnotatorController::ToggleAnnotatorCanvas() {
   auto* capture_mode_controller = CaptureModeController::Get();
-  // TODO(b/342104047): This check is necessary as long as we only toggle
-  // annotator from Projector. Once we start using the annotator outside of
-  // Projector, we should remove the check.
-  if (capture_mode_controller->is_recording_in_progress()) {
+  if (base::FeatureList::IsEnabled(ash::features::kAnnotatorMode) ||
+      capture_mode_controller->is_recording_in_progress()) {
     annotations_overlay_controller_->Toggle();
   }
 }
 
+void AnnotatorController::NotifyStateChanged() {
+  for (AnnotatorObserver& observer : observers_) {
+    observer.OnAnnotatorStateChanged(annotator_enabled_);
+  }
+}
+
 }  // namespace ash
diff --git a/ash/annotator/annotator_controller.h b/ash/annotator/annotator_controller.h
index 6a6ab13f..ef4296d 100644
--- a/ash/annotator/annotator_controller.h
+++ b/ash/annotator/annotator_controller.h
@@ -15,6 +15,8 @@
 #include "base/functional/callback.h"
 #include "base/functional/callback_forward.h"
 #include "base/memory/raw_ptr.h"
+#include "base/observer_list.h"
+#include "base/observer_list_types.h"
 #include "third_party/skia/include/core/SkColor.h"
 
 namespace aura {
@@ -41,6 +43,11 @@
   AnnotatorController& operator=(const AnnotatorController&) = delete;
   ~AnnotatorController() override;
 
+  class AnnotatorObserver : public base::CheckedObserver {
+   public:
+    virtual void OnAnnotatorStateChanged(bool enabled) {}
+  };
+
   bool is_annotator_enabled() const { return annotator_enabled_; }
   AnnotationSourceWatcher* annotation_source_watcher() {
     return annotation_source_watcher_.get();
@@ -72,6 +79,7 @@
   void CreateAnnotationOverlayForWindow(
       aura::Window* window,
       std::optional<gfx::Rect> partial_region_bounds);
+  void CreateAnnotationOverlayForMarkerMode(aura::Window* window);
 
   // AnnotatorControllerBase:
   void SetToolClient(AnnotatorClient* client) override;
@@ -88,6 +96,9 @@
   // Updates the accessible name of the |annotation_tray_| in the accessibility
   // cache.
   void UpdateAnnotationTrayAccessibleName(bool is_annotator_enabled);
+  // Adds/removes the specified |observer|.
+  void AddObserver(AnnotatorObserver* observer);
+  void RemoveObserver(AnnotatorObserver* observer);
 
   void set_canvas_initialized_callback_for_test(base::OnceClosure callback) {
     on_canvas_initialized_callback_for_test_ = std::move(callback);
@@ -103,6 +114,8 @@
   // targeting the underlying window. Otherwise, it's hidden and cannot accept
   // any events.
   void ToggleAnnotatorCanvas();
+  // Notifies observers that the |annotator_enabled_| state has changed.
+  void NotifyStateChanged();
   raw_ptr<AnnotatorClient> client_ = nullptr;
   // True if the canvas is initialized successfully, false if it failed to
   // initialize. An absent value indicates that the initialization has not
@@ -116,6 +129,7 @@
   // Controls and owns the overlay widget, which is used to host annotations.
   std::unique_ptr<AnnotationsOverlayController> annotations_overlay_controller_;
   std::unique_ptr<AnnotationSourceWatcher> annotation_source_watcher_;
+  base::ObserverList<AnnotatorObserver> observers_;
 };
 
 }  // namespace ash
diff --git a/ash/annotator/annotator_controller_unittest.cc b/ash/annotator/annotator_controller_unittest.cc
index ce69efea..f4c805c 100644
--- a/ash/annotator/annotator_controller_unittest.cc
+++ b/ash/annotator/annotator_controller_unittest.cc
@@ -41,6 +41,17 @@
 
 }  // namespace
 
+class MockAnnotatorObserver : public AnnotatorController::AnnotatorObserver {
+ public:
+  MockAnnotatorObserver() = default;
+  MockAnnotatorObserver(const MockAnnotatorObserver&) = delete;
+  MockAnnotatorObserver& operator=(const MockAnnotatorObserver&) = delete;
+  ~MockAnnotatorObserver() override {}
+
+  // AnnotatorObserver:
+  MOCK_METHOD1(OnAnnotatorStateChanged, void(bool));
+};
+
 class AnnotatorControllerTest : public AshTestBase {
  public:
   AnnotatorControllerTest() = default;
@@ -54,14 +65,24 @@
 
     auto* annotator_controller = Shell::Get()->annotator_controller();
     annotator_controller->SetToolClient(&client_);
+    annotator_controller->AddObserver(&observer_);
+  }
+
+  // AshTestBase:
+  void TearDown() override {
+    Shell::Get()->annotator_controller()->RemoveObserver(&observer_);
+    AshTestBase::TearDown();
   }
 
   AnnotatorController* annotator_controller() {
     return Shell::Get()->annotator_controller();
   }
 
+  MockAnnotatorObserver& observer() { return observer_; }
+
  protected:
   MockAnnotatorClient client_;
+  MockAnnotatorObserver observer_;
 };
 
 TEST_F(AnnotatorControllerTest, SetAnnotatorTool) {
@@ -122,6 +143,7 @@
   annotator_controller()->RegisterView(Shell::GetPrimaryRootWindow());
   EXPECT_TRUE(annotation_tray->visible_preferred());
 
+  EXPECT_CALL(observer(), OnAnnotatorStateChanged(true));
   annotator_controller()->CreateAnnotationOverlayForWindow(
       Shell::GetPrimaryRootWindow(), std::nullopt);
   annotator_controller()->EnableAnnotatorTool();
@@ -139,6 +161,7 @@
   annotator_controller()->EnableAnnotatorTool();
   EXPECT_FALSE(annotator_controller()->is_annotator_enabled());
 
+  EXPECT_CALL(observer(), OnAnnotatorStateChanged(true));
   // Enables the annotator after creating the view for annotating.
   annotator_controller()->CreateAnnotationOverlayForWindow(
       Shell::GetPrimaryRootWindow(), std::nullopt);
@@ -155,11 +178,13 @@
   annotator_controller()->RegisterView(Shell::GetPrimaryRootWindow());
   EXPECT_TRUE(annotation_tray->visible_preferred());
 
+  EXPECT_CALL(observer(), OnAnnotatorStateChanged(true));
   annotator_controller()->CreateAnnotationOverlayForWindow(
       Shell::GetPrimaryRootWindow(), std::nullopt);
   annotator_controller()->EnableAnnotatorTool();
   EXPECT_TRUE(annotator_controller()->is_annotator_enabled());
 
+  EXPECT_CALL(observer(), OnAnnotatorStateChanged(false));
   annotator_controller()->DisableAnnotator();
   EXPECT_FALSE(annotation_tray->visible_preferred());
   EXPECT_FALSE(annotator_controller()->is_annotator_enabled());
@@ -170,13 +195,15 @@
   base::HistogramTester histogram_tester;
 
   // Enable marker.
+  EXPECT_CALL(observer(), OnAnnotatorStateChanged(true));
   annotator_controller()->CreateAnnotationOverlayForWindow(
       Shell::GetPrimaryRootWindow(), std::nullopt);
   annotator_controller()->EnableAnnotatorTool();
   EXPECT_TRUE(annotator_controller()->is_annotator_enabled());
 
+  EXPECT_CALL(observer(), OnAnnotatorStateChanged(false));
   EXPECT_CALL(client_, Clear());
-  annotator_controller()->ResetTools();
+  annotator_controller()->DisableAnnotator();
   EXPECT_FALSE(annotator_controller()->is_annotator_enabled());
 
   histogram_tester.ExpectUniqueSample(kProjectorToolbarHistogramName,
@@ -425,4 +452,49 @@
   }
 }
 
+TEST_F(AnnotatorControllerTest, AnnotatorNotEnabledWhenNoView) {
+  // Does nothing as there is no view for annotating.
+  annotator_controller()->EnableAnnotatorTool();
+  EXPECT_FALSE(annotator_controller()->is_annotator_enabled());
+
+  // Register view and create annotation overlay.
+  auto* annotation_tray = Shell::GetPrimaryRootWindowController()
+                              ->GetStatusAreaWidget()
+                              ->annotation_tray();
+  annotator_controller()->RegisterView(Shell::GetPrimaryRootWindow());
+  annotator_controller()->CreateAnnotationOverlayForMarkerMode(
+      Shell::GetPrimaryRootWindow());
+  EXPECT_FALSE(annotator_controller()->is_annotator_enabled());
+  EXPECT_FALSE(annotation_tray->GetEnabled());
+  EXPECT_TRUE(annotation_tray->visible_preferred());
+
+  // Annotator not enabled when canvas is not initialized.
+  annotator_controller()->EnableAnnotatorTool();
+  EXPECT_TRUE(annotator_controller()->is_annotator_enabled());
+  EXPECT_FALSE(annotation_tray->GetEnabled());
+  EXPECT_TRUE(annotation_tray->visible_preferred());
+}
+
+TEST_F(AnnotatorControllerTest, VerifyMarkerMode) {
+  // Register view and create annotation overlay.
+  auto* annotation_tray = Shell::GetPrimaryRootWindowController()
+                              ->GetStatusAreaWidget()
+                              ->annotation_tray();
+  annotator_controller()->RegisterView(Shell::GetPrimaryRootWindow());
+  annotator_controller()->CreateAnnotationOverlayForMarkerMode(
+      Shell::GetPrimaryRootWindow());
+  EXPECT_FALSE(annotation_tray->GetEnabled());
+  EXPECT_TRUE(annotation_tray->visible_preferred());
+
+  // Activating marker mode when canvas is initialized.
+  annotator_controller()->OnCanvasInitialized(true);
+  annotator_controller()->EnableAnnotatorTool();
+  EXPECT_TRUE(annotator_controller()->is_annotator_enabled());
+  EXPECT_TRUE(annotation_tray->GetEnabled());
+
+  annotator_controller()->DisableAnnotator();
+  EXPECT_FALSE(annotation_tray->GetEnabled());
+  EXPECT_FALSE(annotation_tray->visible_preferred());
+}
+
 }  // namespace ash
diff --git a/ash/system/palette/palette_tray.cc b/ash/system/palette/palette_tray.cc
index 25a566b3..86d55bec 100644
--- a/ash/system/palette/palette_tray.cc
+++ b/ash/system/palette/palette_tray.cc
@@ -378,10 +378,13 @@
       Shell::Get()->projector_controller();
   projector_session_observation_.Observe(
       projector_controller->projector_session());
+  annotator_controller_observation_.Observe(
+      Shell::Get()->annotator_controller());
 }
 
 void PaletteTray::OnShellDestroying() {
   projector_session_observation_.Reset();
+  annotator_controller_observation_.Reset();
 }
 
 void PaletteTray::OnDidApplyDisplayChanges() {
@@ -498,6 +501,8 @@
 
 void PaletteTray::OnProjectorSessionActiveStateChanged(bool active) {
   is_palette_visibility_paused_ = active;
+  // If the projector session is active, the palette tray should be disabled and
+  // hidden.
   if (active) {
     DeactivateActiveTool();
     SetVisiblePreferred(false);
@@ -506,6 +511,19 @@
   }
 }
 
+void PaletteTray::OnAnnotatorStateChanged(bool enabled) {
+  if (enabled) {
+    // If the annotator is enabled, hide the palette tray. The marker remains
+    // the active tool.
+    SetVisiblePreferred(false);
+  } else {
+    // Once the annotator gets disabled, deactivate the active tool and show the
+    // tray again.
+    DeactivateActiveTool();
+    UpdateIconVisibility();
+  }
+}
+
 void PaletteTray::OnActiveToolChanged() {
   ++num_actions_in_bubble_;
 
diff --git a/ash/system/palette/palette_tray.h b/ash/system/palette/palette_tray.h
index 2adaf83..bdc5101e 100644
--- a/ash/system/palette/palette_tray.h
+++ b/ash/system/palette/palette_tray.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include "ash/annotator/annotator_controller.h"
 #include "ash/ash_export.h"
 #include "ash/public/cpp/projector/projector_session.h"
 #include "ash/public/cpp/session/session_observer.h"
@@ -54,14 +55,15 @@
 // class also controls the lifetime for all of the tools available in the
 // palette. PaletteTray has one instance per-display. It is only made visible if
 // the display has stylus hardware.
-class ASH_EXPORT PaletteTray : public TrayBackgroundView,
+class ASH_EXPORT PaletteTray : public AnnotatorController::AnnotatorObserver,
+                               public display::DisplayManagerObserver,
+                               public PaletteToolManager::Delegate,
+                               public ProjectorSessionObserver,
                                public SessionObserver,
                                public ShelfObserver,
                                public ShellObserver,
-                               public display::DisplayManagerObserver,
-                               public PaletteToolManager::Delegate,
-                               public ui::InputDeviceEventObserver,
-                               public ProjectorSessionObserver {
+                               public TrayBackgroundView,
+                               public ui::InputDeviceEventObserver {
   METADATA_HEADER(PaletteTray, TrayBackgroundView)
 
  public:
@@ -119,6 +121,9 @@
   // ProjectorSessionObserver:
   void OnProjectorSessionActiveStateChanged(bool active) override;
 
+  // AnnotatorObserver:
+  void OnAnnotatorStateChanged(bool enabled) override;
+
  private:
   friend class PaletteTrayTestApi;
   friend class StatusAreaInternalsHandler;
@@ -211,6 +216,8 @@
 
   base::ScopedObservation<ProjectorSession, ProjectorSessionObserver>
       projector_session_observation_{this};
+  base::ScopedObservation<AnnotatorController, AnnotatorObserver>
+      annotator_controller_observation_{this};
 
   ScopedSessionObserver scoped_session_observer_;
 
diff --git a/ash/system/palette/palette_tray_unittest.cc b/ash/system/palette/palette_tray_unittest.cc
index b926add..fd87715 100644
--- a/ash/system/palette/palette_tray_unittest.cc
+++ b/ash/system/palette/palette_tray_unittest.cc
@@ -7,6 +7,10 @@
 #include <memory>
 #include <string>
 
+#include "ash/annotator/annotation_source_watcher.h"
+#include "ash/annotator/annotation_tray.h"
+#include "ash/annotator/annotator_controller.h"
+#include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
 #include "ash/constants/ash_switches.h"
 #include "ash/projector/model/projector_session_impl.h"
@@ -24,6 +28,7 @@
 #include "ash/system/status_area_widget_test_helper.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/test_shell_delegate.h"
+#include "ash/webui/annotator/test/mock_annotator_client.h"
 #include "base/command_line.h"
 #include "base/files/safe_base_name.h"
 #include "base/memory/ptr_util.h"
@@ -828,4 +833,74 @@
   EXPECT_TRUE(palette_tray_->GetVisible());
 }
 
+class PaletteTrayTestWithAnnotator : public PaletteTrayTest {
+ public:
+  PaletteTrayTestWithAnnotator() {
+    scoped_feature_list_.InitAndEnableFeature(ash::features::kAnnotatorMode);
+  }
+
+  PaletteTrayTestWithAnnotator(const PaletteTrayTestWithAnnotator&) = delete;
+  PaletteTrayTestWithAnnotator& operator=(const PaletteTrayTestWithAnnotator&) =
+      delete;
+
+  ~PaletteTrayTestWithAnnotator() override = default;
+
+  // AshTestBase:
+  void SetUp() override {
+    PaletteTrayTest::SetUp();
+    annotator_controller()->SetToolClient(&annotator_client_);
+  }
+
+  AnnotatorController* annotator_controller() {
+    return Shell::Get()->annotator_controller();
+  }
+
+  AnnotationTray* annotation_tray() {
+    return Shell::GetPrimaryRootWindowController()
+        ->GetStatusAreaWidget()
+        ->annotation_tray();
+  }
+
+ protected:
+  base::test::ScopedFeatureList scoped_feature_list_;
+  MockAnnotatorClient annotator_client_;
+};
+
+// Verify that the palette tray behavior in marker mode.
+TEST_F(PaletteTrayTestWithAnnotator,
+       PaletteTrayChangesVisibilityOnAnnotatorChanges) {
+  active_user_pref_service()->SetBoolean(prefs::kEnableStylusTools, true);
+  local_state()->SetBoolean(prefs::kHasSeenStylus, true);
+
+  // Activate laser tool and verify the palette is visible
+  test_api_->palette_tool_manager()->ActivateTool(PaletteToolId::LASER_POINTER);
+  EXPECT_TRUE(palette_tray_->GetVisible());
+  EXPECT_EQ(
+      test_api_->palette_tool_manager()->GetActiveTool(PaletteGroup::MODE),
+      PaletteToolId::LASER_POINTER);
+
+  // Activate marker tool.
+  test_api_->palette_tool_manager()->ActivateTool(PaletteToolId::MARKER_MODE);
+  // Simulate activating marker in the controller.
+  annotator_controller()->OnCanvasInitialized(true);
+  annotator_controller()->EnableAnnotatorTool();
+
+  // Verify annotation tray is shown, palette tray is hidden, and the active
+  // tool is marker mode.
+  EXPECT_FALSE(palette_tray_->GetVisible());
+  EXPECT_EQ(
+      test_api_->palette_tool_manager()->GetActiveTool(PaletteGroup::MODE),
+      PaletteToolId::MARKER_MODE);
+  EXPECT_TRUE(annotation_tray()->visible_preferred());
+
+  // Disable annotator. Verify annotation tray is hidden, palette tray is shown
+  // and the active tool is none.
+  annotator_controller()->DisableAnnotator();
+  EXPECT_FALSE(annotation_tray()->visible_preferred());
+  EXPECT_TRUE(palette_tray_->GetVisible());
+  EXPECT_EQ(
+      test_api_->palette_tool_manager()->GetActiveTool(PaletteGroup::MODE),
+      PaletteToolId::NONE);
+}
+
 }  // namespace ash
diff --git a/ash/system/palette/tools/marker_mode.cc b/ash/system/palette/tools/marker_mode.cc
index 8cee22c..e3763ab 100644
--- a/ash/system/palette/tools/marker_mode.cc
+++ b/ash/system/palette/tools/marker_mode.cc
@@ -79,14 +79,4 @@
   return kPaletteTrayIconProjectorIcon;
 }
 
-// TODO(b/339834202): Consider changing to base class's OnViewClicked() calling
-// a overridable function.
-void MarkerMode::OnViewClicked(views::View* sender) {
-  Shell::Get()
-      ->annotator_controller()
-      ->annotation_source_watcher()
-      ->NotifyMarkerClicked(GetRootWindow());
-  CommonPaletteTool::OnViewClicked(sender);
-}
-
 }  // namespace ash
diff --git a/ash/system/palette/tools/marker_mode.h b/ash/system/palette/tools/marker_mode.h
index 440c4d9a..5c31d71 100644
--- a/ash/system/palette/tools/marker_mode.h
+++ b/ash/system/palette/tools/marker_mode.h
@@ -36,7 +36,6 @@
 
   // CommonPaletteTool:
   const gfx::VectorIcon& GetPaletteIcon() const override;
-  void OnViewClicked(views::View* sender) override;
 };
 
 }  // namespace ash
diff --git a/ash/wm/lock_state_controller.cc b/ash/wm/lock_state_controller.cc
index 8bd8cecc..0c95e7ef 100644
--- a/ash/wm/lock_state_controller.cc
+++ b/ash/wm/lock_state_controller.cc
@@ -180,10 +180,27 @@
                              std::move(delete_image_cb));
 }
 
+bool IsInformedRestoreEnabledForPrimaryUser() {
+  auto* session_controller_impl = Shell::Get()->session_controller();
+  CHECK(session_controller_impl);
+  auto* prefs = session_controller_impl->GetPrimaryUserPrefService();
+  if (!prefs) {
+    // Note: this may be called on the login screen.
+    return false;
+  }
+  return IsAskEveryTime(prefs);
+}
+
 // TODO(minch): Check whether the screenshot should be taken in kiosk mode.
 // Returns true if the informed restore screenshot should be taken on session
 // state changes.
 bool ShouldTakeInformedRestoreScreenshot() {
+  // If the current active user disables the informed restore feature, we should
+  // not take the screenshot.
+  if (!IsInformedRestoreEnabledForPrimaryUser()) {
+    return false;
+  }
+
   auto* shell = Shell::Get();
   // Do not take the informed restore screenshot if it is in overview mode, lock
   // screen, home launcher or pinned mode.
@@ -238,8 +255,10 @@
   if (!has_regular_unminimized_window) {
     RecordScreenshotOnShutdownStatus(
         ScreenshotOnShutdownStatus::kFailedWithNoWindows);
+    return false;
   }
-  return has_regular_unminimized_window;
+
+  return true;
 }
 
 // Hide the cursor and lock the cursor as well if `lock` is true.
diff --git a/ash/wm/lock_state_controller_unittest.cc b/ash/wm/lock_state_controller_unittest.cc
index 39e4d62..dc1f86eb 100644
--- a/ash/wm/lock_state_controller_unittest.cc
+++ b/ash/wm/lock_state_controller_unittest.cc
@@ -11,6 +11,7 @@
 #include "ash/app_list/app_list_controller_impl.h"
 #include "ash/constants/ash_pref_names.h"
 #include "ash/constants/ash_switches.h"
+#include "ash/public/cpp/ash_prefs.h"
 #include "ash/public/cpp/shutdown_controller.h"
 #include "ash/root_window_controller.h"
 #include "ash/session/session_controller_impl.h"
@@ -19,6 +20,7 @@
 #include "ash/system/power/power_button_controller.h"
 #include "ash/system/power/power_button_controller_test_api.h"
 #include "ash/system/power/power_button_test_base.h"
+#include "ash/test/login_info.h"
 #include "ash/touch/touch_devices_controller.h"
 #include "ash/utility/layer_copy_animator.h"
 #include "ash/wallpaper/views/wallpaper_view.h"
@@ -1055,6 +1057,12 @@
     file_path_ = temp_dir_.GetPath().AppendASCII("test_informed_restore.png");
     SetInformedRestoreImagePathForTest(file_path_);
     Initialize(ButtonType::NORMAL, LoginStatus::USER);
+
+    // Although `kAskEveryTime` is the default value, this is needed because
+    // `IsAskEveryTime` checks the pref is explicitly set using `HasPrefPath`.
+    Shell::Get()->session_controller()->GetPrimaryUserPrefService()->SetInteger(
+        prefs::kRestoreAppsAndPagesPrefName,
+        static_cast<int>(full_restore::RestoreOption::kAskEveryTime));
   }
 
   void TearDown() override {
@@ -1335,4 +1343,70 @@
   EXPECT_FALSE(base::PathExists(file_path()));
 }
 
+TEST_F(LockStateControllerInformedRestoreTest,
+       ScreenshotIsTakenIfInformedRestoreIsEnabled) {
+  EXPECT_FALSE(base::PathExists(file_path()));
+
+  // At least one window is needed to trigger screenshot.
+  auto test_window = CreateTestWindow();
+
+  base::RunLoop run_loop;
+  lock_state_test_api_->set_informed_restore_image_callback(
+      run_loop.QuitClosure());
+  // Disable the timeout to avoid test flakiness.
+  lock_state_test_api_->disable_screenshot_timeout_for_test(true);
+
+  lock_state_controller_->RequestSignOut();
+  run_loop.Run();
+  EXPECT_TRUE(base::PathExists(file_path()));
+}
+
+TEST_F(LockStateControllerInformedRestoreTest,
+       ScreenshotIsNotTakenIfFullRestoreIsAlways) {
+  // Create an empty file to simulate an old informed restore image. This should
+  // be removed when screenshot is not taken.
+  ASSERT_TRUE(base::WriteFile(file_path(), ""));
+
+  Shell::Get()->session_controller()->GetPrimaryUserPrefService()->SetInteger(
+      prefs::kRestoreAppsAndPagesPrefName,
+      static_cast<int>(full_restore::RestoreOption::kAlways));
+
+  // At least one window is needed to trigger screenshot.
+  auto test_window = CreateTestWindow();
+
+  base::RunLoop run_loop;
+  lock_state_test_api_->set_informed_restore_image_callback(
+      run_loop.QuitClosure());
+  // Disable the timeout to avoid test flakiness.
+  lock_state_test_api_->disable_screenshot_timeout_for_test(true);
+
+  lock_state_controller_->RequestSignOut();
+  run_loop.Run();
+  EXPECT_FALSE(base::PathExists(file_path()));
+}
+
+TEST_F(LockStateControllerInformedRestoreTest,
+       ScreenshotIsNotTakenIfFullRestoreIsDisabled) {
+  // Create an empty file to simulate an old informed restore image. This should
+  // be removed when screenshot is not taken.
+  ASSERT_TRUE(base::WriteFile(file_path(), ""));
+
+  Shell::Get()->session_controller()->GetPrimaryUserPrefService()->SetInteger(
+      prefs::kRestoreAppsAndPagesPrefName,
+      static_cast<int>(full_restore::RestoreOption::kDoNotRestore));
+
+  // At least one window is needed to trigger screenshot.
+  auto test_window = CreateTestWindow();
+
+  base::RunLoop run_loop;
+  lock_state_test_api_->set_informed_restore_image_callback(
+      run_loop.QuitClosure());
+  // Disable the timeout to avoid test flakiness.
+  lock_state_test_api_->disable_screenshot_timeout_for_test(true);
+
+  lock_state_controller_->RequestSignOut();
+  run_loop.Run();
+  EXPECT_FALSE(base::PathExists(file_path()));
+}
+
 }  // namespace ash
diff --git a/base/files/file_path_watcher_inotify.cc b/base/files/file_path_watcher_inotify.cc
index 4d6d5e9..07ab540c 100644
--- a/base/files/file_path_watcher_inotify.cc
+++ b/base/files/file_path_watcher_inotify.cc
@@ -31,12 +31,12 @@
 #include "base/files/file_util.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
-#include "base/lazy_instance.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
+#include "base/no_destructor.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/synchronization/lock.h"
 #include "base/task/sequenced_task_runner.h"
@@ -56,7 +56,7 @@
 constexpr char kInotifyMaxUserWatchesPath[] =
     "/proc/sys/fs/inotify/max_user_watches";
 
-// This is a soft limit. If there are more than |kExpectedFilePathWatches|
+// This is a soft limit. If there are more than `kExpectedFilePathWatches`
 // FilePathWatchers for a user, than they might affect each other's inotify
 // watchers limit.
 constexpr size_t kExpectedFilePathWatchers = 16u;
@@ -68,7 +68,6 @@
 #endif  // !BUILDFLAG(IS_FUCHSIA)
 
 class FilePathWatcherImpl;
-class InotifyReader;
 
 // Used by test to override inotify watcher limit.
 size_t g_override_max_inotify_watches = 0u;
@@ -127,11 +126,14 @@
   InotifyReader(const InotifyReader&) = delete;
   InotifyReader& operator=(const InotifyReader&) = delete;
 
-  // Watch directory |path| for changes. |watcher| will be notified on each
-  // change. Returns |kInvalidWatch| on failure.
+  // No destructor since it's a singleton that's never destroyed.
+  ~InotifyReader() = delete;
+
+  // Watch directory `path` for changes. `watcher` will be notified on each
+  // change. Returns `kInvalidWatch` on failure.
   Watch AddWatch(const FilePath& path, FilePathWatcherImpl* watcher);
 
-  // Remove |watch| if it's valid.
+  // Remove `watch` if it's valid.
   void RemoveWatch(Watch watch, FilePathWatcherImpl* watcher);
 
   // Invoked on "inotify_reader" thread to notify relevant watchers.
@@ -141,12 +143,9 @@
   bool HasWatches();
 
  private:
-  friend struct LazyInstanceTraitsBase<InotifyReader>;
+  friend class base::NoDestructor<InotifyReader>;
 
   InotifyReader();
-  // There is no destructor because |g_inotify_reader| is a
-  // base::LazyInstace::Leaky object. Having a destructor causes build
-  // issues with GCC 6 (http://crbug.com/636346).
 
   // Returns true on successful thread creation.
   bool StartThread();
@@ -177,12 +176,12 @@
   ~FilePathWatcherImpl() override;
 
   // Called for each event coming from the watch on the original thread.
-  // |fired_watch| identifies the watch that fired, |child| indicates what has
-  // changed, and is relative to the currently watched path for |fired_watch|.
+  // `fired_watch` identifies the watch that fired, `child` indicates what has
+  // changed, and is relative to the currently watched path for `fired_watch`.
   //
-  // |change_info| includes information about the change.
-  // |created| is true if the object appears.
-  // |deleted| is true if the object disappears.
+  // `change_info` includes information about the change.
+  // `created` is true if the object appears.
+  // `deleted` is true if the object disappears.
   void OnFilePathChanged(InotifyReader::Watch fired_watch,
                          const FilePath::StringType& child,
                          FilePathWatcher::ChangeInfo change_info,
@@ -197,13 +196,13 @@
   InotifyReader::WatcherEntry GetWatcherEntry();
 
  private:
-  // Start watching |path| for changes and notify |delegate| on each change.
-  // Returns true if watch for |path| has been added successfully.
+  // Start watching `path` for changes and notify `delegate` on each change.
+  // Returns true if watch for `path` has been added successfully.
   bool Watch(const FilePath& path,
              Type type,
              const FilePathWatcher::Callback& callback) override;
 
-  // A generalized version. It extends |Type|.
+  // A generalized version. It extends `Type`.
   bool WatchWithOptions(const FilePath& path,
                         const WatchOptions& flags,
                         const FilePathWatcher::Callback& callback) override;
@@ -216,12 +215,12 @@
   // Cancel the watch. This unregisters the instance with InotifyReader.
   void Cancel() override;
 
-  // Inotify watches are installed for all directory components of |target_|.
+  // Inotify watches are installed for all directory components of `target_`.
   // A WatchEntry instance holds:
-  // - |watch|: the watch descriptor for a component.
-  // - |subdir|: the subdirectory that identifies the next component.
+  // - `watch`: the watch descriptor for a component.
+  // - `subdir`: the subdirectory that identifies the next component.
   //   - For the last component, there is no next component, so it is empty.
-  // - |linkname|: the target of the symlink.
+  // - `linkname`: the target of the symlink.
   //   - Only if the target being watched is a symbolic link.
   struct WatchEntry {
     explicit WatchEntry(const FilePath::StringType& dirname)
@@ -232,35 +231,35 @@
     FilePath::StringType linkname;
   };
 
-  // Reconfigure to watch for the most specific parent directory of |target_|
+  // Reconfigure to watch for the most specific parent directory of `target_`
   // that exists. Also calls UpdateRecursiveWatches() below. Returns true if
   // watch limit is not hit. Otherwise, returns false.
   [[nodiscard]] bool UpdateWatches();
 
-  // Reconfigure to recursively watch |target_| and all its sub-directories.
+  // Reconfigure to recursively watch `target_` and all its sub-directories.
   // - This is a no-op if the watch is not recursive.
-  // - If |target_| does not exist, then clear all the recursive watches.
-  // - Assuming |target_| exists, passing kInvalidWatch as |fired_watch| forces
-  //   addition of recursive watches for |target_|.
-  // - Otherwise, only the directory associated with |fired_watch| and its
+  // - If `target_` does not exist, then clear all the recursive watches.
+  // - Assuming `target_` exists, passing kInvalidWatch as `fired_watch` forces
+  //   addition of recursive watches for `target_`.
+  // - Otherwise, only the directory associated with `fired_watch` and its
   //   sub-directories will be reconfigured.
   // Returns true if watch limit is not hit. Otherwise, returns false.
   [[nodiscard]] bool UpdateRecursiveWatches(InotifyReader::Watch fired_watch,
                                             bool is_dir);
 
-  // Enumerate recursively through |path| and add / update watches.
+  // Enumerate recursively through `path` and add / update watches.
   // Returns true if watch limit is not hit. Otherwise, returns false.
   [[nodiscard]] bool UpdateRecursiveWatchesForPath(const FilePath& path);
 
-  // Do internal bookkeeping to update mappings between |watch| and its
-  // associated full path |path|.
+  // Do internal bookkeeping to update mappings between `watch` and its
+  // associated full path `path`.
   void TrackWatchForRecursion(InotifyReader::Watch watch, const FilePath& path);
 
   // Remove all the recursive watches.
   void RemoveRecursiveWatches();
 
-  // |path| is a symlink to a non-existent target. Attempt to add a watch to
-  // the link target's parent directory. Update |watch_entry| on success.
+  // `path` is a symlink to a non-existent target. Attempt to add a watch to
+  // the link target's parent directory. Update `watch_entry` on success.
   // Returns true if watch limit is not hit. Otherwise, returns false.
   [[nodiscard]] bool AddWatchForBrokenSymlink(const FilePath& path,
                                               WatchEntry* watch_entry);
@@ -278,7 +277,7 @@
 
   // The vector of watches and next component names for all path components,
   // starting at the root directory. The last entry corresponds to the watch for
-  // |target_| and always stores an empty next component name in |subdir|.
+  // `target_` and always stores an empty next component name in `subdir`.
   std::vector<WatchEntry> watches_;
 
   std::unordered_map<InotifyReader::Watch, FilePath> recursive_paths_by_watch_;
@@ -287,7 +286,10 @@
   WeakPtrFactory<FilePathWatcherImpl> weak_factory_{this};
 };
 
-LazyInstance<InotifyReader>::Leaky g_inotify_reader = LAZY_INSTANCE_INITIALIZER;
+InotifyReader& GetInotifyReader() {
+  static NoDestructor<InotifyReader> instance;
+  return *instance;
+}
 
 void InotifyReaderThreadDelegate::ThreadMain() {
   PlatformThread::SetName("inotify_reader");
@@ -325,7 +327,7 @@
       inotify_event* event = reinterpret_cast<inotify_event*>(&buffer[i]);
       size_t event_size = sizeof(inotify_event) + event->len;
       DUMP_WILL_BE_CHECK_LE(i + event_size, static_cast<size_t>(bytes_read));
-      g_inotify_reader.Get().OnInotifyEvent(event);
+      GetInotifyReader().OnInotifyEvent(event);
       i += event_size;
     }
   }
@@ -346,8 +348,7 @@
 }
 
 bool InotifyReader::StartThread() {
-  // This object is LazyInstance::Leaky, so thread_delegate_ will outlive the
-  // thread.
+  // This object is never deleted, so thread_delegate_ will outlive the thread.
   return PlatformThread::CreateNonJoinable(0, &thread_delegate_);
 }
 
@@ -473,46 +474,46 @@
   // Whether kWatchLimitExceeded is encountered during update.
   bool exceeded_limit = false;
 
-  // Find the entries in |watches_| that correspond to |fired_watch|.
+  // Find the entries in `watches_` that correspond to `fired_watch`.
   for (size_t i = 0; i < watches_.size(); ++i) {
     const WatchEntry& watch_entry = watches_[i];
     if (fired_watch != watch_entry.watch) {
       continue;
     }
 
-    // Check whether a path component of |target_| changed.
+    // Check whether a path component of `target_` changed.
     bool change_on_target_path = child.empty() ||
                                  (child == watch_entry.linkname) ||
                                  (child == watch_entry.subdir);
 
-    // Check if the change references |target_| or a direct child of |target_|.
+    // Check if the change references `target_` or a direct child of `target_`.
     bool target_changed;
     if (watch_entry.subdir.empty()) {
       // The fired watch is for a WatchEntry without a subdir. Thus for a given
-      // |target_| = "/path/to/foo", this is for "foo". Here, check either:
+      // `target_` = "/path/to/foo", this is for "foo". Here, check either:
       // - the target has no symlink: it is the target and it changed.
-      // - the target has a symlink, and it matches |child|.
+      // - the target has a symlink, and it matches `child`.
       target_changed =
           (watch_entry.linkname.empty() || child == watch_entry.linkname);
     } else {
       // The fired watch is for a WatchEntry with a subdir. Thus for a given
-      // |target_| = "/path/to/foo", this is for {"/", "/path", "/path/to"}.
+      // `target_` = "/path/to/foo", this is for {"/", "/path", "/path/to"}.
       // So we can safely access the next WatchEntry since we have not reached
-      // the end yet. Check |watch_entry| is for "/path/to", i.e. the next
+      // the end yet. Check `watch_entry` is for "/path/to", i.e. the next
       // element is "foo".
       bool next_watch_may_be_for_target = watches_[i + 1].subdir.empty();
       if (next_watch_may_be_for_target) {
-        // The current |watch_entry| is for "/path/to", so check if the |child|
+        // The current `watch_entry` is for "/path/to", so check if the `child`
         // that changed is "foo".
         target_changed = watch_entry.subdir == child;
       } else {
-        // The current |watch_entry| is not for "/path/to", so the next entry
-        // cannot be "foo". Thus |target_| has not changed.
+        // The current `watch_entry` is not for "/path/to", so the next entry
+        // cannot be "foo". Thus `target_` has not changed.
         target_changed = false;
       }
     }
 
-    // Update watches if a directory component of the |target_| path
+    // Update watches if a directory component of the `target_` path
     // (dis)appears. Note that we don't add the additional restriction of
     // checking the event mask to see if it is for a directory here as changes
     // to symlinks on the target path will not have IN_ISDIR set in the event
@@ -664,8 +665,9 @@
   set_cancelled();
   callback_.Reset();
 
+  InotifyReader& reader = GetInotifyReader();
   for (const auto& watch : watches_) {
-    g_inotify_reader.Get().RemoveWatch(watch.watch, this);
+    reader.RemoveWatch(watch.watch, this);
   }
   watches_.clear();
   target_.clear();
@@ -684,7 +686,7 @@
     InotifyReader::Watch old_watch = watch_entry.watch;
     watch_entry.watch = InotifyReader::kInvalidWatch;
     watch_entry.linkname.clear();
-    watch_entry.watch = g_inotify_reader.Get().AddWatch(path, this);
+    watch_entry.watch = GetInotifyReader().AddWatch(path, this);
     if (watch_entry.watch == InotifyReader::kWatchLimitExceeded) {
       return false;
     }
@@ -700,7 +702,7 @@
       }
     }
     if (old_watch != watch_entry.watch) {
-      g_inotify_reader.Get().RemoveWatch(old_watch, this);
+      GetInotifyReader().RemoveWatch(old_watch, this);
     }
     path = path.Append(watch_entry.subdir);
   }
@@ -722,14 +724,14 @@
     return true;
   }
 
-  // Check to see if this is a forced update or if some component of |target_|
-  // has changed. For these cases, redo the watches for |target_| and below.
+  // Check to see if this is a forced update or if some component of `target_`
+  // has changed. For these cases, redo the watches for `target_` and below.
   if (!Contains(recursive_paths_by_watch_, fired_watch) &&
       fired_watch != watches_.back().watch) {
     return UpdateRecursiveWatchesForPath(target_);
   }
 
-  // Underneath |target_|, only directory changes trigger watch updates.
+  // Underneath `target_`, only directory changes trigger watch updates.
   if (!is_dir) {
     return true;
   }
@@ -751,17 +753,17 @@
     // a dir with Chrome OS file manager open for the dir). In such case,
     // `cur_dir` under `changed_dir` could exist in this loop but not in
     // the FileEnumerator loop in the upcoming UpdateRecursiveWatchesForPath(),
-    // As a result, `g_inotify_reader` would have an entry in its `watchers_`
+    // As a result, `GetInotifyReader()` would have an entry in its `watchers_`
     // pointing to `this` but `this` is no longer aware of that. Crash in
     // http://crbug/990004 could happen later.
     //
     // Remove the watcher of `cur_path` regardless of whether it exists
-    // or not to keep `this` and `g_inotify_reader` consistent even when the
+    // or not to keep `this` and `GetInotifyReader()` consistent even when the
     // race happens. The watcher will be added back if `cur_path` exists in
     // the FileEnumerator loop in UpdateRecursiveWatchesForPath().
-    g_inotify_reader.Get().RemoveWatch(end_it->second, this);
+    GetInotifyReader().RemoveWatch(end_it->second, this);
 
-    // Keep it in sync with |recursive_watches_by_path_| crbug.com/995196.
+    // Keep it in sync with `recursive_watches_by_path_` crbug.com/995196.
     recursive_paths_by_watch_.erase(end_it->second);
   }
   recursive_watches_by_path_.erase(start_it, end_it);
@@ -797,8 +799,7 @@
     // needs to be an add or update operation.
     if (!Contains(recursive_watches_by_path_, current)) {
       // Try to add new watches.
-      InotifyReader::Watch watch =
-          g_inotify_reader.Get().AddWatch(current, this);
+      InotifyReader::Watch watch = GetInotifyReader().AddWatch(current, this);
       if (watch == InotifyReader::kWatchLimitExceeded) {
         return false;
       }
@@ -815,13 +816,12 @@
       // Update existing watches.
       InotifyReader::Watch old_watch = recursive_watches_by_path_[current];
       DUMP_WILL_BE_CHECK_NE(InotifyReader::kInvalidWatch, old_watch);
-      InotifyReader::Watch watch =
-          g_inotify_reader.Get().AddWatch(current, this);
+      InotifyReader::Watch watch = GetInotifyReader().AddWatch(current, this);
       if (watch == InotifyReader::kWatchLimitExceeded) {
         return false;
       }
       if (watch != old_watch) {
-        g_inotify_reader.Get().RemoveWatch(old_watch, this);
+        GetInotifyReader().RemoveWatch(old_watch, this);
         recursive_paths_by_watch_.erase(old_watch);
         recursive_watches_by_path_.erase(current);
         TrackWatchForRecursion(watch, current);
@@ -852,8 +852,9 @@
     return;
   }
 
+  InotifyReader& reader = GetInotifyReader();
   for (const auto& it : recursive_paths_by_watch_) {
-    g_inotify_reader.Get().RemoveWatch(it.first, this);
+    reader.RemoveWatch(it.first, this);
   }
 
   recursive_paths_by_watch_.clear();
@@ -878,7 +879,7 @@
   // changes to a component "/" which is harmless so no special treatment of
   // this case is required.
   InotifyReader::Watch watch =
-      g_inotify_reader.Get().AddWatch(link->DirName(), this);
+      GetInotifyReader().AddWatch(link->DirName(), this);
   if (watch == InotifyReader::kWatchLimitExceeded) {
     return false;
   }
@@ -949,7 +950,7 @@
 
 // static
 bool FilePathWatcher::HasWatchesForTest() {
-  return g_inotify_reader.Get().HasWatches();
+  return GetInotifyReader().HasWatches();
 }
 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 
diff --git a/base/i18n/break_iterator.cc b/base/i18n/break_iterator.cc
index 4cce46f..739a383 100644
--- a/base/i18n/break_iterator.cc
+++ b/base/i18n/break_iterator.cc
@@ -9,9 +9,9 @@
 #include <ostream>
 #include <string_view>
 
-#include "base/check.h"
-#include "base/lazy_instance.h"
+#include "base/check_op.h"
 #include "base/memory/raw_ptr.h"
+#include "base/no_destructor.h"
 #include "base/notreached.h"
 #include "base/synchronization/lock.h"
 #include "third_party/icu/source/common/unicode/ubrk.h"
@@ -27,7 +27,7 @@
 // also optimize to not create break iterator many time. For each kind of break
 // iterator (character, word, line and sentence, but NOT rule), we keep one of
 // them in the main_ and lease it out. If some other code request a lease
-// before |main_| is returned, we create a new instance of the iterator.
+// before `main_` is returned, we create a new instance of the iterator.
 // This will keep at most 4 break iterators (one for each kind) unreleased until
 // the program destruction time.
 template <UBreakIteratorType break_type>
@@ -80,14 +80,25 @@
   Lock lock_;
 };
 
-static LazyInstance<DefaultLocaleBreakIteratorCache<UBRK_CHARACTER>>::Leaky
-    char_break_cache = LAZY_INSTANCE_INITIALIZER;
-static LazyInstance<DefaultLocaleBreakIteratorCache<UBRK_WORD>>::Leaky
-    word_break_cache = LAZY_INSTANCE_INITIALIZER;
-static LazyInstance<DefaultLocaleBreakIteratorCache<UBRK_SENTENCE>>::Leaky
-    sentence_break_cache = LAZY_INSTANCE_INITIALIZER;
-static LazyInstance<DefaultLocaleBreakIteratorCache<UBRK_LINE>>::Leaky
-    line_break_cache = LAZY_INSTANCE_INITIALIZER;
+DefaultLocaleBreakIteratorCache<UBRK_CHARACTER>& GetCharBreakCache() {
+  static NoDestructor<DefaultLocaleBreakIteratorCache<UBRK_CHARACTER>> cache;
+  return *cache;
+}
+
+DefaultLocaleBreakIteratorCache<UBRK_WORD>& GetWordBreakCache() {
+  static NoDestructor<DefaultLocaleBreakIteratorCache<UBRK_WORD>> cache;
+  return *cache;
+}
+
+DefaultLocaleBreakIteratorCache<UBRK_SENTENCE>& GetSentenceBreakCache() {
+  static NoDestructor<DefaultLocaleBreakIteratorCache<UBRK_SENTENCE>> cache;
+  return *cache;
+}
+
+DefaultLocaleBreakIteratorCache<UBRK_LINE>& GetLineBreakCache() {
+  static NoDestructor<DefaultLocaleBreakIteratorCache<UBRK_LINE>> cache;
+  return *cache;
+}
 
 }  // namespace
 
@@ -109,17 +120,17 @@
     case RULE_BASED:
       return;
     case BREAK_CHARACTER:
-      char_break_cache.Pointer()->Return(std::move(iter_));
+      GetCharBreakCache().Return(std::move(iter_));
       return;
     case BREAK_WORD:
-      word_break_cache.Pointer()->Return(std::move(iter_));
+      GetWordBreakCache().Return(std::move(iter_));
       return;
     case BREAK_SENTENCE:
-      sentence_break_cache.Pointer()->Return(std::move(iter_));
+      GetSentenceBreakCache().Return(std::move(iter_));
       return;
     case BREAK_LINE:
     case BREAK_NEWLINE:
-      line_break_cache.Pointer()->Return(std::move(iter_));
+      GetLineBreakCache().Return(std::move(iter_));
       return;
   }
 }
@@ -129,17 +140,17 @@
   UParseError parse_error;
   switch (break_type_) {
     case BREAK_CHARACTER:
-      iter_ = char_break_cache.Pointer()->Lease(status);
+      iter_ = GetCharBreakCache().Lease(status);
       break;
     case BREAK_WORD:
-      iter_ = word_break_cache.Pointer()->Lease(status);
+      iter_ = GetWordBreakCache().Lease(status);
       break;
     case BREAK_SENTENCE:
-      iter_ = sentence_break_cache.Pointer()->Lease(status);
+      iter_ = GetSentenceBreakCache().Lease(status);
       break;
     case BREAK_LINE:
     case BREAK_NEWLINE:
-      iter_ = line_break_cache.Pointer()->Lease(status);
+      iter_ = GetLineBreakCache().Lease(status);
       break;
     case RULE_BASED:
       iter_ = UBreakIteratorPtr(
diff --git a/base/metrics/histogram_macros_internal.h b/base/metrics/histogram_macros_internal.h
index daa5515..09a9458f 100644
--- a/base/metrics/histogram_macros_internal.h
+++ b/base/metrics/histogram_macros_internal.h
@@ -15,6 +15,7 @@
 #include "base/dcheck_is_on.h"
 #include "base/metrics/histogram.h"
 #include "base/metrics/sparse_histogram.h"
+#include "base/no_destructor.h"
 #include "base/time/time.h"
 #include "base/types/cxx23_to_underlying.h"
 
@@ -56,9 +57,9 @@
 // process.
 
 // In some cases (integration into 3rd party code), it's useful to separate the
-// definition of |atomic_histogram_pointer| from its use. To achieve this we
-// define HISTOGRAM_POINTER_USE, which uses an |atomic_histogram_pointer|, and
-// STATIC_HISTOGRAM_POINTER_BLOCK, which defines an |atomic_histogram_pointer|
+// definition of `atomic_histogram_pointer` from its use. To achieve this we
+// define HISTOGRAM_POINTER_USE, which uses an `atomic_histogram_pointer`, and
+// STATIC_HISTOGRAM_POINTER_BLOCK, which defines an `atomic_histogram_pointer`
 // and forwards to HISTOGRAM_POINTER_USE.
 #define HISTOGRAM_POINTER_USE(                                           \
     atomic_histogram_pointer, constant_histogram_name,                   \
@@ -70,7 +71,7 @@
     if (!histogram_pointer) {                                            \
       /*                                                                 \
        * This is the slow path, which will construct OR find the         \
-       * matching histogram. |histogram_factory_get_invocation| includes \
+       * matching histogram. `histogram_factory_get_invocation` includes \
        * locks on a global histogram name map and is completely thread   \
        * safe.                                                           \
        */                                                                \
@@ -91,7 +92,7 @@
   } while (0)
 
 // This is a helper macro used by other macros and shouldn't be used directly.
-// Defines the static |atomic_histogram_pointer| and forwards to
+// Defines the static `atomic_histogram_pointer` and forwards to
 // HISTOGRAM_POINTER_USE.
 #define STATIC_HISTOGRAM_POINTER_BLOCK(constant_histogram_name,               \
                                        histogram_add_method_invocation,       \
@@ -161,9 +162,8 @@
                                   scale,                                       \
                                   flag) {}                                     \
     };                                                                         \
-    static base::LazyInstance<ScaledLinearHistogramInstance>::Leaky            \
-        scaled_leaky;                                                          \
-    scaled_leaky.Get().AddScaledCount(sample, count);                          \
+    static base::NoDestructor<ScaledLinearHistogramInstance> scaled_leaky;     \
+    scaled_leaky->AddScaledCount(sample, count);                               \
   } while (0)
 
 // Helper for 'overloading' UMA_HISTOGRAM_ENUMERATION with a variable number of
@@ -177,7 +177,7 @@
       base::internal::EnumSizeTraits<std::decay_t<decltype(sample)>>::Count(), \
       flags)
 
-// Note: The value in |sample| must be strictly less than |enum_size|.
+// Note: The value in `sample` must be strictly less than `enum_size`.
 #define INTERNAL_UMA_HISTOGRAM_ENUMERATION_SPECIFY_BOUNDARY(name, sample,     \
                                                             enum_size, flags) \
   INTERNAL_HISTOGRAM_ENUMERATION_WITH_FLAG(name, sample, enum_size, flags)
diff --git a/base/metrics/persistent_histogram_allocator_unittest.cc b/base/metrics/persistent_histogram_allocator_unittest.cc
index 6b5b12e..16cca60 100644
--- a/base/metrics/persistent_histogram_allocator_unittest.cc
+++ b/base/metrics/persistent_histogram_allocator_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "base/compiler_specific.h"
 #include "base/containers/heap_array.h"
+#include "base/debug/leak_annotations.h"
 #include "base/files/file.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
diff --git a/base/metrics/sample_vector.cc b/base/metrics/sample_vector.cc
index 2ac458d4..ffed6e2f 100644
--- a/base/metrics/sample_vector.cc
+++ b/base/metrics/sample_vector.cc
@@ -14,11 +14,11 @@
 #include "base/debug/crash_logging.h"
 #include "base/debug/dump_without_crashing.h"
 #include "base/debug/leak_annotations.h"
-#include "base/lazy_instance.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_span.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/persistent_memory_allocator.h"
+#include "base/no_destructor.h"
 #include "base/notreached.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/strcat.h"
@@ -438,14 +438,14 @@
 }
 
 void SampleVectorBase::MountCountsStorageAndMoveSingleSample() {
-  // There are many SampleVector objects and the lock is needed very
-  // infrequently (just when advancing from single-sample to multi-sample) so
-  // define a single, global lock that all can use. This lock only prevents
-  // concurrent entry into the code below; access and updates to |counts_data_|
-  // still requires atomic operations.
-  static LazyInstance<Lock>::Leaky counts_lock = LAZY_INSTANCE_INITIALIZER;
   if (counts_data_.load(std::memory_order_relaxed) == nullptr) {
-    AutoLock lock(counts_lock.Get());
+    // There are many SampleVector objects and the lock is needed very
+    // infrequently (just when advancing from single-sample to multi-sample) so
+    // define a single, global lock that all can use. This lock only prevents
+    // concurrent entry into the code below; access and updates to
+    // |counts_data_| still requires atomic operations.
+    static base::NoDestructor<Lock> counts_lock;
+    AutoLock lock(*counts_lock);
     if (counts_data_.load(std::memory_order_relaxed) == nullptr) {
       // Create the actual counts storage while the above lock is acquired.
       span<HistogramBase::Count32> counts = CreateCountsStorageWhileLocked();
diff --git a/base/metrics/statistics_recorder.cc b/base/metrics/statistics_recorder.cc
index d30e4c6..20755633 100644
--- a/base/metrics/statistics_recorder.cc
+++ b/base/metrics/statistics_recorder.cc
@@ -19,6 +19,7 @@
 #include "base/metrics/metrics_hashes.h"
 #include "base/metrics/persistent_histogram_allocator.h"
 #include "base/metrics/record_histogram_checker.h"
+#include "base/no_destructor.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
@@ -35,9 +36,6 @@
 }  // namespace
 
 // static
-LazyInstance<Lock>::Leaky StatisticsRecorder::lock_ = LAZY_INSTANCE_INITIALIZER;
-
-// static
 StatisticsRecorder* StatisticsRecorder::top_ = nullptr;
 
 // static
@@ -317,6 +315,17 @@
   InitLogOnShutdownWhileLocked();
 }
 
+// static
+Lock& StatisticsRecorder::GetLock() {
+  static base::NoDestructor<Lock> lock;
+  return *lock;
+}
+
+// static
+void StatisticsRecorder::AssertLockHeld() {
+  GetLock().AssertAcquired();
+}
+
 HistogramBase* StatisticsRecorder::FindHistogramByHashInternal(
     uint64_t hash,
     std::string_view name) const {
diff --git a/base/metrics/statistics_recorder.h b/base/metrics/statistics_recorder.h
index 8b34310..221bec82 100644
--- a/base/metrics/statistics_recorder.h
+++ b/base/metrics/statistics_recorder.h
@@ -22,7 +22,6 @@
 #include "base/base_export.h"
 #include "base/functional/callback.h"
 #include "base/gtest_prod_util.h"
-#include "base/lazy_instance.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/metrics/histogram_base.h"
@@ -320,8 +319,11 @@
   }
 
  private:
-  static Lock& GetLock() { return lock_.Get(); }
-  static void AssertLockHeld() { lock_.Get().AssertAcquired(); }
+  // Global lock for internal synchronization.
+  // Note: Care must be taken to not read or write anything to persistent memory
+  // while holding this lock, as that could cause a file I/O stall.
+  static Lock& GetLock();
+  static void AssertLockHeld();
 
   // Returns the histogram registered with |hash|, if there is one. Returns
   // nullptr otherwise.
@@ -401,11 +403,6 @@
   // Previous global recorder that existed when this one was created.
   raw_ptr<StatisticsRecorder> previous_ = nullptr;
 
-  // Global lock for internal synchronization.
-  // Note: Care must be taken to not read or write anything to persistent memory
-  // while holding this lock, as that could cause a file I/O stall.
-  static LazyInstance<Lock>::Leaky lock_;
-
   // Current global recorder. This recorder is used by static methods. When a
   // new global recorder is created by CreateTemporaryForTesting(), then the
   // previous global recorder is referenced by top_->previous_.
diff --git a/base/task/common/checked_lock_impl.cc b/base/task/common/checked_lock_impl.cc
index 172a754..a457aa6f 100644
--- a/base/task/common/checked_lock_impl.cc
+++ b/base/task/common/checked_lock_impl.cc
@@ -11,9 +11,9 @@
 #include <vector>
 
 #include "base/check_op.h"
-#include "base/lazy_instance.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/raw_ptr_exclusion.h"
+#include "base/no_destructor.h"
 #include "base/synchronization/condition_variable.h"
 #include "base/task/common/checked_lock.h"
 #include "base/threading/platform_thread.h"
@@ -138,8 +138,10 @@
   RAW_PTR_EXCLUSION ThreadLocalOwnedPointer<LockVector> tls_acquired_locks_;
 };
 
-LazyInstance<SafeAcquisitionTracker>::Leaky g_safe_acquisition_tracker =
-    LAZY_INSTANCE_INITIALIZER;
+SafeAcquisitionTracker& GetSafeAcquisitionTracker() {
+  static base::NoDestructor<SafeAcquisitionTracker> tracker;
+  return *tracker;
+}
 
 }  // namespace
 
@@ -147,7 +149,7 @@
 
 CheckedLockImpl::CheckedLockImpl(const CheckedLockImpl* predecessor) {
   DCHECK(predecessor == nullptr || !predecessor->is_universal_successor_);
-  g_safe_acquisition_tracker.Get().RegisterLock(this, predecessor);
+  GetSafeAcquisitionTracker().RegisterLock(this, predecessor);
 }
 
 CheckedLockImpl::CheckedLockImpl(UniversalPredecessor)
@@ -155,25 +157,25 @@
 
 CheckedLockImpl::CheckedLockImpl(UniversalSuccessor)
     : is_universal_successor_(true) {
-  g_safe_acquisition_tracker.Get().RegisterLock(this, nullptr);
+  GetSafeAcquisitionTracker().RegisterLock(this, nullptr);
 }
 
 CheckedLockImpl::~CheckedLockImpl() {
-  g_safe_acquisition_tracker.Get().UnregisterLock(this);
+  GetSafeAcquisitionTracker().UnregisterLock(this);
 }
 
 void CheckedLockImpl::AssertNoLockHeldOnCurrentThread() {
-  g_safe_acquisition_tracker.Get().AssertNoLockHeldOnCurrentThread();
+  GetSafeAcquisitionTracker().AssertNoLockHeldOnCurrentThread();
 }
 
 void CheckedLockImpl::Acquire(subtle::LockTracking tracking) {
   lock_.Acquire(tracking);
-  g_safe_acquisition_tracker.Get().RecordAcquisition(this);
+  GetSafeAcquisitionTracker().RecordAcquisition(this);
 }
 
 void CheckedLockImpl::Release() {
   lock_.Release();
-  g_safe_acquisition_tracker.Get().RecordRelease(this);
+  GetSafeAcquisitionTracker().RecordRelease(this);
 }
 
 void CheckedLockImpl::AssertAcquired() const {
diff --git a/build/android/gyp/nocompile_test.py b/build/android/gyp/nocompile_test.py
index 134986f..0abf0e662 100755
--- a/build/android/gyp/nocompile_test.py
+++ b/build/android/gyp/nocompile_test.py
@@ -12,13 +12,13 @@
 from util import build_utils
 
 _CHROMIUM_SRC = os.path.normpath(os.path.join(__file__, '..', '..', '..', '..'))
-_NINJA_PATH = os.path.join(_CHROMIUM_SRC, 'third_party', 'ninja', 'ninja')
+_SISO_PATH = os.path.join(_CHROMIUM_SRC, 'third_party', 'siso', 'cipd', 'siso')
 
 # Relative to _CHROMIUM_SRC
 _GN_SRC_REL_PATH = os.path.join('buildtools', 'linux64', 'gn')
 
 # Regex for determining whether compile failed because 'gn gen' needs to be run.
-_GN_GEN_REGEX = re.compile(r'ninja: (error|fatal):')
+_GN_GEN_REGEX = re.compile(r'Error: build.ninja not found')
 
 
 def _raise_command_exception(args, returncode, output):
@@ -115,7 +115,7 @@
     ]
     _run_command(gn_args, cwd=_CHROMIUM_SRC)
 
-  ninja_args = [_NINJA_PATH, '-C', options.out_dir, gn_path]
+  ninja_args = [_SISO_PATH, 'ninja', '-C', options.out_dir, gn_path]
   return _run_command_get_failure_output(ninja_args)
 
 
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn
index 5183d752..9d778df8 100644
--- a/build/config/BUILDCONFIG.gn
+++ b/build/config/BUILDCONFIG.gn
@@ -608,9 +608,12 @@
                 ":mac_no_default_new_delete_symbols",
                 "//build/config/compiler:exceptions",
                 "//build/config/compiler:rtti",
-              ]) != []) {
-        # Exceptions and RTTI flags are incompatible with libc++ modules build.
-        # So disable modules build for such targets.
+              ]) != [] ||
+          filter_include(configs,
+                         [ "//build/config/compiler:no_exceptions" ]) == []) {
+        # Exceptions (i.e. if the 'no_exceptions' config is not used) and RTTI
+        # flags are incompatible with libc++ modules build. So disable modules
+        # build for such targets.
         use_libcxx_modules = false
       }
 
@@ -737,9 +740,12 @@
                 ":mac_no_default_new_delete_symbols",
                 "//build/config/compiler:exceptions",
                 "//build/config/compiler:rtti",
-              ]) != []) {
-        # Exceptions and RTTI flags are incompatible with libc++ modules build.
-        # So disable modules build for such targets.
+              ]) != [] ||
+          filter_include(configs,
+                         [ "//build/config/compiler:no_exceptions" ]) == []) {
+        # Exceptions (i.e. if the 'no_exceptions' config is not used) and RTTI
+        # flags are incompatible with libc++ modules build. So disable modules
+        # build for such targets.
         use_libcxx_modules = false
       }
 
diff --git a/build/config/siso/clang_exception.star b/build/config/siso/clang_exception.star
index 11cf5bf..eaf7171 100644
--- a/build/config/siso/clang_exception.star
+++ b/build/config/siso/clang_exception.star
@@ -52,16 +52,20 @@
             "name": "slow_compile",
             "action_outs": [
                 # keep-sorted start
+                "./obj/content/browser/browser/browser_interface_binders.o",
                 "./obj/content/test/content_browsertests/interest_group_browsertest.o",
                 "./obj/content/test/content_browsertests/navigation_controller_impl_browsertest.o",
+                "./obj/content/test/content_browsertests/prerender_browsertest.o",
                 "./obj/content/test/content_browsertests/site_per_process_browsertest.o",
                 "./obj/content/test/content_unittests/auction_runner_unittest.o",
                 "./obj/third_party/abseil-cpp/absl/functional/any_invocable_test/any_invocable_test.o",
+                "./obj/third_party/highway/highway_tests/cast_test.o",
                 "./obj/third_party/highway/highway_tests/convert_test.o",
                 "./obj/third_party/highway/highway_tests/demote_test.o",
                 "./obj/third_party/highway/highway_tests/div_test.o",
                 "./obj/third_party/highway/highway_tests/if_test.o",
                 "./obj/third_party/highway/highway_tests/interleaved_test.o",
+                "./obj/third_party/highway/highway_tests/logical_test.o",
                 "./obj/third_party/highway/highway_tests/mask_mem_test.o",
                 "./obj/third_party/highway/highway_tests/mask_test.o",
                 "./obj/third_party/highway/highway_tests/masked_arithmetic_test.o",
diff --git a/chrome/VERSION b/chrome/VERSION
index 87b999d12..296e55d 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=140
 MINOR=0
-BUILD=7325
+BUILD=7326
 PATCH=0
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni
index ea0efd4..dc2af2eb 100644
--- a/chrome/android/chrome_java_resources.gni
+++ b/chrome/android/chrome_java_resources.gni
@@ -539,7 +539,6 @@
   "java/res/layout/other_forms_of_history_dialog.xml",
   "java/res/layout/password_manager_dialog.xml",
   "java/res/layout/password_manager_dialog_with_help_button.xml",
-  "java/res/layout/password_no_result.xml",
   "java/res/layout/powered_by_chrome_footer.xml",
   "java/res/layout/radio_button_group_homepage_preference.xml",
   "java/res/layout/reader_mode_bottom_sheet.xml",
@@ -579,7 +578,6 @@
   "java/res/menu/bookmark_folder_picker_menu.xml",
   "java/res/menu/bookmark_toolbar_menu_improved.xml",
   "java/res/menu/history_manager_menu.xml",
-  "java/res/menu/save_password_preferences_action_bar_menu.xml",
   "java/res/raw/composeplate_loop_dark.json",
   "java/res/raw/composeplate_loop_light.json",
   "java/res/transition/fade.xml",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index 4649fe4..7edb986 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -856,8 +856,6 @@
   "java/src/org/chromium/chrome/browser/password_manager/PasswordManagerDialogViewBinder.java",
   "java/src/org/chromium/chrome/browser/password_manager/PasswordManagerErrorMessageHelperBridge.java",
   "java/src/org/chromium/chrome/browser/password_manager/PasswordManagerLauncher.java",
-  "java/src/org/chromium/chrome/browser/password_manager/settings/ManualCallbackDelayer.java",
-  "java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java",
   "java/src/org/chromium/chrome/browser/payments/AddressEditor.java",
   "java/src/org/chromium/chrome/browser/payments/AutofillContact.java",
   "java/src/org/chromium/chrome/browser/payments/ChromePaymentRequestFactory.java",
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponentBridge.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponentBridge.java
index f46fb62..e939e24 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponentBridge.java
+++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponentBridge.java
@@ -189,6 +189,8 @@
             callback =
                     (field) -> {
                         assert mNativeView != 0 : "Controller was destroyed but the bridge wasn't!";
+                        ManualFillingMetricsRecorder.recordActionSelected(
+                                AccessoryAction.AUTOFILL_SUGGESTION_FROM_ACCESSORY_SHEET);
                         ManualFillingMetricsRecorder.recordSuggestionSelected(
                                 sheetType, suggestionType);
                         ManualFillingComponentBridgeJni.get()
@@ -219,6 +221,8 @@
         Callback<UserInfoField> callback =
                 (field) -> {
                     assert mNativeView != 0 : "Controller was destroyed but the bridge wasn't!";
+                    ManualFillingMetricsRecorder.recordActionSelected(
+                            AccessoryAction.AUTOFILL_SUGGESTION_FROM_ACCESSORY_SHEET);
                     ManualFillingMetricsRecorder.recordSuggestionSelected(
                             sheetType, suggestionType);
                     ManualFillingComponentBridgeJni.get()
@@ -274,6 +278,8 @@
         Callback<UserInfoField> callback =
                 (field) -> {
                     assert mNativeView != 0 : "Controller was destroyed but the bridge wasn't!";
+                    ManualFillingMetricsRecorder.recordActionSelected(
+                            AccessoryAction.AUTOFILL_SUGGESTION_FROM_ACCESSORY_SHEET);
                     ManualFillingMetricsRecorder.recordSuggestionSelected(
                             sheetType, suggestionType);
                     ManualFillingComponentBridgeJni.get()
@@ -333,6 +339,8 @@
         Callback<UserInfoField> callback =
                 (field) -> {
                     assert mNativeView != 0 : "Controller was destroyed but the bridge wasn't!";
+                    ManualFillingMetricsRecorder.recordActionSelected(
+                            AccessoryAction.AUTOFILL_SUGGESTION_FROM_ACCESSORY_SHEET);
                     ManualFillingMetricsRecorder.recordSuggestionSelected(
                             sheetType, suggestionType);
                     ManualFillingComponentBridgeJni.get()
diff --git a/chrome/android/java/res/layout/password_no_result.xml b/chrome/android/java/res/layout/password_no_result.xml
deleted file mode 100644
index 91b0d4e4..0000000
--- a/chrome/android/java/res/layout/password_no_result.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-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.
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-    <org.chromium.components.browser_ui.widget.MaterialCardViewNoShadow
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:layout_marginStart="16dp"
-        android:layout_marginEnd="16dp"
-        android:foreground="@drawable/button_borderless_compat"
-        style="@style/MaterialCardStyle">
-
-        <org.chromium.ui.widget.TextViewWithLeading
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:padding="@dimen/card_padding"
-            android:text="@string/password_no_result"
-            android:textAlignment="center"
-            android:textAppearance="@style/TextAppearance.TextMedium.Secondary"
-            app:leading="@dimen/text_size_medium_leading" />
-
-    </org.chromium.components.browser_ui.widget.MaterialCardViewNoShadow>
-
-</FrameLayout>
diff --git a/chrome/android/java/res/menu/save_password_preferences_action_bar_menu.xml b/chrome/android/java/res/menu/save_password_preferences_action_bar_menu.xml
deleted file mode 100644
index 36fa645..0000000
--- a/chrome/android/java/res/menu/save_password_preferences_action_bar_menu.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright 2017 The Chromium Authors
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
--->
-
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto" >
-
-    <item
-        android:id="@+id/menu_id_search"
-        android:icon="@drawable/ic_search"
-        android:title="@string/search"
-        app:showAsAction="always"
-        app:actionViewClass="androidx.appcompat.widget.SearchView" />
-
-    <item
-        android:id="@id/menu_id_targeted_help"
-        android:icon="@drawable/ic_help_and_feedback"
-        android:title="@string/menu_help"
-        app:showAsAction="ifRoom"/>
-
-    <item
-        android:id="@+id/export_passwords"
-        android:title="@string/password_settings_export_action_title"
-        android:contentDescription="@string/password_settings_export_action_description"
-        app:showAsAction="never"/>
-</menu>
diff --git a/chrome/android/java/res/xml/main_preferences.xml b/chrome/android/java/res/xml/main_preferences.xml
index f032c32..3354344 100644
--- a/chrome/android/java/res/xml/main_preferences.xml
+++ b/chrome/android/java/res/xml/main_preferences.xml
@@ -70,7 +70,6 @@
         android:order="11"
         android:title="@string/prefs_section_autofill"/>
     <org.chromium.chrome.browser.password_manager.settings.PasswordsPreference
-        android:fragment="org.chromium.chrome.browser.password_manager.settings.PasswordSettings"
         android:key="passwords"
         android:order="12"
         android:title="@string/password_manager_settings_title"/>
diff --git a/chrome/android/java/res/xml/main_preferences_legacy.xml b/chrome/android/java/res/xml/main_preferences_legacy.xml
index a048f0a..58e53f0 100644
--- a/chrome/android/java/res/xml/main_preferences_legacy.xml
+++ b/chrome/android/java/res/xml/main_preferences_legacy.xml
@@ -51,7 +51,6 @@
         android:order="7"
         android:title="@string/address_bar_settings"/>
     <org.chromium.chrome.browser.password_manager.settings.PasswordsPreference
-        android:fragment="org.chromium.chrome.browser.password_manager.settings.PasswordSettings"
         android:key="passwords"
         android:order="8"
         android:title="@string/password_manager_settings_title"/>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
index 207554f..e54d8bc 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -43,7 +43,6 @@
 import org.chromium.base.CallbackUtils;
 import org.chromium.base.CommandLine;
 import org.chromium.base.ContextUtils;
-import org.chromium.base.DeviceInfo;
 import org.chromium.base.InputHintChecker;
 import org.chromium.base.Log;
 import org.chromium.base.PowerMonitor;
@@ -2636,7 +2635,7 @@
             return true;
         }
 
-        if (id == R.id.dev_tools && DeviceInfo.isDesktop()) {
+        if (id == R.id.dev_tools) {
             DevToolsWindowAndroid.openDevTools(currentTab.getWebContents());
             return true;
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
index 482c138..a81964b2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -96,6 +96,7 @@
 import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
 import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
 import org.chromium.ui.modelutil.PropertyModel;
+import org.chromium.ui.mojom.MenuSourceType;
 import org.chromium.ui.widget.Toast;
 import org.chromium.url.GURL;
 
@@ -386,11 +387,11 @@
 
     @VisibleForTesting
     boolean shouldShowEmptySpaceContextMenu() {
-        // Enable empty space context menu for large screen devices, and devices
-        // (with any screen size) with input periperals attached.
-        return (DeviceFormFactor.isNonMultiDisplayContextOnTablet(mContext)
-                        || (DeviceInput.supportsPrecisionPointer()
-                                && DeviceInput.supportsKeyboard()))
+        // Enable empty space context menu from mouse-right click on all device form factors, while
+        // long press (touch) should only work for large screen devices (crbug.com/429262357).
+        return (mParams.getSourceType() == MenuSourceType.MOUSE
+                     || (DeviceFormFactor.isNonMultiDisplayContextOnTablet(mContext)
+                         && mParams.getSourceType() == MenuSourceType.LONG_PRESS))
                 && ChromeFeatureList.isEnabled(ChromeFeatureList.CONTEXT_MENU_EMPTY_SPACE);
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadMessageBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadMessageBridge.java
index 82dbe61a..81cf2f80 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadMessageBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadMessageBridge.java
@@ -9,8 +9,8 @@
 import android.content.Context;
 
 import org.jni_zero.CalledByNative;
-import org.jni_zero.NativeMethods;
 
+import org.chromium.base.JniOnceCallback;
 import org.chromium.build.annotations.NullMarked;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar;
@@ -20,35 +20,16 @@
 
 @NullMarked
 public class DownloadMessageBridge {
-    private long mNativeDownloadMessageBridge;
-
-    /**
-     * Constructor, taking a pointer to the native instance.
-     *
-     * @param nativeDownloadMessageBridge Pointer to the native object.
-     */
-    public DownloadMessageBridge(long nativeDownloadMessageBridge) {
-        mNativeDownloadMessageBridge = nativeDownloadMessageBridge;
-    }
-
     @CalledByNative
-    public static DownloadMessageBridge create(long nativeDialog) {
-        return new DownloadMessageBridge(nativeDialog);
-    }
-
-    @CalledByNative
-    public void showIncognitoDownloadMessage(long callbackId) {
+    public static void showIncognitoDownloadMessage(JniOnceCallback<Boolean> callback) {
         DownloadMessageUiController messageUiController =
                 DownloadManagerService.getDownloadManagerService()
                         .getMessageUiController(/* otrProfileId= */ null);
-        messageUiController.showIncognitoDownloadMessage(
-                (accepted) -> {
-                    onConfirmed(callbackId, accepted);
-                });
+        messageUiController.showIncognitoDownloadMessage(callback);
     }
 
     @CalledByNative
-    public void showUnsupportedDownloadMessage(WindowAndroid window) {
+    public static void showUnsupportedDownloadMessage(WindowAndroid window) {
         SnackbarManager snackbarManager = SnackbarManagerProvider.from(window);
         if (snackbarManager == null) return;
 
@@ -64,21 +45,4 @@
         snackbar.setSingleLine(false);
         snackbarManager.showSnackbar(snackbar);
     }
-
-    @CalledByNative
-    private void destroy() {
-        mNativeDownloadMessageBridge = 0;
-    }
-
-    private void onConfirmed(long callbackId, boolean accepted) {
-        if (mNativeDownloadMessageBridge != 0) {
-            DownloadMessageBridgeJni.get()
-                    .onConfirmed(mNativeDownloadMessageBridge, callbackId, accepted);
-        }
-    }
-
-    @NativeMethods
-    interface Natives {
-        void onConfirmed(long nativeDownloadMessageBridge, long callbackId, boolean accepted);
-    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java
deleted file mode 100644
index 5de34e2..0000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java
+++ /dev/null
@@ -1,768 +0,0 @@
-// Copyright 2014 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.password_manager.settings;
-
-import static org.chromium.build.NullUtil.assumeNonNull;
-import static org.chromium.chrome.browser.password_manager.PasswordMetricsUtil.PASSWORD_SETTINGS_EXPORT_METRICS_ID;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.text.SpannableString;
-import android.text.style.ForegroundColorSpan;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.StringRes;
-import androidx.appcompat.widget.Toolbar;
-import androidx.fragment.app.FragmentManager;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceGroup;
-
-import org.chromium.base.BuildInfo;
-import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.base.supplier.ObservableSupplier;
-import org.chromium.base.supplier.ObservableSupplierImpl;
-import org.chromium.build.annotations.NullMarked;
-import org.chromium.build.annotations.Nullable;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.password_check.PasswordCheck;
-import org.chromium.chrome.browser.password_check.PasswordCheckFactory;
-import org.chromium.chrome.browser.password_manager.ManagePasswordsReferrer;
-import org.chromium.chrome.browser.password_manager.PasswordCheckReferrer;
-import org.chromium.chrome.browser.password_manager.PasswordManagerHelper;
-import org.chromium.chrome.browser.preferences.Pref;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.settings.ChromeBaseSettingsFragment;
-import org.chromium.chrome.browser.settings.ChromeManagedPreferenceDelegate;
-import org.chromium.chrome.browser.sync.SyncServiceFactory;
-import org.chromium.chrome.browser.sync.settings.SyncSettingsUtils;
-import org.chromium.components.browser_ui.settings.ChromeBasePreference;
-import org.chromium.components.browser_ui.settings.ChromeSwitchPreference;
-import org.chromium.components.browser_ui.settings.SearchUtils;
-import org.chromium.components.browser_ui.settings.TextMessagePreference;
-import org.chromium.components.browser_ui.styles.SemanticColorUtils;
-import org.chromium.components.prefs.PrefService;
-import org.chromium.components.signin.base.CoreAccountInfo;
-import org.chromium.components.sync.PassphraseType;
-import org.chromium.components.sync.SyncService;
-import org.chromium.components.user_prefs.UserPrefs;
-import org.chromium.ui.text.SpanApplier;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Locale;
-
-/**
- * The "Passwords" screen in Settings, which allows the user to enable or disable password saving,
- * to view saved passwords (just the username and URL), and to delete saved passwords.
- *
- * <p>TODO: crbug.com/372657804 - Make sure that the PasswordSettings is not created in UPM M4.1
- */
-@NullMarked
-public class PasswordSettings extends ChromeBaseSettingsFragment
-        implements PasswordListObserver,
-                Preference.OnPreferenceClickListener,
-                SyncService.SyncStateChangedListener {
-    @IntDef({
-        TrustedVaultBannerState.NOT_SHOWN,
-        TrustedVaultBannerState.OFFER_OPT_IN,
-        TrustedVaultBannerState.OPTED_IN
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    private @interface TrustedVaultBannerState {
-        int NOT_SHOWN = 0;
-        int OFFER_OPT_IN = 1;
-        int OPTED_IN = 2;
-    }
-
-    // Keys for name/password dictionaries.
-    public static final String PASSWORD_LIST_URL = "url";
-    public static final String PASSWORD_LIST_NAME = "name";
-    public static final String PASSWORD_LIST_PASSWORD = "password";
-
-    // Used to pass the password id into a new activity.
-    public static final String PASSWORD_LIST_ID = "id";
-
-    // The key for saving |mSearchQuery| to instance bundle.
-    private static final String SAVED_STATE_SEARCH_QUERY = "saved-state-search-query";
-
-    public static final String PREF_SAVE_PASSWORDS_SWITCH = "save_passwords_switch";
-    public static final String PREF_AUTOSIGNIN_SWITCH = "autosignin_switch";
-    public static final String PREF_CHECK_PASSWORDS = "check_passwords";
-    public static final String PREF_TRUSTED_VAULT_BANNER = "trusted_vault_banner";
-    public static final String PREF_KEY_MANAGE_ACCOUNT_LINK = "manage_account_link";
-
-    private static final String PREF_KEY_CATEGORY_SAVED_PASSWORDS = "saved_passwords";
-    private static final String PREF_KEY_CATEGORY_EXCEPTIONS = "exceptions";
-    private static final String PREF_KEY_SAVED_PASSWORDS_NO_TEXT = "saved_passwords_no_text";
-
-    private static final int ORDER_SWITCH = 0;
-    private static final int ORDER_AUTO_SIGNIN_CHECKBOX = 1;
-    private static final int ORDER_CHECK_PASSWORDS = 2;
-    private static final int ORDER_TRUSTED_VAULT_BANNER = 3;
-    private static final int ORDER_MANAGE_ACCOUNT_LINK = 4;
-    private static final int ORDER_SAVED_PASSWORDS = 6;
-    private static final int ORDER_EXCEPTIONS = 7;
-    private static final int ORDER_SAVED_PASSWORDS_NO_TEXT = 8;
-
-    // This request code is not actually consumed today in onActivityResult() but is defined here to
-    // avoid bugs in the future if the request code is reused.
-    private static final int REQUEST_CODE_TRUSTED_VAULT_OPT_IN = 1;
-
-    // Unique request code for the password exporting activity.
-    private static final int PASSWORD_EXPORT_INTENT_REQUEST_CODE = 3485764;
-
-    private boolean mNoPasswords;
-    private boolean mNoPasswordExceptions;
-    private @TrustedVaultBannerState int mTrustedVaultBannerState =
-            TrustedVaultBannerState.NOT_SHOWN;
-
-    private @Nullable MenuItem mHelpItem;
-    private @Nullable MenuItem mSearchItem;
-
-    private @Nullable String mSearchQuery;
-    private @Nullable Preference mLinkPref;
-    private @Nullable Menu mMenu;
-
-    private @Nullable PasswordCheck mPasswordCheck;
-    private @ManagePasswordsReferrer int mManagePasswordsReferrer;
-    private final ObservableSupplierImpl<String> mPageTitle = new ObservableSupplierImpl<>();
-
-    /** For controlling the UX flow of exporting passwords. */
-    private final ExportFlow mExportFlow = new ExportFlow();
-
-    public ExportFlow getExportFlowForTesting() {
-        return mExportFlow;
-    }
-
-    @Override
-    public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) {
-        mExportFlow.onCreate(
-                savedInstanceState,
-                new ExportFlow.Delegate() {
-                    @Override
-                    public Activity getActivity() {
-                        return PasswordSettings.this.getActivity();
-                    }
-
-                    @Override
-                    public FragmentManager getFragmentManager() {
-                        FragmentManager fragmentManager =
-                                PasswordSettings.this.getFragmentManager();
-                        assert fragmentManager != null;
-                        return fragmentManager;
-                    }
-
-                    @Override
-                    public int getViewId() {
-                        View view = getView();
-                        assert view != null;
-                        return view.getId();
-                    }
-
-                    @Override
-                    public void runCreateFileOnDiskIntent(Intent intent) {
-                        startActivityForResult(intent, PASSWORD_EXPORT_INTENT_REQUEST_CODE);
-                    }
-
-                    @Override
-                    public Profile getProfile() {
-                        return PasswordSettings.this.getProfile();
-                    }
-                },
-                PASSWORD_SETTINGS_EXPORT_METRICS_ID);
-        mPageTitle.set(getString(R.string.password_manager_settings_title));
-        setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getStyledContext()));
-        PasswordManagerHandlerProvider.getForProfile(getProfile()).addObserver(this);
-
-        SyncService syncService = SyncServiceFactory.getForProfile(getProfile());
-        if (syncService != null) {
-            syncService.addSyncStateChangedListener(this);
-        }
-
-        setHasOptionsMenu(true); // Password Export might be optional but Search is always present.
-
-        mManagePasswordsReferrer = getReferrerFromInstanceStateOrLaunchBundle(savedInstanceState);
-
-        if (savedInstanceState == null) return;
-
-        if (savedInstanceState.containsKey(SAVED_STATE_SEARCH_QUERY)) {
-            mSearchQuery = savedInstanceState.getString(SAVED_STATE_SEARCH_QUERY);
-        }
-    }
-
-    @Override
-    public ObservableSupplier<String> getPageTitle() {
-        return mPageTitle;
-    }
-
-    private @ManagePasswordsReferrer int getReferrerFromInstanceStateOrLaunchBundle(
-            @Nullable Bundle savedInstanceState) {
-        if (savedInstanceState != null
-                && savedInstanceState.containsKey(
-                        PasswordManagerHelper.MANAGE_PASSWORDS_REFERRER)) {
-            return savedInstanceState.getInt(PasswordManagerHelper.MANAGE_PASSWORDS_REFERRER);
-        }
-        Bundle extras = getArguments();
-        assert extras.containsKey(PasswordManagerHelper.MANAGE_PASSWORDS_REFERRER)
-                : "PasswordSettings must be launched with a manage-passwords-referrer fragment"
-                        + "argument, but none was provided.";
-        return extras.getInt(PasswordManagerHelper.MANAGE_PASSWORDS_REFERRER);
-    }
-
-    @Override
-    public void onCreate(@Nullable Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        mPasswordCheck = PasswordCheckFactory.getOrCreate();
-        computeTrustedVaultBannerState();
-    }
-
-    @Override
-    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-
-        // Disable animations of preference changes.
-        getListView().setItemAnimator(null);
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        menu.clear();
-        mMenu = menu;
-        inflater.inflate(R.menu.save_password_preferences_action_bar_menu, menu);
-        menu.findItem(R.id.export_passwords).setVisible(ExportFlow.providesPasswordExport());
-        menu.findItem(R.id.export_passwords).setEnabled(false);
-        mSearchItem = menu.findItem(R.id.menu_id_search);
-        mSearchItem.setVisible(true);
-        mHelpItem = menu.findItem(R.id.menu_id_targeted_help);
-        SearchUtils.initializeSearchView(
-                mSearchItem, mSearchQuery, getActivity(), this::filterPasswords);
-    }
-
-    @Override
-    public void onPrepareOptionsMenu(Menu menu) {
-        menu.findItem(R.id.export_passwords).setEnabled(!mNoPasswords && !mExportFlow.isActive());
-        super.onPrepareOptionsMenu(menu);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        int id = item.getItemId();
-        if (id == R.id.export_passwords) {
-            RecordHistogram.recordEnumeratedHistogram(
-                    mExportFlow.getExportEventHistogramName(),
-                    ExportFlow.PasswordExportEvent.EXPORT_OPTION_SELECTED,
-                    ExportFlow.PasswordExportEvent.COUNT);
-            mExportFlow.startExporting();
-            return true;
-        }
-
-        assumeNonNull(mSearchItem);
-        if (SearchUtils.handleSearchNavigation(item, mSearchItem, mSearchQuery, getActivity())) {
-            filterPasswords(/* query= */ null);
-            return true;
-        }
-        if (id == R.id.menu_id_targeted_help) {
-            getHelpAndFeedbackLauncher()
-                    .show(getActivity(), getString(R.string.help_context_passwords), null);
-            return true;
-        }
-        return super.onOptionsItemSelected(item);
-    }
-
-    private void filterPasswords(@Nullable String query) {
-        assert mHelpItem != null;
-
-        mSearchQuery = query;
-        mHelpItem.setShowAsAction(
-                mSearchQuery == null
-                        ? MenuItem.SHOW_AS_ACTION_IF_ROOM
-                        : MenuItem.SHOW_AS_ACTION_NEVER);
-        rebuildPasswordLists();
-    }
-
-    /** Empty screen message when no passwords or exceptions are stored. */
-    private void displayEmptyScreenMessage() {
-        TextMessagePreference emptyView = new TextMessagePreference(getStyledContext(), null);
-        emptyView.setSummary(R.string.saved_passwords_none_text);
-        emptyView.setKey(PREF_KEY_SAVED_PASSWORDS_NO_TEXT);
-        emptyView.setOrder(ORDER_SAVED_PASSWORDS_NO_TEXT);
-        emptyView.setDividerAllowedAbove(false);
-        emptyView.setDividerAllowedBelow(false);
-        getPreferenceScreen().addPreference(emptyView);
-    }
-
-    /** Include a message when there's no match. */
-    private void displayPasswordNoResultScreenMessage() {
-        Preference noResultView = new Preference(getStyledContext());
-        noResultView.setLayoutResource(R.layout.password_no_result);
-        noResultView.setSelectable(false);
-        getPreferenceScreen().addPreference(noResultView);
-    }
-
-    @Override
-    public void onDetach() {
-        super.onDetach();
-        ReauthenticationManager.resetLastReauth();
-    }
-
-    void rebuildPasswordLists() {
-        mNoPasswords = false;
-        mNoPasswordExceptions = false;
-        getPreferenceScreen().removeAll();
-        PasswordManagerHandlerProvider passwordManagerHandlerProvider =
-                PasswordManagerHandlerProvider.getForProfile(getProfile());
-        assert passwordManagerHandlerProvider != null;
-        PasswordManagerHandler passwordManagerHandler =
-                passwordManagerHandlerProvider.getPasswordManagerHandler();
-        assert passwordManagerHandler != null;
-        if (mSearchQuery != null) {
-            // Only the filtered passwords and exceptions should be shown.
-            passwordManagerHandler.updatePasswordLists();
-            return;
-        }
-
-        createSavePasswordsSwitch();
-        if (shouldShowAutoSigninOption()) {
-            createAutoSignInCheckbox();
-        }
-        if (mPasswordCheck != null) {
-            createCheckPasswords();
-        }
-
-        if (mTrustedVaultBannerState == TrustedVaultBannerState.OPTED_IN) {
-            createTrustedVaultBanner(
-                    R.string.android_trusted_vault_banner_sub_label_opted_in,
-                    this::openTrustedVaultInfoPage);
-        } else if (mTrustedVaultBannerState == TrustedVaultBannerState.OFFER_OPT_IN) {
-            createTrustedVaultBanner(
-                    R.string.android_trusted_vault_banner_sub_label_offer_opt_in,
-                    this::openTrustedVaultOptInDialog);
-        }
-        passwordManagerHandler.updatePasswordLists();
-    }
-
-    private boolean shouldShowAutoSigninOption() {
-        return !BuildInfo.getInstance().isAutomotive;
-    }
-
-    /**
-     * Removes the UI displaying the list of saved passwords or exceptions.
-     * @param preferenceCategoryKey The key string identifying the PreferenceCategory to be removed.
-     */
-    private void resetList(String preferenceCategoryKey) {
-        PreferenceCategory profileCategory =
-                (PreferenceCategory) getPreferenceScreen().findPreference(preferenceCategoryKey);
-        if (profileCategory != null) {
-            profileCategory.removeAll();
-            getPreferenceScreen().removePreference(profileCategory);
-        }
-    }
-
-    /** Removes the message informing the user that there are no saved entries to display. */
-    private void resetNoEntriesTextMessage() {
-        Preference message = getPreferenceScreen().findPreference(PREF_KEY_SAVED_PASSWORDS_NO_TEXT);
-        if (message != null) {
-            getPreferenceScreen().removePreference(message);
-        }
-    }
-
-    @Override
-    public void passwordListAvailable(int count) {
-        resetList(PREF_KEY_CATEGORY_SAVED_PASSWORDS);
-        resetNoEntriesTextMessage();
-
-        mNoPasswords = count == 0;
-        if (mNoPasswords) {
-            if (mNoPasswordExceptions) displayEmptyScreenMessage();
-            return;
-        }
-
-        displayManageAccountLink();
-
-        PreferenceGroup passwordParent;
-        if (mSearchQuery == null) {
-            PreferenceCategory profileCategory = new PreferenceCategory(getStyledContext());
-            profileCategory.setKey(PREF_KEY_CATEGORY_SAVED_PASSWORDS);
-            profileCategory.setTitle(R.string.password_list_title);
-            profileCategory.setOrder(ORDER_SAVED_PASSWORDS);
-            getPreferenceScreen().addPreference(profileCategory);
-            passwordParent = profileCategory;
-        } else {
-            passwordParent = getPreferenceScreen();
-        }
-        for (int i = 0; i < count; i++) {
-            PasswordManagerHandler passwordManagerHandler =
-                    PasswordManagerHandlerProvider.getForProfile(getProfile())
-                            .getPasswordManagerHandler();
-            assert passwordManagerHandler != null;
-            SavedPasswordEntry saved = passwordManagerHandler.getSavedPasswordEntry(i);
-            String url = saved.getUrl();
-            String name = saved.getUserName();
-            String password = saved.getPassword();
-            if (shouldBeFiltered(url, name)) {
-                continue; // The current password won't show with the active filter, try the next.
-            }
-            Preference preference = new Preference(getStyledContext());
-            preference.setTitle(url);
-            preference.setOnPreferenceClickListener(this);
-            preference.setSummary(name);
-            Bundle args = preference.getExtras();
-            args.putString(PASSWORD_LIST_NAME, name);
-            args.putString(PASSWORD_LIST_URL, url);
-            args.putString(PASSWORD_LIST_PASSWORD, password);
-            args.putInt(PASSWORD_LIST_ID, i);
-            passwordParent.addPreference(preference);
-        }
-        mNoPasswords = passwordParent.getPreferenceCount() == 0;
-        if (mMenu != null) {
-            MenuItem menuItem = mMenu.findItem(R.id.export_passwords);
-            if (menuItem != null) {
-                menuItem.setEnabled(!mNoPasswords && !mExportFlow.isActive());
-            }
-        }
-        if (mNoPasswords) {
-            if (count == 0) displayEmptyScreenMessage(); // Show if the list was already empty.
-            if (mSearchQuery == null) {
-                // If not searching, the category needs to be removed again.
-                getPreferenceScreen().removePreference(passwordParent);
-            } else {
-                displayPasswordNoResultScreenMessage();
-            }
-        }
-    }
-
-    /**
-     * Returns true if there is a search query that requires the exclusion of an entry based on
-     * the passed url or name.
-     * @param url the visible URL of the entry to check. May be empty but must not be null.
-     * @param name the visible user name of the entry to check. May be empty but must not be null.
-     * @return Returns whether the entry with the passed url and name should be filtered.
-     */
-    private boolean shouldBeFiltered(final String url, final String name) {
-        if (mSearchQuery == null) {
-            return false;
-        }
-        return !url.toLowerCase(Locale.ENGLISH).contains(mSearchQuery.toLowerCase(Locale.ENGLISH))
-                && !name.toLowerCase(Locale.getDefault())
-                        .contains(mSearchQuery.toLowerCase(Locale.getDefault()));
-    }
-
-    @Override
-    public void passwordExceptionListAvailable(int count) {
-        if (mSearchQuery != null) return; // Don't show exceptions if a search is ongoing.
-        resetList(PREF_KEY_CATEGORY_EXCEPTIONS);
-        resetNoEntriesTextMessage();
-
-        mNoPasswordExceptions = count == 0;
-        if (mNoPasswordExceptions) {
-            if (mNoPasswords) displayEmptyScreenMessage();
-            return;
-        }
-
-        displayManageAccountLink();
-
-        PreferenceCategory profileCategory = new PreferenceCategory(getStyledContext());
-        profileCategory.setKey(PREF_KEY_CATEGORY_EXCEPTIONS);
-        profileCategory.setTitle(R.string.section_saved_passwords_exceptions);
-        profileCategory.setOrder(ORDER_EXCEPTIONS);
-        getPreferenceScreen().addPreference(profileCategory);
-        for (int i = 0; i < count; i++) {
-            PasswordManagerHandler passwordManagerHandler =
-                    PasswordManagerHandlerProvider.getForProfile(getProfile())
-                            .getPasswordManagerHandler();
-            assert passwordManagerHandler != null;
-            String exception = passwordManagerHandler.getSavedPasswordException(i);
-            Preference preference = new Preference(getStyledContext());
-            preference.setTitle(exception);
-            preference.setOnPreferenceClickListener(this);
-            Bundle args = preference.getExtras();
-            args.putString(PASSWORD_LIST_URL, exception);
-            args.putInt(PASSWORD_LIST_ID, i);
-            profileCategory.addPreference(preference);
-        }
-    }
-
-    @Override
-    public void onStart() {
-        super.onStart();
-        rebuildPasswordLists();
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        mExportFlow.onResume();
-    }
-
-    @Override
-    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent intent) {
-        super.onActivityResult(requestCode, resultCode, intent);
-        if (requestCode != PASSWORD_EXPORT_INTENT_REQUEST_CODE) return;
-        if (resultCode != Activity.RESULT_OK) return;
-        if (intent == null || intent.getData() == null) return;
-
-        mExportFlow.savePasswordsToDownloads(intent.getData());
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        mExportFlow.onSaveInstanceState(outState);
-        if (mSearchQuery != null) {
-            outState.putString(SAVED_STATE_SEARCH_QUERY, mSearchQuery);
-        }
-        outState.putInt(PasswordManagerHelper.MANAGE_PASSWORDS_REFERRER, mManagePasswordsReferrer);
-    }
-
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-
-        SyncService syncService = SyncServiceFactory.getForProfile(getProfile());
-        if (syncService != null) {
-            syncService.removeSyncStateChangedListener(this);
-        }
-        // The component should only be destroyed when the activity has been closed by the user
-        // (e.g. by pressing on the back button) and not when the activity is temporarily destroyed
-        // by the system.
-        if (getActivity().isFinishing()) {
-            PasswordManagerHandlerProvider.getForProfile(getProfile()).removeObserver(this);
-            if (mPasswordCheck != null
-                    && mManagePasswordsReferrer != ManagePasswordsReferrer.CHROME_SETTINGS) {
-                PasswordCheckFactory.destroy();
-            }
-        }
-    }
-
-    /**
-     *  Preference was clicked. Either navigate to manage account site or launch the PasswordEditor
-     *  depending on which preference it was.
-     */
-    @Override
-    public boolean onPreferenceClick(Preference preference) {
-        if (preference == mLinkPref) {
-            Intent intent =
-                    new Intent(
-                            Intent.ACTION_VIEW, Uri.parse(PasswordUiView.getAccountDashboardURL()));
-            intent.setPackage(getActivity().getPackageName());
-            getActivity().startActivity(intent);
-        } else {
-            boolean isBlockedCredential =
-                    !preference.getExtras().containsKey(PasswordSettings.PASSWORD_LIST_NAME);
-            PasswordManagerHandler passwordManagerHandler =
-                    PasswordManagerHandlerProvider.getForProfile(getProfile())
-                            .getPasswordManagerHandler();
-            assert passwordManagerHandler != null;
-            passwordManagerHandler.showPasswordEntryEditingView(
-                    getActivity(),
-                    preference.getExtras().getInt(PasswordSettings.PASSWORD_LIST_ID),
-                    isBlockedCredential);
-        }
-        return true;
-    }
-
-    private void createSavePasswordsSwitch() {
-        ChromeSwitchPreference savePasswordsSwitch =
-                new ChromeSwitchPreference(getStyledContext(), null);
-        savePasswordsSwitch.setKey(PREF_SAVE_PASSWORDS_SWITCH);
-        savePasswordsSwitch.setTitle(R.string.password_settings_save_passwords);
-        savePasswordsSwitch.setOrder(ORDER_SWITCH);
-        savePasswordsSwitch.setSummaryOn(R.string.text_on);
-        savePasswordsSwitch.setSummaryOff(R.string.text_off);
-        savePasswordsSwitch.setOnPreferenceChangeListener(
-                (preference, newValue) -> {
-                    getPrefService()
-                            .setBoolean(Pref.CREDENTIALS_ENABLE_SERVICE, (boolean) newValue);
-                    return true;
-                });
-        savePasswordsSwitch.setManagedPreferenceDelegate(
-                new ChromeManagedPreferenceDelegate(getProfile()) {
-                    @Override
-                    public boolean isPreferenceControlledByPolicy(Preference preference) {
-                        return getPrefService()
-                                .isManagedPreference(Pref.CREDENTIALS_ENABLE_SERVICE);
-                    }
-                });
-
-        getPreferenceScreen().addPreference(savePasswordsSwitch);
-
-        // Note: setting the switch state before the preference is added to the screen results in
-        // some odd behavior where the switch state doesn't always match the internal enabled state
-        // (e.g. the switch will say "On" when save passwords is really turned off), so
-        // .setChecked() should be called after .addPreference()
-        savePasswordsSwitch.setChecked(
-                getPrefService().getBoolean(Pref.CREDENTIALS_ENABLE_SERVICE));
-    }
-
-    private void createAutoSignInCheckbox() {
-        ChromeSwitchPreference autoSignInSwitch =
-                new ChromeSwitchPreference(getStyledContext(), null);
-        autoSignInSwitch.setKey(PREF_AUTOSIGNIN_SWITCH);
-        autoSignInSwitch.setTitle(R.string.passwords_auto_signin_title);
-        autoSignInSwitch.setOrder(ORDER_AUTO_SIGNIN_CHECKBOX);
-        autoSignInSwitch.setSummary(R.string.passwords_auto_signin_description);
-        autoSignInSwitch.setOnPreferenceChangeListener(
-                (preference, newValue) -> {
-                    getPrefService()
-                            .setBoolean(Pref.CREDENTIALS_ENABLE_AUTOSIGNIN, (boolean) newValue);
-                    return true;
-                });
-        autoSignInSwitch.setManagedPreferenceDelegate(
-                new ChromeManagedPreferenceDelegate(getProfile()) {
-                    @Override
-                    public boolean isPreferenceControlledByPolicy(Preference preference) {
-                        return getPrefService()
-                                .isManagedPreference(Pref.CREDENTIALS_ENABLE_AUTOSIGNIN);
-                    }
-                });
-        getPreferenceScreen().addPreference(autoSignInSwitch);
-        autoSignInSwitch.setChecked(
-                getPrefService().getBoolean(Pref.CREDENTIALS_ENABLE_AUTOSIGNIN));
-    }
-
-    private void createCheckPasswords() {
-        ChromeBasePreference checkPasswords = new ChromeBasePreference(getStyledContext());
-        checkPasswords.setKey(PREF_CHECK_PASSWORDS);
-        checkPasswords.setTitle(R.string.passwords_check_title);
-        checkPasswords.setOrder(ORDER_CHECK_PASSWORDS);
-        checkPasswords.setSummary(R.string.passwords_check_description);
-        // Add a listener which launches a settings page for the leak password check
-        checkPasswords.setOnPreferenceClickListener(
-                preference -> {
-                    PasswordCheck passwordCheck = PasswordCheckFactory.getOrCreate();
-                    passwordCheck.showUi(
-                            getStyledContext(), PasswordCheckReferrer.PASSWORD_SETTINGS);
-                    // Return true to notify the click was handled.
-                    return true;
-                });
-        getPreferenceScreen().addPreference(checkPasswords);
-    }
-
-    private void createTrustedVaultBanner(
-            @StringRes int subLabel, Preference.OnPreferenceClickListener listener) {
-        ChromeBasePreference trustedVaultBanner = new ChromeBasePreference(getStyledContext());
-        trustedVaultBanner.setKey(PREF_TRUSTED_VAULT_BANNER);
-        trustedVaultBanner.setTitle(R.string.android_trusted_vault_banner_label);
-        trustedVaultBanner.setOrder(ORDER_TRUSTED_VAULT_BANNER);
-        trustedVaultBanner.setSummary(subLabel);
-        trustedVaultBanner.setOnPreferenceClickListener(listener);
-        getPreferenceScreen().addPreference(trustedVaultBanner);
-    }
-
-    private void displayManageAccountLink() {
-        SyncService syncService = SyncServiceFactory.getForProfile(getProfile());
-        if (syncService == null || !syncService.isEngineInitialized()) {
-            return;
-        }
-        if (!PasswordManagerHelper.isSyncingPasswordsWithNoCustomPassphrase(syncService)) {
-            return;
-        }
-        if (mSearchQuery != null && !mNoPasswords) {
-            return; // Don't add the Manage Account link if there is a search going on.
-        }
-        if (getPreferenceScreen().findPreference(PREF_KEY_MANAGE_ACCOUNT_LINK) != null) {
-            return; // Don't add the Manage Account link if it's present.
-        }
-        if (mLinkPref != null) {
-            // If we created the link before, reuse it.
-            getPreferenceScreen().addPreference(mLinkPref);
-            return;
-        }
-        ForegroundColorSpan colorSpan =
-                new ForegroundColorSpan(SemanticColorUtils.getDefaultTextColorLink(getContext()));
-        SpannableString title =
-                SpanApplier.applySpans(
-                        getString(R.string.manage_passwords_text),
-                        new SpanApplier.SpanInfo("<link>", "</link>", colorSpan));
-        mLinkPref = new ChromeBasePreference(getStyledContext());
-        mLinkPref.setKey(PREF_KEY_MANAGE_ACCOUNT_LINK);
-        mLinkPref.setTitle(title);
-        mLinkPref.setOnPreferenceClickListener(this);
-        mLinkPref.setOrder(ORDER_MANAGE_ACCOUNT_LINK);
-        getPreferenceScreen().addPreference(mLinkPref);
-    }
-
-    private Context getStyledContext() {
-        return getPreferenceManager().getContext();
-    }
-
-    private PrefService getPrefService() {
-        return UserPrefs.get(getProfile());
-    }
-
-    @Override
-    public void syncStateChanged() {
-        final @TrustedVaultBannerState int oldTrustedVaultBannerState = mTrustedVaultBannerState;
-        computeTrustedVaultBannerState();
-        if (oldTrustedVaultBannerState != mTrustedVaultBannerState) {
-            rebuildPasswordLists();
-        }
-    }
-
-    private void computeTrustedVaultBannerState() {
-        final SyncService syncService = SyncServiceFactory.getForProfile(getProfile());
-        if (syncService == null) {
-            mTrustedVaultBannerState = TrustedVaultBannerState.NOT_SHOWN;
-            return;
-        }
-        if (!syncService.isEngineInitialized()) {
-            // Can't call getPassphraseType() yet.
-            mTrustedVaultBannerState = TrustedVaultBannerState.NOT_SHOWN;
-            return;
-        }
-        if (syncService.getPassphraseType() == PassphraseType.TRUSTED_VAULT_PASSPHRASE) {
-            mTrustedVaultBannerState = TrustedVaultBannerState.OPTED_IN;
-            return;
-        }
-        if (syncService.shouldOfferTrustedVaultOptIn()) {
-            mTrustedVaultBannerState = TrustedVaultBannerState.OFFER_OPT_IN;
-            return;
-        }
-        mTrustedVaultBannerState = TrustedVaultBannerState.NOT_SHOWN;
-    }
-
-    private boolean openTrustedVaultOptInDialog(Preference unused) {
-        SyncService syncService = SyncServiceFactory.getForProfile(getProfile());
-        assert syncService != null;
-        CoreAccountInfo accountInfo = syncService.getAccountInfo();
-        assert accountInfo != null;
-        SyncSettingsUtils.openTrustedVaultOptInDialog(
-                this, accountInfo, REQUEST_CODE_TRUSTED_VAULT_OPT_IN);
-        // Return true to notify the click was handled.
-        return true;
-    }
-
-    private boolean openTrustedVaultInfoPage(Preference unused) {
-        Intent intent =
-                new Intent(
-                        Intent.ACTION_VIEW,
-                        Uri.parse(PasswordUiView.getTrustedVaultLearnMoreURL()));
-        intent.setPackage(getActivity().getPackageName());
-        getActivity().startActivity(intent);
-        // Return true to notify the click was handled.
-        return true;
-    }
-
-    @Nullable Menu getMenuForTesting() {
-        return mMenu;
-    }
-
-    Toolbar getToolbarForTesting() {
-        return getActivity().findViewById(R.id.action_bar);
-    }
-
-    @Override
-    public @AnimationType int getAnimationType() {
-        return AnimationType.PROPERTY;
-    }
-}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsNavigationImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsNavigationImpl.java
index 9012e6fa..c7cb29e1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsNavigationImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsNavigationImpl.java
@@ -18,7 +18,6 @@
 import org.chromium.chrome.browser.autofill.settings.NonCardPaymentMethodsManagementFragment;
 import org.chromium.chrome.browser.browsing_data.ClearBrowsingDataFragment;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.password_manager.settings.PasswordSettings;
 import org.chromium.chrome.browser.safety_check.SafetyCheckSettingsFragment;
 import org.chromium.chrome.browser.safety_hub.SafetyHubFragment;
 import org.chromium.chrome.browser.sync.settings.GoogleServicesSettings;
@@ -55,7 +54,6 @@
             case SettingsFragment.PAYMENT_METHODS:
             case SettingsFragment.SITE:
             case SettingsFragment.ACCESSIBILITY:
-            case SettingsFragment.PASSWORDS:
             case SettingsFragment.GOOGLE_SERVICES:
             case SettingsFragment.MANAGE_SYNC:
             case SettingsFragment.FINANCIAL_ACCOUNTS:
@@ -119,8 +117,6 @@
                 return SiteSettings.class;
             case SettingsFragment.ACCESSIBILITY:
                 return AccessibilitySettings.class;
-            case SettingsFragment.PASSWORDS:
-                return PasswordSettings.class;
             case SettingsFragment.GOOGLE_SERVICES:
                 return GoogleServicesSettings.class;
             case SettingsFragment.MANAGE_SYNC:
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtils.java
index 789146e..9db32c3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtils.java
@@ -140,6 +140,10 @@
             return SyncError.SYNC_SETUP_INCOMPLETE;
         }
 
+        if (syncService.hasUnrecoverableError()) {
+            return SyncError.OTHER_ERRORS;
+        }
+
         return getCommonError(profile);
     }
 
@@ -570,13 +574,7 @@
             return SyncError.NO_ERROR;
         }
 
-        @SyncError int error = getCommonError(profile);
-        // Do not show identity error for unrecoverable errors, since they are not actionable.
-        // TODO(crbug.com/40944114): Remove these unused values after sync-to-signin transition.
-        if (error == SyncError.OTHER_ERRORS) {
-            return SyncError.NO_ERROR;
-        }
-        return error;
+        return getCommonError(profile);
     }
 
     /** Returns the errors common to both getSyncError() and getIdentityError(). */
@@ -584,8 +582,7 @@
         SyncService syncService = SyncServiceFactory.getForProfile(profile);
         assert syncService != null;
 
-        if (syncService.getAuthError().getState()
-                == GoogleServiceAuthErrorState.INVALID_GAIA_CREDENTIALS) {
+        if (syncService.getAuthError().getState() != GoogleServiceAuthErrorState.NONE) {
             return SyncError.AUTH_ERROR;
         }
 
@@ -593,11 +590,6 @@
             return SyncError.CLIENT_OUT_OF_DATE;
         }
 
-        if (syncService.getAuthError().getState() != GoogleServiceAuthErrorState.NONE
-                || syncService.hasUnrecoverableError()) {
-            return SyncError.OTHER_ERRORS;
-        }
-
         if (syncService.isEngineInitialized()
                 && syncService.isPassphraseRequiredForPreferredDataTypes()) {
             return SyncError.PASSPHRASE_REQUIRED;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
index c5908570..3d4bd8f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -733,7 +733,6 @@
      * @param ephemeralTabCoordinatorSupplier Supplies the {@link EphemeralTabCoordinator}.
      * @param initializeWithIncognitoColors Whether the toolbar should be initialized with incognito
      * @param backPressManager The {@link BackPressManager} handling back press gesture.
-     * @param overviewColorSupplier Notifies when the overview color changes.
      * @param desktopWindowStateManager The {@link DesktopWindowStateManager} instance.
      * @param multiInstanceManager The {@link MultiInstanceManager} used to move tabs to new
      *     windows.
@@ -785,7 +784,6 @@
             Supplier<EphemeralTabCoordinator> ephemeralTabCoordinatorSupplier,
             boolean initializeWithIncognitoColors,
             @Nullable BackPressManager backPressManager,
-            @Nullable ObservableSupplier<Integer> overviewColorSupplier,
             ObservableSupplier<ReadAloudController> readAloudControllerSupplier,
             @Nullable DesktopWindowStateManager desktopWindowStateManager,
             @Nullable MultiInstanceManager multiInstanceManager,
@@ -1099,6 +1097,7 @@
                         toolbarLayout,
                         buttonDataProviders,
                         browsingModeThemeColorProvider,
+                        mIncognitoStateProvider,
                         initializeWithIncognitoColors,
                         mConstraintsProxy,
                         onLongClickListener,
@@ -1630,8 +1629,6 @@
                     }
                 };
 
-        mToolbar.setIncognitoStateProvider(mIncognitoStateProvider, overviewColorSupplier);
-
         mFindToolbarManager = findToolbarManager;
         mFindToolbarManager.addObserver(mFindToolbarObserver);
 
@@ -1841,6 +1838,7 @@
             ToolbarLayout toolbarLayout,
             List<ButtonDataProvider> buttonDataProviders,
             ThemeColorProvider browsingModeThemeColorProvider,
+            IncognitoStateProvider incognitoStateProvider,
             boolean initializeWithIncognitoColors,
             ObservableSupplier<Integer> constraintsSupplier,
             OnLongClickListener onLongClickListener,
@@ -1856,6 +1854,7 @@
                         buttonDataProviders,
                         mLayoutStateProviderSupplier,
                         browsingModeThemeColorProvider,
+                        incognitoStateProvider,
                         mMenuButtonCoordinator,
                         mMenuButtonCoordinator.getMenuButtonHelperSupplier(),
                         mTabSwitcherButtonCoordinator,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
index ef53797..592a546 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
@@ -1571,7 +1571,6 @@
                             mEphemeralTabCoordinatorSupplier,
                             mInitializeUiWithIncognitoColors,
                             mBackPressManager,
-                            mOverviewColorSupplier,
                             mReadAloudControllerSupplier,
                             getDesktopWindowStateManager(),
                             getMultiInstanceManager(),
diff --git a/chrome/android/javatests/BUILD.gn b/chrome/android/javatests/BUILD.gn
index 4f5216a..7c9df3df 100644
--- a/chrome/android/javatests/BUILD.gn
+++ b/chrome/android/javatests/BUILD.gn
@@ -971,10 +971,6 @@
     "src/org/chromium/chrome/browser/password_manager/TouchToFillMainFlowIntegrationTest.java",
     "src/org/chromium/chrome/browser/password_manager/VirtualViewStructureInstrumentationTest.java",
     "src/org/chromium/chrome/browser/password_manager/settings/CredentialManagerIntegrationTest.java",
-    "src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsSearchTest.java",
-    "src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTest.java",
-    "src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTestHelper.java",
-    "src/org/chromium/chrome/browser/password_manager/settings/PasswordViewingTypeTest.java",
     "src/org/chromium/chrome/browser/password_manager/settings/PasswordsPreferenceTest.java",
   ]
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsSearchTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsSearchTest.java
deleted file mode 100644
index a9055350..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsSearchTest.java
+++ /dev/null
@@ -1,539 +0,0 @@
-// Copyright 2021 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.password_manager.settings;
-
-import static androidx.test.espresso.Espresso.onView;
-import static androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu;
-import static androidx.test.espresso.action.ViewActions.click;
-import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
-import static androidx.test.espresso.action.ViewActions.typeText;
-import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
-import static androidx.test.espresso.assertion.ViewAssertions.matches;
-import static androidx.test.espresso.matcher.ViewMatchers.assertThat;
-import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom;
-import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
-import static androidx.test.espresso.matcher.ViewMatchers.withId;
-import static androidx.test.espresso.matcher.ViewMatchers.withParent;
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static org.hamcrest.Matchers.allOf;
-import static org.hamcrest.Matchers.anyOf;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.hamcrest.Matchers.nullValue;
-import static org.hamcrest.Matchers.sameInstance;
-
-import static org.chromium.chrome.browser.password_manager.settings.PasswordSettingsTestHelper.ARES_AT_OLYMP;
-import static org.chromium.chrome.browser.password_manager.settings.PasswordSettingsTestHelper.DEIMOS_AT_OLYMP;
-import static org.chromium.chrome.browser.password_manager.settings.PasswordSettingsTestHelper.GREEK_GODS;
-import static org.chromium.chrome.browser.password_manager.settings.PasswordSettingsTestHelper.HADES_AT_UNDERWORLD;
-import static org.chromium.chrome.browser.password_manager.settings.PasswordSettingsTestHelper.PHOBOS_AT_OLYMP;
-import static org.chromium.chrome.browser.password_manager.settings.PasswordSettingsTestHelper.ZEUS_ON_EARTH;
-import static org.chromium.ui.test.util.ViewUtils.VIEW_GONE;
-import static org.chromium.ui.test.util.ViewUtils.VIEW_INVISIBLE;
-import static org.chromium.ui.test.util.ViewUtils.VIEW_NULL;
-import static org.chromium.ui.test.util.ViewUtils.onViewWaiting;
-
-import android.app.Instrumentation;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.graphics.ColorFilter;
-import android.graphics.drawable.Drawable;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import androidx.annotation.IdRes;
-import androidx.annotation.StringRes;
-import androidx.appcompat.view.menu.ActionMenuItemView;
-import androidx.core.graphics.drawable.DrawableCompat;
-import androidx.test.espresso.Espresso;
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import org.hamcrest.Matcher;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.BaseActivityTestRule;
-import org.chromium.base.test.util.Batch;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.DisabledTest;
-import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.RequiresRestart;
-import org.chromium.chrome.browser.flags.ChromeSwitches;
-import org.chromium.chrome.browser.history.HistoryActivity;
-import org.chromium.chrome.browser.history.HistoryContentManager;
-import org.chromium.chrome.browser.history.StubbedHistoryProvider;
-import org.chromium.chrome.browser.password_check.PasswordCheck;
-import org.chromium.chrome.browser.password_check.PasswordCheckFactory;
-import org.chromium.chrome.browser.settings.SettingsActivityTestRule;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.R;
-import org.chromium.ui.test.util.ViewUtils;
-
-import java.util.Date;
-import java.util.concurrent.atomic.AtomicReference;
-
-/** Tests for the search feature of the "Passwords" settings screen. */
-@RunWith(ChromeJUnit4ClassRunner.class)
-@Batch(Batch.PER_CLASS)
-@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
-public class PasswordSettingsSearchTest {
-    private static final long UI_UPDATING_TIMEOUT_MS = 3000;
-
-    @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
-
-    @Rule
-    public BaseActivityTestRule<HistoryActivity> mHistoryActivityTestRule =
-            new BaseActivityTestRule<>(HistoryActivity.class);
-
-    @Rule
-    public SettingsActivityTestRule<PasswordSettings> mSettingsActivityTestRule =
-            new SettingsActivityTestRule<>(PasswordSettings.class);
-
-    @Mock private PasswordCheck mPasswordCheck;
-
-    private final PasswordSettingsTestHelper mTestHelper = new PasswordSettingsTestHelper();
-
-    @Before
-    public void setUp() {
-        PasswordCheckFactory.setPasswordCheckForTesting(mPasswordCheck);
-    }
-
-    @After
-    public void tearDown() {
-        mTestHelper.tearDown();
-    }
-
-    /** Check that the search item is visible in the action bar. */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    @SuppressWarnings("AlwaysShowAction") // We need to ensure the icon is in the action bar.
-    public void testSearchIconVisibleInActionBar() {
-        mTestHelper.setPasswordSource(null); // Initialize empty preferences.
-        mTestHelper.startPasswordSettingsFromMainSettings(mSettingsActivityTestRule);
-        onViewWaiting(withText(R.string.password_manager_settings_title));
-        PasswordSettings f = mSettingsActivityTestRule.getFragment();
-
-        // Force the search option into the action bar.
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    f.getMenuForTesting()
-                            .findItem(R.id.menu_id_search)
-                            .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
-                });
-
-        onView(withId(R.id.menu_id_search)).check(matches(isDisplayed()));
-    }
-
-    /** Check that the search item is visible in the overflow menu. */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    public void testSearchTextInOverflowMenuVisible() {
-        mTestHelper.setPasswordSource(
-                null); // Initialize empty preferences.mSettingsActivityTestRule
-        mTestHelper.startPasswordSettingsFromMainSettings(mSettingsActivityTestRule);
-        onViewWaiting(withText(R.string.password_manager_settings_title));
-        PasswordSettings f = mSettingsActivityTestRule.getFragment();
-
-        // Force the search option into the overflow menu.
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    f.getMenuForTesting()
-                            .findItem(R.id.menu_id_search)
-                            .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
-                });
-
-        // Open the overflow menu.
-        openActionBarOverflowOrOptionsMenu(
-                InstrumentationRegistry.getInstrumentation().getTargetContext());
-
-        onView(withText(R.string.search)).check(matches(isDisplayed()));
-    }
-
-    /**
-     * Check that searching doesn't push the help icon into the overflow menu permanently. On screen
-     * sizes where the help item starts out in the overflow menu, ensure it stays there.
-     */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    public void testTriggeringSearchRestoresHelpIcon() {
-        mTestHelper.setPasswordSource(null);
-        mTestHelper.startPasswordSettingsFromMainSettings(mSettingsActivityTestRule);
-        onViewWaiting(withText(R.string.password_manager_settings_title));
-
-        // Retrieve the initial status and ensure that the help option is there at all.
-        final AtomicReference<Boolean> helpInOverflowMenu = new AtomicReference<>(false);
-        onView(withId(R.id.menu_id_targeted_help))
-                .check(
-                        (helpMenuItem, e) -> {
-                            ActionMenuItemView view = (ActionMenuItemView) helpMenuItem;
-                            helpInOverflowMenu.set(view == null || !view.showsIcon());
-                        });
-        if (helpInOverflowMenu.get()) {
-            openActionBarOverflowOrOptionsMenu(
-                    InstrumentationRegistry.getInstrumentation().getTargetContext());
-            onView(withText(R.string.menu_help)).check(matches(isDisplayed()));
-            Espresso.pressBack(); // to close the Overflow menu.
-        } else {
-            onView(withId(R.id.menu_id_targeted_help)).check(matches(isDisplayed()));
-        }
-
-        // Trigger the search, close it and wait for UI to be restored.
-        onView(withSearchMenuIdOrText()).perform(click());
-        onView(withContentDescription(R.string.abc_action_bar_up_description)).perform(click());
-        onViewWaiting(withText(R.string.password_manager_settings_title));
-
-        // Check that the help option is exactly where it was to begin with.
-        if (helpInOverflowMenu.get()) {
-            openActionBarOverflowOrOptionsMenu(
-                    InstrumentationRegistry.getInstrumentation().getTargetContext());
-            onView(withText(R.string.menu_help)).check(matches(isDisplayed()));
-            onView(withId(R.id.menu_id_targeted_help)).check(doesNotExist());
-        } else {
-            onView(withText(R.string.menu_help)).check(doesNotExist());
-            onView(withId(R.id.menu_id_targeted_help)).check(matches(isDisplayed()));
-        }
-    }
-
-    /** Check that the search filters the list by name. */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    public void testSearchFiltersByUserName() {
-        mTestHelper.setPasswordSourceWithMultipleEntries(GREEK_GODS);
-        mTestHelper.startPasswordSettingsFromMainSettings(mSettingsActivityTestRule);
-
-        // Search for a string matching multiple user names. Case doesn't need to match.
-        onView(withSearchMenuIdOrText()).perform(click());
-        onView(withId(R.id.search_src_text))
-                .perform(click(), typeText("aREs"), closeSoftKeyboard());
-
-        onView(withText(ARES_AT_OLYMP.getUserName())).check(matches(isDisplayed()));
-        onView(withText(PHOBOS_AT_OLYMP.getUserName())).check(matches(isDisplayed()));
-        onView(withText(DEIMOS_AT_OLYMP.getUserName())).check(matches(isDisplayed()));
-        onView(withText(ZEUS_ON_EARTH.getUserName())).check(doesNotExist());
-        onView(withText(HADES_AT_UNDERWORLD.getUrl())).check(doesNotExist());
-    }
-
-    /** Check that the search filters the list by URL. */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    public void testSearchFiltersByUrl() {
-        mTestHelper.setPasswordSourceWithMultipleEntries(GREEK_GODS);
-        mTestHelper.startPasswordSettingsFromMainSettings(mSettingsActivityTestRule);
-
-        // Search for a string that matches multiple URLs. Case doesn't need to match.
-        onView(withSearchMenuIdOrText()).perform(click());
-        onView(withId(R.id.search_src_text))
-                .perform(click(), typeText("Olymp"), closeSoftKeyboard());
-
-        onView(withText(ARES_AT_OLYMP.getUserName())).check(matches(isDisplayed()));
-        onView(withText(PHOBOS_AT_OLYMP.getUserName())).check(matches(isDisplayed()));
-        onView(withText(DEIMOS_AT_OLYMP.getUserName())).check(matches(isDisplayed()));
-        onView(withText(ZEUS_ON_EARTH.getUserName())).check(doesNotExist());
-        onView(withText(HADES_AT_UNDERWORLD.getUrl())).check(doesNotExist());
-    }
-
-    /** Check that the search filters the list by URL. */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    public void testSearchDisplaysNoResultMessageIfSearchTurnsUpEmpty() {
-        mTestHelper.setPasswordSourceWithMultipleEntries(GREEK_GODS);
-        mTestHelper.startPasswordSettingsFromMainSettings(mSettingsActivityTestRule);
-
-        // Open the search which should hide the Account link.
-        onView(withSearchMenuIdOrText()).perform(click());
-
-        // Search for a string that matches nothing which should leave the results entirely blank.
-        onView(withId(R.id.search_src_text))
-                .perform(click(), typeText("Mars"), closeSoftKeyboard());
-
-        for (SavedPasswordEntry god : GREEK_GODS) {
-            onView(allOf(withText(god.getUserName()), withText(god.getUrl())))
-                    .check(doesNotExist());
-        }
-        onView(withText(R.string.saved_passwords_none_text)).check(doesNotExist());
-        // Check that the section header for saved passwords is not present. Do not confuse it with
-        // the toolbar label which contains the same string, look for the one inside a linear
-        // layout.
-        onView(
-                        allOf(
-                                withParent(isAssignableFrom(LinearLayout.class)),
-                                withText(R.string.password_manager_settings_title)))
-                .check(doesNotExist());
-        // Check the message for no result.
-        onView(withText(R.string.password_no_result)).check(matches(isDisplayed()));
-    }
-
-    /** Check that triggering the search hides all non-password prefs. */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    public void testSearchIconClickedHidesExceptionsTemporarily() {
-        mTestHelper.setPasswordExceptions(new String[] {"http://exclu.de", "http://not-inclu.de"});
-        mTestHelper.startPasswordSettingsFromMainSettings(mSettingsActivityTestRule);
-
-        onView(withText(R.string.section_saved_passwords_exceptions)).check(matches(isDisplayed()));
-
-        onView(withSearchMenuIdOrText()).perform(click());
-        onView(withId(R.id.search_src_text)).perform(click(), closeSoftKeyboard());
-
-        onView(withText(R.string.section_saved_passwords_exceptions)).check(doesNotExist());
-
-        onView(withContentDescription(R.string.abc_action_bar_up_description)).perform(click());
-        InstrumentationRegistry.getInstrumentation().waitForIdleSync(); // Close search view.
-
-        onView(withText(R.string.section_saved_passwords_exceptions)).check(matches(isDisplayed()));
-    }
-
-    /** Check that triggering the search hides all non-password prefs. */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    public void testSearchIconClickedHidesGeneralPrefs() {
-        mTestHelper.setPasswordSource(ZEUS_ON_EARTH);
-        mTestHelper.startPasswordSettingsFromMainSettings(mSettingsActivityTestRule);
-        final PasswordSettings prefs = mSettingsActivityTestRule.getFragment();
-        final AtomicReference<Boolean> menuInitiallyVisible = new AtomicReference<>();
-        ThreadUtils.runOnUiThreadBlocking(
-                () ->
-                        menuInitiallyVisible.set(
-                                prefs.getToolbarForTesting().isOverflowMenuShowing()));
-
-        onView(withText(R.string.password_settings_save_passwords)).check(matches(isDisplayed()));
-
-        if (menuInitiallyVisible.get()) { // Check overflow menu only on large screens that have it.
-            onView(withContentDescription(R.string.abc_action_menu_overflow_description))
-                    .check(matches(isDisplayed()));
-        }
-
-        onView(withSearchMenuIdOrText()).perform(click());
-
-        onView(withText(R.string.password_settings_save_passwords)).check(doesNotExist());
-        ViewUtils.waitForViewCheckingState(
-                withParent(withContentDescription(R.string.abc_action_menu_overflow_description)),
-                VIEW_INVISIBLE | VIEW_GONE | VIEW_NULL);
-
-        onView(withContentDescription(R.string.abc_action_bar_up_description)).perform(click());
-        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
-        if (menuInitiallyVisible.get()) { // If the overflow menu was there, it should be restored.
-            onView(withContentDescription(R.string.abc_action_menu_overflow_description))
-                    .check(matches(isDisplayed()));
-        }
-    }
-
-    /** Check that closing the search via back button brings back all non-password prefs. */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    public void testSearchBarBackButtonRestoresGeneralPrefs() {
-        mTestHelper.setPasswordSourceWithMultipleEntries(GREEK_GODS);
-        mTestHelper.startPasswordSettingsFromMainSettings(mSettingsActivityTestRule);
-
-        onView(withSearchMenuIdOrText()).perform(click());
-        onView(withId(R.id.search_src_text)).perform(click(), typeText("Zeu"), closeSoftKeyboard());
-
-        onView(withText(R.string.password_settings_save_passwords)).check(doesNotExist());
-
-        onView(withContentDescription(R.string.abc_action_bar_up_description)).perform(click());
-        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
-
-        onView(withText(R.string.password_settings_save_passwords)).check(matches(isDisplayed()));
-
-        onView(withId(R.id.menu_id_search)).check(matches(isDisplayed()));
-    }
-
-    /** Check that clearing the search also hides the clear button. */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    public void testSearchViewCloseIconExistsOnlyToClearQueries() {
-        mTestHelper.setPasswordSourceWithMultipleEntries(GREEK_GODS);
-        mTestHelper.startPasswordSettingsFromMainSettings(mSettingsActivityTestRule);
-
-        // Trigger search which shouldn't have the button yet.
-        onView(withSearchMenuIdOrText()).perform(click());
-        ViewUtils.waitForViewCheckingState(
-                withId(R.id.search_close_btn), VIEW_INVISIBLE | VIEW_GONE | VIEW_NULL);
-
-        // Type something and see the button appear.
-        onView(withId(R.id.search_src_text))
-                // Trigger search which shouldn't have the button yet.
-                .perform(click(), typeText("Zeu"), closeSoftKeyboard());
-        onView(withId(R.id.search_close_btn)).check(matches(isDisplayed()));
-
-        // Clear the search which should hide the button again.
-        onView(withId(R.id.search_close_btn)).perform(click()); // Clear search.
-        ViewUtils.waitForViewCheckingState(
-                withId(R.id.search_close_btn), VIEW_INVISIBLE | VIEW_GONE | VIEW_NULL);
-    }
-
-    /**
-     * Check that the changed color of the loaded Drawable does not persist for other uses of the
-     * drawable. This is not implicitly true as a loaded Drawable is by default only a reference to
-     * the globally defined resource.
-     */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    public void testSearchIconColorAffectsOnlyLocalSearchDrawable() {
-        // Open the password preferences and remember the applied color filter.
-        mTestHelper.startPasswordSettingsFromMainSettings(mSettingsActivityTestRule);
-        final PasswordSettings f = mSettingsActivityTestRule.getFragment();
-        onView(withId(R.id.search_button)).check(matches(isDisplayed()));
-        final AtomicReference<ColorFilter> passwordSearchFilter = new AtomicReference<>();
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    Drawable drawable =
-                            f.getMenuForTesting().findItem(R.id.menu_id_search).getIcon();
-                    passwordSearchFilter.set(DrawableCompat.getColorFilter(drawable));
-                });
-
-        // Now launch a non-empty History activity.
-        StubbedHistoryProvider mHistoryProvider = new StubbedHistoryProvider();
-        mHistoryProvider.addItem(StubbedHistoryProvider.createHistoryItem(0, new Date().getTime()));
-        mHistoryProvider.addItem(StubbedHistoryProvider.createHistoryItem(1, new Date().getTime()));
-        HistoryContentManager.setProviderForTests(mHistoryProvider);
-        mHistoryActivityTestRule.launchActivity(null);
-
-        // Find the search view to ensure that the set color filter is different from the saved one.
-        final AtomicReference<ColorFilter> historySearchFilter = new AtomicReference<>();
-        onView(withId(R.id.search_menu_id)).check(matches(isDisplayed()));
-        onView(withId(R.id.search_menu_id))
-                .check(
-                        (searchMenuItem, e) -> {
-                            Drawable drawable =
-                                    ((ActionMenuItemView) searchMenuItem).getItemData().getIcon();
-                            historySearchFilter.set(DrawableCompat.getColorFilter(drawable));
-                            assertThat(
-                                    historySearchFilter.get(),
-                                    anyOf(
-                                            is(nullValue()),
-                                            is(not(sameInstance(passwordSearchFilter.get())))));
-                        });
-
-        // Close the activity and check that the icon in the password preferences has not changed.
-        mHistoryActivityTestRule.getActivity().finish();
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    ColorFilter colorFilter =
-                            DrawableCompat.getColorFilter(
-                                    f.getMenuForTesting().findItem(R.id.menu_id_search).getIcon());
-                    assertThat(
-                            colorFilter,
-                            anyOf(is(nullValue()), is(sameInstance(passwordSearchFilter.get()))));
-                    assertThat(
-                            colorFilter,
-                            anyOf(
-                                    is(nullValue()),
-                                    is(not(sameInstance(historySearchFilter.get())))));
-                });
-    }
-
-    /**
-     * Check that the filtered password list persists after the user had inspected a single result.
-     *
-     * <p>TODO(crbug.com/40763233): Move this test to a full integration test which spins up native
-     * and actually has stored passwords.
-     */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    @DisabledTest(message = "crbug/1202907 - The edit UI is now launched via native.")
-    @RequiresRestart("crbug/1137002 - Figure out why this flakes as a batched test.")
-    public void testSearchResultsPersistAfterEntryInspection() {
-        mTestHelper.setPasswordSourceWithMultipleEntries(GREEK_GODS);
-        mTestHelper.setPasswordExceptions(new String[] {"http://exclu.de", "http://not-inclu.de"});
-        ReauthenticationManager.setApiOverride(ReauthenticationManager.OverrideState.AVAILABLE);
-        ReauthenticationManager.setScreenLockSetUpOverride(
-                ReauthenticationManager.OverrideState.AVAILABLE);
-        mTestHelper.startPasswordSettingsFromMainSettings(mSettingsActivityTestRule);
-
-        // Open the search and filter all but "Zeus".
-        onView(withSearchMenuIdOrText()).perform(click());
-
-        onViewWaiting(withId(R.id.search_src_text));
-        onView(withId(R.id.search_src_text)).perform(click(), typeText("Zeu"), closeSoftKeyboard());
-        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
-
-        onView(withText(R.string.passwords_auto_signin_title)).check(doesNotExist());
-        onView(withText(ZEUS_ON_EARTH.getUserName())).check(matches(isDisplayed()));
-        onView(withText(PHOBOS_AT_OLYMP.getUserName())).check(doesNotExist());
-        onView(withText(HADES_AT_UNDERWORLD.getUrl())).check(doesNotExist());
-
-        // Click "Zeus" to open edit field and verify the password. Pretend the user just passed the
-        // reauthentication challenge.
-        ReauthenticationManager.recordLastReauth(
-                System.currentTimeMillis(), ReauthenticationManager.ReauthScope.ONE_AT_A_TIME);
-        Instrumentation.ActivityMonitor monitor =
-                InstrumentationRegistry.getInstrumentation()
-                        .addMonitor(new IntentFilter(Intent.ACTION_VIEW), null, false);
-        onView(withText(ZEUS_ON_EARTH.getUserName())).perform(click());
-        monitor.waitForActivityWithTimeout(UI_UPDATING_TIMEOUT_MS);
-        Assert.assertEquals("Monitor for has not been called", 1, monitor.getHits());
-        InstrumentationRegistry.getInstrumentation().removeMonitor(monitor);
-        onView(withContentDescription(R.string.password_entry_viewer_show_stored_password))
-                .perform(click());
-        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
-
-        onView(withText(ZEUS_ON_EARTH.getPassword())).check(matches(isDisplayed()));
-        onView(withContentDescription(R.string.abc_action_bar_up_description))
-                .perform(click()); // Go back to the search list.
-        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
-
-        onView(withText(R.string.passwords_auto_signin_title)).check(doesNotExist());
-        onView(withText(ZEUS_ON_EARTH.getUserName())).check(matches(isDisplayed()));
-        onView(withText(PHOBOS_AT_OLYMP.getUserName())).check(doesNotExist());
-        onView(withText(HADES_AT_UNDERWORLD.getUrl())).check(doesNotExist());
-        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
-
-        // The search bar should still be open and still display the search query.
-        onViewWaiting(allOf(withId(R.id.search_src_text), withText("Zeu")));
-        onView(withId(R.id.search_src_text)).check(matches(withText("Zeu")));
-    }
-
-    /**
-     * Looks for the search icon by id or by its title.
-     *
-     * @return Returns either the icon button or the menu option.
-     */
-    private static Matcher<View> withSearchMenuIdOrText() {
-        return withMenuIdOrText(R.id.menu_id_search, R.string.search);
-    }
-
-    /**
-     * Looks for the icon by id. If it cannot be found, it's probably hidden in the overflow menu.
-     * In that case, open the menu and search for its title.
-     *
-     * @return Returns either the icon button or the menu option.
-     */
-    private static Matcher<View> withMenuIdOrText(@IdRes int actionId, @StringRes int actionLabel) {
-        Matcher<View> matcher = withId(actionId);
-        try {
-            Espresso.onView(matcher).check(matches(isDisplayed()));
-            return matcher;
-        } catch (Exception NoMatchingViewException) {
-            openActionBarOverflowOrOptionsMenu(
-                    InstrumentationRegistry.getInstrumentation().getTargetContext());
-            return withText(actionLabel);
-        }
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTest.java
deleted file mode 100644
index 3391dd0..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTest.java
+++ /dev/null
@@ -1,393 +0,0 @@
-// Copyright 2014 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.password_manager.settings;
-
-import static androidx.test.espresso.matcher.ViewMatchers.withText;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.when;
-
-import static org.chromium.ui.test.util.ViewUtils.onViewWaiting;
-
-import android.os.Bundle;
-
-import androidx.test.filters.MediumTest;
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.Feature;
-import org.chromium.chrome.browser.flags.ChromeSwitches;
-import org.chromium.chrome.browser.password_check.PasswordCheck;
-import org.chromium.chrome.browser.password_check.PasswordCheckFactory;
-import org.chromium.chrome.browser.password_manager.ManagePasswordsReferrer;
-import org.chromium.chrome.browser.password_manager.PasswordManagerHelper;
-import org.chromium.chrome.browser.preferences.Pref;
-import org.chromium.chrome.browser.profiles.ProfileManager;
-import org.chromium.chrome.browser.settings.SettingsActivityTestRule;
-import org.chromium.chrome.browser.sync.SyncServiceFactory;
-import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
-import org.chromium.chrome.test.OverrideContextWrapperTestRule;
-import org.chromium.chrome.test.R;
-import org.chromium.components.browser_ui.settings.ChromeSwitchPreference;
-import org.chromium.components.prefs.PrefService;
-import org.chromium.components.sync.DataType;
-import org.chromium.components.sync.PassphraseType;
-import org.chromium.components.sync.SyncService;
-import org.chromium.components.user_prefs.UserPrefs;
-
-import java.util.Set;
-
-/**
- * Tests for the "Passwords" settings screen. These tests are not batchable (without significant
- * effort), so consider splitting large new suites into separate classes.
- */
-@RunWith(ChromeJUnit4ClassRunner.class)
-@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
-public class PasswordSettingsTest {
-    @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
-
-    @Rule
-    public SettingsActivityTestRule<PasswordSettings> mPasswordSettingsActivityTestRule =
-            new SettingsActivityTestRule<>(PasswordSettings.class);
-
-    @Rule
-    public OverrideContextWrapperTestRule mAutomotiveContextWrapperTestRule =
-            new OverrideContextWrapperTestRule();
-
-    @Mock private PasswordCheck mPasswordCheck;
-
-    @Mock private SyncService mMockSyncService;
-
-    private final PasswordSettingsTestHelper mTestHelper = new PasswordSettingsTestHelper();
-
-    @Before
-    public void setUp() {
-        PasswordCheckFactory.setPasswordCheckForTesting(mPasswordCheck);
-
-        // By default sync is off. Tests can override this later.
-        setSyncServiceState(false, false);
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> SyncServiceFactory.setInstanceForTesting(mMockSyncService));
-
-        // This initializes the browser, so some tests can do setup before PasswordSettings is
-        // launched. ChromeTabbedActivityTestRule.startMainActivityOnBlankPage() is more commonly
-        // used for this end, but using another settings activity instead makes these tests more
-        // isolated, i.e. avoids exercising unnecessary logic. BlankUiTestActivityTestCase also
-        // won't fit here, it doesn't initialize enough of the browser.
-        Bundle fragmentArgs = new Bundle();
-        fragmentArgs.putInt(
-                PasswordManagerHelper.MANAGE_PASSWORDS_REFERRER,
-                ManagePasswordsReferrer.CHROME_SETTINGS);
-        mPasswordSettingsActivityTestRule.startSettingsActivity(fragmentArgs);
-        mPasswordSettingsActivityTestRule.finishActivity();
-    }
-
-    @After
-    public void tearDown() {
-        mTestHelper.tearDown();
-    }
-
-    /** Ensure that resetting of empty passwords list works. */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    public void testResetListEmpty() {
-        // Load the preferences, they should show the empty list.
-        mTestHelper.startPasswordSettingsFromMainSettings(mPasswordSettingsActivityTestRule);
-        onViewWaiting(withText(R.string.password_manager_settings_title));
-
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    PasswordSettings savePasswordPreferences =
-                            mPasswordSettingsActivityTestRule.getFragment();
-                    // Emulate an update from PasswordStore. This should not crash.
-                    savePasswordPreferences.passwordListAvailable(0);
-                });
-    }
-
-    /**
-     * Ensure that the on/off switch in "Save Passwords" settings actually enables and disables
-     * password saving.
-     */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    public void testSavePasswordsSwitch() {
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    getPrefService().setBoolean(Pref.CREDENTIALS_ENABLE_SERVICE, true);
-                });
-
-        mTestHelper.startPasswordSettingsFromMainSettings(mPasswordSettingsActivityTestRule);
-        onViewWaiting(withText(R.string.password_manager_settings_title));
-
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    PasswordSettings savedPasswordPrefs =
-                            mPasswordSettingsActivityTestRule.getFragment();
-                    ChromeSwitchPreference onOffSwitch =
-                            (ChromeSwitchPreference)
-                                    savedPasswordPrefs.findPreference(
-                                            PasswordSettings.PREF_SAVE_PASSWORDS_SWITCH);
-                    assertTrue(onOffSwitch.isChecked());
-
-                    onOffSwitch.performClick();
-                    assertFalse(getPrefService().getBoolean(Pref.CREDENTIALS_ENABLE_SERVICE));
-
-                    onOffSwitch.performClick();
-                    assertTrue(getPrefService().getBoolean(Pref.CREDENTIALS_ENABLE_SERVICE));
-                });
-
-        mPasswordSettingsActivityTestRule.finishActivity();
-
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    getPrefService().setBoolean(Pref.CREDENTIALS_ENABLE_SERVICE, false);
-                });
-
-        mTestHelper.startPasswordSettingsFromMainSettings(mPasswordSettingsActivityTestRule);
-        onViewWaiting(withText(R.string.password_manager_settings_title));
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    PasswordSettings savedPasswordPrefs =
-                            mPasswordSettingsActivityTestRule.getFragment();
-                    ChromeSwitchPreference onOffSwitch =
-                            (ChromeSwitchPreference)
-                                    savedPasswordPrefs.findPreference(
-                                            PasswordSettings.PREF_SAVE_PASSWORDS_SWITCH);
-                    assertFalse(onOffSwitch.isChecked());
-                });
-    }
-
-    /**
-     * Tests that the link pointing to managing passwords in the user's account is not displayed for
-     * non signed in users.
-     */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    public void testManageAccountLinkNotSignedIn() {
-        // Add a password entry, because the link is only displayed if the password list is not
-        // empty.
-        mTestHelper.setPasswordSource(
-                new SavedPasswordEntry("https://example.com", "test user", "password"));
-        mTestHelper.startPasswordSettingsFromMainSettings(mPasswordSettingsActivityTestRule);
-        PasswordSettings savedPasswordPrefs = mPasswordSettingsActivityTestRule.getFragment();
-        Assert.assertNull(
-                savedPasswordPrefs.findPreference(PasswordSettings.PREF_KEY_MANAGE_ACCOUNT_LINK));
-    }
-
-    /**
-     * Tests that the link pointing to managing passwords in the user's account is not displayed for
-     * signed in users, not syncing passwords.
-     */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    public void testManageAccountLinkSignedInNotSyncing() {
-        // Add a password entry, because the link is only displayed if the password list is not
-        // empty.
-        mTestHelper.setPasswordSource(
-                new SavedPasswordEntry("https://example.com", "test user", "password"));
-        setSyncServiceState(false, false);
-
-        mTestHelper.startPasswordSettingsFromMainSettings(mPasswordSettingsActivityTestRule);
-        PasswordSettings savedPasswordPrefs = mPasswordSettingsActivityTestRule.getFragment();
-
-        Assert.assertNull(
-                savedPasswordPrefs.findPreference(PasswordSettings.PREF_KEY_MANAGE_ACCOUNT_LINK));
-    }
-
-    /**
-     * Tests that the link pointing to managing passwords in the user's account is displayed for
-     * users syncing passwords.
-     */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    public void testManageAccountLinkSyncing() {
-        // Add a password entry, because the link is only displayed if the password list is not
-        // empty.
-        mTestHelper.setPasswordSource(
-                new SavedPasswordEntry("https://example.com", "test user", "password"));
-        setSyncServiceState(false, true);
-
-        mTestHelper.startPasswordSettingsFromMainSettings(mPasswordSettingsActivityTestRule);
-        PasswordSettings savedPasswordPrefs = mPasswordSettingsActivityTestRule.getFragment();
-
-        Assert.assertNotNull(
-                savedPasswordPrefs.findPreference(PasswordSettings.PREF_KEY_MANAGE_ACCOUNT_LINK));
-    }
-
-    /**
-     * Tests that the link pointing to managing passwords in the user's account is not displayed for
-     * users syncing passwords with custom passphrase.
-     */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    public void testManageAccountLinkSyncingWithPassphrase() {
-        // Add a password entry, because the link is only displayed if the password list is not
-        // empty.
-        mTestHelper.setPasswordSource(
-                new SavedPasswordEntry("https://example.com", "test user", "password"));
-        setSyncServiceState(true, true);
-
-        mTestHelper.startPasswordSettingsFromMainSettings(mPasswordSettingsActivityTestRule);
-        PasswordSettings savedPasswordPrefs = mPasswordSettingsActivityTestRule.getFragment();
-
-        Assert.assertNull(
-                savedPasswordPrefs.findPreference(PasswordSettings.PREF_KEY_MANAGE_ACCOUNT_LINK));
-    }
-
-    /**
-     * Ensure that the "Auto Sign-in" switch in "Save Passwords" settings actually enables and
-     * disables auto sign-in.
-     */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    public void testAutoSignInCheckbox() {
-        mAutomotiveContextWrapperTestRule.setIsAutomotive(false);
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    getPrefService().setBoolean(Pref.CREDENTIALS_ENABLE_AUTOSIGNIN, true);
-                });
-
-        mTestHelper.startPasswordSettingsFromMainSettings(mPasswordSettingsActivityTestRule);
-
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    PasswordSettings passwordPrefs =
-                            mPasswordSettingsActivityTestRule.getFragment();
-                    ChromeSwitchPreference onOffSwitch =
-                            (ChromeSwitchPreference)
-                                    passwordPrefs.findPreference(
-                                            PasswordSettings.PREF_AUTOSIGNIN_SWITCH);
-                    assertTrue(onOffSwitch.isChecked());
-
-                    onOffSwitch.performClick();
-                    assertFalse(getPrefService().getBoolean(Pref.CREDENTIALS_ENABLE_AUTOSIGNIN));
-
-                    onOffSwitch.performClick();
-                    assertTrue(getPrefService().getBoolean(Pref.CREDENTIALS_ENABLE_AUTOSIGNIN));
-                });
-
-        mPasswordSettingsActivityTestRule.finishActivity();
-
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    getPrefService().setBoolean(Pref.CREDENTIALS_ENABLE_AUTOSIGNIN, false);
-                });
-
-        mTestHelper.startPasswordSettingsFromMainSettings(mPasswordSettingsActivityTestRule);
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    PasswordSettings passwordPrefs =
-                            mPasswordSettingsActivityTestRule.getFragment();
-                    ChromeSwitchPreference onOffSwitch =
-                            (ChromeSwitchPreference)
-                                    passwordPrefs.findPreference(
-                                            PasswordSettings.PREF_AUTOSIGNIN_SWITCH);
-                    assertFalse(onOffSwitch.isChecked());
-                });
-    }
-
-    /**
-     * Ensure that the "Auto Sign-in" switch in "Save Passwords" settings is not present on
-     * automotive.
-     */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    public void testAutoSignInCheckboxIsNotPresentOnAutomotive() {
-        mAutomotiveContextWrapperTestRule.setIsAutomotive(true);
-
-        mTestHelper.startPasswordSettingsFromMainSettings(mPasswordSettingsActivityTestRule);
-
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    PasswordSettings passwordPrefs =
-                            mPasswordSettingsActivityTestRule.getFragment();
-                    ChromeSwitchPreference onOffSwitch =
-                            (ChromeSwitchPreference)
-                                    passwordPrefs.findPreference(
-                                            PasswordSettings.PREF_AUTOSIGNIN_SWITCH);
-                    assertNull("There should be no autosignin switch.", onOffSwitch);
-                });
-    }
-
-    /** Check that the check passwords preference is shown. */
-    @Test
-    @SmallTest
-    @Feature({"Preferences"})
-    public void testCheckPasswordsEnabled() {
-        mTestHelper.startPasswordSettingsFromMainSettings(mPasswordSettingsActivityTestRule);
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    PasswordSettings passwordPrefs =
-                            mPasswordSettingsActivityTestRule.getFragment();
-                    Assert.assertNotNull(
-                            passwordPrefs.findPreference(PasswordSettings.PREF_CHECK_PASSWORDS));
-                });
-    }
-
-    @Test
-    @MediumTest
-    @Feature({"Preferences"})
-    public void testDestroysPasswordCheckIfFirstInSettingsStack() {
-        setSyncServiceState(true, true);
-        mTestHelper.startPasswordSettingsDirectly(mPasswordSettingsActivityTestRule);
-        mPasswordSettingsActivityTestRule.finishActivity();
-        Assert.assertNull(PasswordCheckFactory.getPasswordCheckInstance());
-    }
-
-    @Test
-    @MediumTest
-    @Feature({"Preferences"})
-    public void testDoesNotDestroyPasswordCheckIfNotFirstInSettingsStack() {
-        setSyncServiceState(true, true);
-        mTestHelper.startPasswordSettingsFromMainSettings(mPasswordSettingsActivityTestRule);
-        mPasswordSettingsActivityTestRule.finishActivity();
-        Assert.assertNotNull(PasswordCheckFactory.getPasswordCheckInstance());
-        // Clean up the password check component.
-        PasswordCheckFactory.destroy();
-    }
-
-    private static PrefService getPrefService() {
-        return UserPrefs.get(ProfileManager.getLastUsedRegularProfile());
-    }
-
-    private void setSyncServiceState(
-            final boolean usingCustomPassphrase, final boolean syncingPasswords) {
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    when(mMockSyncService.hasSyncConsent()).thenReturn(syncingPasswords);
-                    when(mMockSyncService.isEngineInitialized()).thenReturn(true);
-                    when(mMockSyncService.isUsingExplicitPassphrase())
-                            .thenReturn(usingCustomPassphrase);
-                    when(mMockSyncService.getPassphraseType())
-                            .thenReturn(
-                                    usingCustomPassphrase
-                                            ? PassphraseType.CUSTOM_PASSPHRASE
-                                            : PassphraseType.KEYSTORE_PASSPHRASE);
-                    Integer elements = syncingPasswords ? DataType.PASSWORDS : DataType.AUTOFILL;
-                    when(mMockSyncService.getActiveDataTypes()).thenReturn(Set.of(elements));
-                });
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTestHelper.java b/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTestHelper.java
deleted file mode 100644
index 7cd9f55..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettingsTestHelper.java
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2021 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.password_manager.settings;
-
-import android.os.Bundle;
-import android.view.View;
-
-import androidx.preference.PreferenceViewHolder;
-import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-import androidx.test.espresso.matcher.BoundedMatcher;
-
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.util.ApplicationTestUtils;
-import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
-import org.chromium.chrome.browser.password_manager.FakePasswordManagerHandler;
-import org.chromium.chrome.browser.password_manager.ManagePasswordsReferrer;
-import org.chromium.chrome.browser.password_manager.PasswordManagerHelper;
-import org.chromium.chrome.browser.profiles.ProfileManager;
-import org.chromium.chrome.browser.settings.SettingsActivity;
-import org.chromium.chrome.browser.settings.SettingsActivityTestRule;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/** Helper functions used in various password settings test suites. */
-class PasswordSettingsTestHelper {
-    static final SavedPasswordEntry ZEUS_ON_EARTH =
-            new SavedPasswordEntry("http://www.phoenicia.gr", "Zeus", "Europa");
-    static final SavedPasswordEntry ARES_AT_OLYMP =
-            new SavedPasswordEntry("https://1-of-12.olymp.gr", "Ares", "God-o'w@r");
-    static final SavedPasswordEntry PHOBOS_AT_OLYMP =
-            new SavedPasswordEntry("https://visitor.olymp.gr", "Phobos-son-of-ares", "G0d0fF34r");
-    static final SavedPasswordEntry DEIMOS_AT_OLYMP =
-            new SavedPasswordEntry("https://visitor.olymp.gr", "Deimops-Ares-son", "G0d0fT3rr0r");
-    static final SavedPasswordEntry HADES_AT_UNDERWORLD =
-            new SavedPasswordEntry("https://underworld.gr", "", "C3rb3rus");
-    static final SavedPasswordEntry[] GREEK_GODS = {
-        ZEUS_ON_EARTH, ARES_AT_OLYMP, PHOBOS_AT_OLYMP, DEIMOS_AT_OLYMP, HADES_AT_UNDERWORLD,
-    };
-
-    private SettingsActivity mActivityToCleanUp;
-
-    /**
-     * Used to provide fake lists of stored passwords. Tests which need it can use setPasswordSource
-     */
-    private FakePasswordManagerHandler mHandler;
-
-    /**
-     * Delayer controlling hiding the progress bar during exporting passwords. This replaces a time
-     * delay used in production.
-     */
-    private final ManualCallbackDelayer mManualDelayer = new ManualCallbackDelayer();
-
-    void tearDown() {
-        try {
-            ApplicationTestUtils.finishActivity(mActivityToCleanUp);
-        } catch (Exception e) {
-            // Activity was already finished by test framework. Any exception is not test-related.
-        }
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    if (!ProfileManager.isInitialized()) return;
-                    PasswordManagerHandlerProvider.getForProfile(
-                                    ProfileManager.getLastUsedRegularProfile())
-                            .resetPasswordManagerHandlerForTest();
-                });
-        setPasswordSource(null);
-    }
-
-    ManualCallbackDelayer getManualDelayer() {
-        return mManualDelayer;
-    }
-
-    FakePasswordManagerHandler getHandler() {
-        return mHandler;
-    }
-
-    /**
-     * Helper to set up a fake source of displayed passwords.
-     *
-     * @param entry An entry to be added to saved passwords. Can be null.
-     */
-    void setPasswordSource(SavedPasswordEntry entry) {
-        SavedPasswordEntry[] entries = {};
-        if (entry != null) {
-            entries = new SavedPasswordEntry[] {entry};
-        }
-        setPasswordSourceWithMultipleEntries(entries);
-    }
-
-    /**
-     * Helper to set up a fake source of displayed passwords with multiple initial passwords.
-     *
-     * @param initialEntries All entries to be added to saved passwords. Can not be null.
-     */
-    void setPasswordSourceWithMultipleEntries(SavedPasswordEntry[] initialEntries) {
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    if (!ChromeBrowserInitializer.getInstance().isFullBrowserInitialized()) {
-                        ChromeBrowserInitializer.getInstance().handleSynchronousStartup();
-                    }
-                });
-
-        PasswordManagerHandlerProvider handlerProvider =
-                ThreadUtils.runOnUiThreadBlocking(
-                        () ->
-                                PasswordManagerHandlerProvider.getForProfile(
-                                        ProfileManager.getLastUsedRegularProfile()));
-        if (mHandler == null) {
-            mHandler = new FakePasswordManagerHandler(handlerProvider);
-        }
-        ArrayList<SavedPasswordEntry> entries = new ArrayList<>(Arrays.asList(initialEntries));
-        mHandler.setSavedPasswords(entries);
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> handlerProvider.setPasswordManagerHandlerForTest(mHandler));
-    }
-
-    /**
-     * Helper to set up a fake source of displayed passwords without passwords but with exceptions.
-     *
-     * @param exceptions All exceptions to be added to saved exceptions. Can not be null.
-     */
-    void setPasswordExceptions(String[] exceptions) {
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    if (!ChromeBrowserInitializer.getInstance().isFullBrowserInitialized()) {
-                        ChromeBrowserInitializer.getInstance().handleSynchronousStartup();
-                    }
-                });
-
-        PasswordManagerHandlerProvider handlerProvider =
-                ThreadUtils.runOnUiThreadBlocking(
-                        () ->
-                                PasswordManagerHandlerProvider.getForProfile(
-                                        ProfileManager.getLastUsedRegularProfile()));
-        if (mHandler == null) {
-            mHandler = new FakePasswordManagerHandler(handlerProvider);
-        }
-        mHandler.setSavedPasswordExceptions(new ArrayList<>(Arrays.asList(exceptions)));
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> handlerProvider.setPasswordManagerHandlerForTest(mHandler));
-    }
-
-    SettingsActivity startPasswordSettingsFromMainSettings(
-            SettingsActivityTestRule<PasswordSettings> testRule) {
-        Bundle fragmentArgs = new Bundle();
-        fragmentArgs.putInt(
-                PasswordManagerHelper.MANAGE_PASSWORDS_REFERRER,
-                ManagePasswordsReferrer.CHROME_SETTINGS);
-        mActivityToCleanUp = testRule.startSettingsActivity(fragmentArgs);
-        return mActivityToCleanUp;
-    }
-
-    SettingsActivity startPasswordSettingsDirectly(
-            SettingsActivityTestRule<PasswordSettings> testRule) {
-        Bundle fragmentArgs = new Bundle();
-        // The passwords accessory sheet is one of the places that can launch password settings
-        // directly (without passing through main settings).
-        fragmentArgs.putInt(
-                PasswordManagerHelper.MANAGE_PASSWORDS_REFERRER,
-                ManagePasswordsReferrer.PASSWORDS_ACCESSORY_SHEET);
-        mActivityToCleanUp = testRule.startSettingsActivity(fragmentArgs);
-        return mActivityToCleanUp;
-    }
-
-    /**
-     * Returns a matcher that checks whether a given view contains another view with the given text.
-     *
-     * @param text The text that the view holder has in its view hierarchy.
-     * @return A Matcher to find a particular {@link ViewHolder} that contains certain text.
-     */
-    static Matcher<ViewHolder> hasTextInViewHolder(String text) {
-        return new BoundedMatcher<>(PreferenceViewHolder.class) {
-            @Override
-            public void describeTo(Description description) {
-                description.appendText("has text: " + text);
-            }
-
-            @Override
-            protected boolean matchesSafely(PreferenceViewHolder preferenceViewHolder) {
-                ArrayList<View> outViews = new ArrayList<>();
-                preferenceViewHolder.itemView.findViewsWithText(
-                        outViews, text, View.FIND_VIEWS_WITH_TEXT);
-                return !outViews.isEmpty();
-            }
-        };
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordViewingTypeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordViewingTypeTest.java
deleted file mode 100644
index ff56edb..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/settings/PasswordViewingTypeTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2016 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.password_manager.settings;
-
-import static org.mockito.Mockito.when;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.RuleChain;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.BaseJUnit4ClassRunner;
-import org.chromium.base.test.util.Feature;
-import org.chromium.chrome.browser.settings.MainSettings;
-import org.chromium.chrome.browser.settings.SettingsActivityTestRule;
-import org.chromium.chrome.browser.sync.SyncServiceFactory;
-import org.chromium.chrome.test.ChromeBrowserTestRule;
-import org.chromium.components.browser_ui.settings.ChromeBasePreference;
-import org.chromium.components.sync.SyncService;
-
-/**
- * Tests for verifying whether users are presented with the correct option of viewing passwords
- * according to the user group they belong to (syncing with sync passphrase, syncing without sync
- * passsphrase, non-syncing).
- */
-@RunWith(BaseJUnit4ClassRunner.class)
-public class PasswordViewingTypeTest {
-    private final ChromeBrowserTestRule mChromeBrowserTestRule = new ChromeBrowserTestRule();
-
-    private final SettingsActivityTestRule<MainSettings> mSettingsActivityTestRule =
-            new SettingsActivityTestRule<>(MainSettings.class);
-
-    // We need to destroy the SettingsActivity before tearing down the mock sign-in environment
-    // setup in ChromeBrowserTestRule to avoid code crash.
-    @Rule
-    public final RuleChain mRuleChain =
-            RuleChain.outerRule(mChromeBrowserTestRule).around(mSettingsActivityTestRule);
-
-    @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
-
-    private ChromeBasePreference mPasswordsPref;
-    @Mock private SyncService mSyncService;
-
-    @Before
-    public void setUp() {
-        mChromeBrowserTestRule.addAccount("account@example.com");
-        mSettingsActivityTestRule.startSettingsActivity();
-        MainSettings mainSettings = mSettingsActivityTestRule.getFragment();
-        mPasswordsPref =
-                (ChromeBasePreference) mainSettings.findPreference(MainSettings.PREF_PASSWORDS);
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> SyncServiceFactory.setInstanceForTesting(mSyncService));
-    }
-
-    /**
-     * Verifies that sync settings are being set up correctly in the case of redirecting users.
-     * Checks that sync users are allowed to view passwords natively.
-     */
-    @Test
-    @SmallTest
-    @Feature({"Sync"})
-    public void testUserRedirectSyncSettings() {
-        when(mSyncService.isSyncFeatureEnabled()).thenReturn(true);
-        when(mSyncService.isEngineInitialized()).thenReturn(true);
-        when(mSyncService.isUsingExplicitPassphrase()).thenReturn(false);
-
-        Assert.assertEquals(
-                PasswordSettings.class.getCanonicalName(), mPasswordsPref.getFragment());
-    }
-
-    /**
-     * Verifies that syncing users with a custom passphrase are allowed to natively view passwords.
-     */
-    @Test
-    @SmallTest
-    public void testSyncingNativePasswordView() {
-        when(mSyncService.isSyncFeatureEnabled()).thenReturn(true);
-        when(mSyncService.isEngineInitialized()).thenReturn(true);
-        when(mSyncService.isUsingExplicitPassphrase()).thenReturn(true);
-
-        Assert.assertEquals(
-                PasswordSettings.class.getCanonicalName(), mPasswordsPref.getFragment());
-        Assert.assertNotNull(mSettingsActivityTestRule.getActivity().getIntent());
-    }
-
-    /** Verifies that non-syncing users are allowed to natively view passwords. */
-    @Test
-    @SmallTest
-    public void testNonSyncingNativePasswordView() {
-        when(mSyncService.isSyncFeatureEnabled()).thenReturn(false);
-        when(mSyncService.isEngineInitialized()).thenReturn(false);
-        when(mSyncService.isUsingExplicitPassphrase()).thenReturn(false);
-
-        Assert.assertEquals(
-                PasswordSettings.class.getCanonicalName(), mPasswordsPref.getFragment());
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java
index 51be9fd..60a0a62 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java
@@ -100,7 +100,6 @@
 import org.chromium.chrome.browser.password_check.PasswordCheckFactory;
 import org.chromium.chrome.browser.password_manager.PasswordManagerUtilBridge;
 import org.chromium.chrome.browser.password_manager.PasswordManagerUtilBridgeJni;
-import org.chromium.chrome.browser.password_manager.settings.PasswordSettings;
 import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.ChromeSharedPreferences;
 import org.chromium.chrome.browser.privacy.settings.PrivacySettings;
@@ -301,7 +300,7 @@
         assertSettingsExists(MainSettings.PREF_SEARCH_ENGINE, SearchEngineSettings.class);
         assertSettingsExists(MainSettings.PREF_AUTOFILL_OPTIONS, null);
         assertSettingsExists(MainSettings.PREF_AUTOFILL_SECTION, null);
-        assertSettingsExists(MainSettings.PREF_PASSWORDS, PasswordSettings.class);
+        assertSettingsExists(MainSettings.PREF_PASSWORDS, null);
         assertSettingsExists("autofill_payment_methods", AutofillPaymentMethodsFragment.class);
         assertSettingsExists("autofill_addresses", AutofillProfilesFragment.class);
         if (supportNotificationSettings()) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/settings/IdentityErrorCardPreferenceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/settings/IdentityErrorCardPreferenceTest.java
index 9fece1b..9f0fe4c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/settings/IdentityErrorCardPreferenceTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/settings/IdentityErrorCardPreferenceTest.java
@@ -249,8 +249,7 @@
     @Test
     @LargeTest
     public void testIdentityErrorCardNotShownForUnrecoverableErrors() throws Exception {
-        mFakeSyncServiceImpl.setAuthError(
-                new GoogleServiceAuthError(GoogleServiceAuthErrorState.CONNECTION_FAILED));
+        mFakeSyncServiceImpl.setHasUnrecoverableError(true);
         mSigninTestRule.addTestAccountThenSignin();
 
         mSettingsActivityTestRule.startSettingsActivity();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtilsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtilsTest.java
index 416f35c..e64e3bd7 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtilsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtilsTest.java
@@ -135,10 +135,7 @@
     @SmallTest
     public void testGetSyncError_unrecoverableError() {
         Mockito.when(mSyncService.hasSyncConsent()).thenReturn(true);
-        Mockito.when(mSyncService.getAuthError())
-                .thenReturn(
-                        new GoogleServiceAuthError(
-                                GoogleServiceAuthErrorState.SERVICE_UNAVAILABLE));
+        Mockito.when(mSyncService.hasUnrecoverableError()).thenReturn(true);
 
         ThreadUtils.runOnUiThreadBlocking(
                 () -> {
diff --git a/chrome/android/junit/BUILD.gn b/chrome/android/junit/BUILD.gn
index 6a4455b..962c711 100644
--- a/chrome/android/junit/BUILD.gn
+++ b/chrome/android/junit/BUILD.gn
@@ -879,10 +879,6 @@
     sources = [
       "src/org/chromium/chrome/browser/password_manager/PasswordCheckupLauncherTest.java",
       "src/org/chromium/chrome/browser/password_manager/PasswordManagerErrorMessageHelperBridgeTest.java",
-      "src/org/chromium/chrome/browser/password_manager/settings/DialogManagerTest.java",
-      "src/org/chromium/chrome/browser/password_manager/settings/EnsureAsyncPostingRule.java",
-      "src/org/chromium/chrome/browser/password_manager/settings/SingleThreadBarrierClosureTest.java",
-      "src/org/chromium/chrome/browser/password_manager/settings/TimedCallbackDelayerTest.java",
     ]
 
     deps = [ ":chrome_junit_tests_helper" ]
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarUnitTest.java
index 84c7986..21a82fd3 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarUnitTest.java
@@ -91,6 +91,8 @@
 import org.chromium.chrome.browser.omnibox.UrlBarData;
 import org.chromium.chrome.browser.omnibox.status.PageInfoIphController;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider;
+import org.chromium.chrome.browser.theme.ThemeColorProvider;
 import org.chromium.chrome.browser.toolbar.LocationBarModel;
 import org.chromium.chrome.browser.toolbar.ToolbarDataProvider;
 import org.chromium.chrome.browser.toolbar.ToolbarProgressBar;
@@ -156,6 +158,8 @@
     private @Mock PageInfoIphController mPageInfoIphController;
     @Mock private BrowserServicesIntentDataProvider mIntentDataProvider;
     @Mock private CustomTabMinimizeDelegate mMinimizeDelegate;
+    @Mock private ThemeColorProvider mThemeColorProvider;
+    @Mock private IncognitoStateProvider mIncognitoStateProvider;
     @Captor ArgumentCaptor<AppMenuObserver> mAppMenuObserverCaptor;
 
     private Activity mActivity;
@@ -220,7 +224,9 @@
                 null,
                 null,
                 /* homeButtonDisplay= */ null,
-                null);
+                null,
+                mThemeColorProvider,
+                mIncognitoStateProvider);
         if (!ChromeFeatureList.sCctToolbarRefactor.isEnabled()) {
             mToolbar.initVisibilityRule(mActivity, () -> mAppMenuHandler, mIntentDataProvider);
         }
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 7445a84f..ff02076 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -2535,7 +2535,6 @@
     "//components/webapps/browser",
     "//components/webapps/common",
     "//components/webapps/common:mojo_bindings",
-    "//components/webapps/isolated_web_apps",
     "//components/webauthn/core/browser:passkey_model",
     "//components/webdata/common",
     "//components/webdata_services",
@@ -3235,8 +3234,6 @@
       "password_manager/android/password_manager_launcher_android.cc",
       "password_manager/android/password_store_bridge.cc",
       "password_manager/android/password_store_bridge.h",
-      "password_manager/android/password_ui_view_android.cc",
-      "password_manager/android/password_ui_view_android.h",
       "password_manager/android/save_update_password_message_delegate.cc",
       "password_manager/android/save_update_password_message_delegate.h",
       "payments/android/service_worker_payment_app_bridge.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 1dde07ad..0f7f5a42 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -4796,6 +4796,10 @@
          std::size(kAndroidTabDeclutterAutoDeleteTesting), nullptr}};
 #endif  // BUILDFLAG(IS_ANDROID)
 
+#if !BUILDFLAG(IS_ANDROID)
+constexpr char kWebiumFlag[] = "webium";
+#endif  // !BUILDFLAG(IS_ANDROID)
+
 // RECORDING USER METRICS FOR FLAGS:
 // -----------------------------------------------------------------------------
 // The first line of the entry is the internal name.
@@ -13027,6 +13031,13 @@
          autofill::features::kAutofillAndroidDesktopSuppressAccessoryOnEmpty)},
 #endif  // BUILDFLAG(IS_ANDROID)
 
+#if !BUILDFLAG(IS_ANDROID)
+    {kWebiumFlag,
+     flag_descriptions::kWebiumName,
+     flag_descriptions::kWebiumDescription, kOsDesktop,
+     FEATURE_VALUE_TYPE(features::kWebium)},
+#endif  // !BUILDFLAG(IS_ANDROID)
+
     // Add new entries above this line.
 
     // NOTE: Adding a new flag requires adding a corresponding entry to enum
@@ -13255,6 +13266,15 @@
            channel != version_info::Channel::UNKNOWN;
   }
 #endif  // BUILDFLAG(IS_ANDROID)
+
+#if !BUILDFLAG(IS_ANDROID)
+  // Only show Webium flag for Canary channel and developer builds.
+  if (!strcmp(kWebiumFlag, entry.internal_name)) {
+    return chrome::GetChannel() != version_info::Channel::CANARY &&
+           version_info::IsOfficialBuild();
+  }
+#endif  // !BUILDFLAG(IS_ANDROID)
+
   if (flags::IsFlagExpired(storage, entry.internal_name)) {
     return true;
   }
diff --git a/chrome/browser/actor/actor_navigation_throttle.cc b/chrome/browser/actor/actor_navigation_throttle.cc
index 2d0efc7..604e991 100644
--- a/chrome/browser/actor/actor_navigation_throttle.cc
+++ b/chrome/browser/actor/actor_navigation_throttle.cc
@@ -86,13 +86,14 @@
   AggregatedJournal& journal = GetJournal();
 
   if (!is_redirection && !initiator_origin) {
-    journal.Log(navigation_url, task_id_, "NavThrottle",
-                "Proceed: not triggered by page");
+    journal.Log(navigation_url, task_id_, mojom::JournalTrack::kActor,
+                "NavThrottle", "Proceed: not triggered by page");
     return content::NavigationThrottle::PROCEED;
   }
 
   if (initiator_origin && initiator_origin->IsSameOriginWith(navigation_url)) {
-    journal.Log(navigation_url, task_id_, "NavThrottle",
+    journal.Log(navigation_url, task_id_, mojom::JournalTrack::kActor,
+                "NavThrottle",
                 is_redirection ? "Proceed: same origin redirect"
                                : "Proceed: same origin navigation");
     // This isn't needed for correctness. We know that if the actor triggered a
@@ -102,7 +103,7 @@
   }
 
   auto journal_entry = journal.CreatePendingAsyncEntry(
-      navigation_url, task_id_, "NavThrottle",
+      navigation_url, task_id_, mojom::JournalTrack::kActor, "NavThrottle",
       is_redirection ? "Defer: check redirect safety"
                      : "Defer: check navigation safety");
 
diff --git a/chrome/browser/actor/aggregated_journal.cc b/chrome/browser/actor/aggregated_journal.cc
index 49652c8..1255e342 100644
--- a/chrome/browser/actor/aggregated_journal.cc
+++ b/chrome/browser/actor/aggregated_journal.cc
@@ -73,19 +73,19 @@
     : url(location), data(std::move(data_arg)) {}
 AggregatedJournal::Entry::~Entry() = default;
 
-AggregatedJournal::AggregatedJournal() : next_trace_id_(base::RandUint64()) {}
+AggregatedJournal::AggregatedJournal() = default;
 AggregatedJournal::~AggregatedJournal() = default;
 
 AggregatedJournal::PendingAsyncEntry::PendingAsyncEntry(
     base::PassKey<AggregatedJournal> pass_key,
     base::SafeRef<AggregatedJournal> journal,
     TaskId task_id,
-    uint64_t trace_id,
+    mojom::JournalTrack track,
     std::string_view event_name)
     : pass_key_(pass_key),
       journal_(journal),
       task_id_(task_id),
-      trace_id_(trace_id),
+      track_(track),
       event_name_(event_name) {}
 
 AggregatedJournal::PendingAsyncEntry::~PendingAsyncEntry() {
@@ -98,7 +98,7 @@
   CHECK(!terminated_);
   terminated_ = true;
   ACTOR_LOG() << "End " << event_name_ << ": " << details;
-  journal_->AddEndEvent(pass_key_, task_id_, trace_id_, event_name_, details);
+  journal_->AddEndEvent(pass_key_, task_id_, track_, event_name_, details);
 }
 
 AggregatedJournal& AggregatedJournal::PendingAsyncEntry::GetJournal() {
@@ -116,30 +116,31 @@
 std::unique_ptr<AggregatedJournal::PendingAsyncEntry>
 AggregatedJournal::CreatePendingAsyncEntry(const GURL& url,
                                            TaskId task_id,
+                                           mojom::JournalTrack track,
                                            std::string_view event_name,
                                            std::string_view details) {
   ACTOR_LOG() << "Begin " << event_name << ": " << details;
 
-  uint64_t trace_id = next_trace_id_++;
   AddEntry(std::make_unique<Entry>(
       url.possibly_invalid_spec(),
       mojom::JournalEntry::New(
-          mojom::JournalEntryType::kBegin, task_id.GetUnsafeValue(), trace_id,
+          mojom::JournalEntryType::kBegin, task_id.GetUnsafeValue(), track,
           base::Time::Now(), std::string(event_name), std::string(details))));
   return base::WrapUnique(new PendingAsyncEntry(
       base::PassKey<AggregatedJournal>(), weak_ptr_factory_.GetSafeRef(),
-      task_id, trace_id, event_name));
+      task_id, track, event_name));
 }
 
 void AggregatedJournal::Log(const GURL& url,
                             TaskId task_id,
+                            mojom::JournalTrack track,
                             std::string_view event_name,
                             std::string_view details) {
   ACTOR_LOG() << event_name << ": " << details;
   AddEntry(std::make_unique<Entry>(
       url.possibly_invalid_spec(),
       mojom::JournalEntry::New(
-          mojom::JournalEntryType::kInstant, task_id.GetUnsafeValue(), /*id=*/0,
+          mojom::JournalEntryType::kInstant, task_id.GetUnsafeValue(), track,
           base::Time::Now(), std::string(event_name), std::string(details))));
 }
 
@@ -175,14 +176,13 @@
 
 void AggregatedJournal::AddEndEvent(base::PassKey<AggregatedJournal> pass_key,
                                     TaskId task_id,
-                                    uint64_t trace_id,
+                                    mojom::JournalTrack track,
                                     const std::string& event_name,
                                     std::string_view details) {
   AddEntry(std::make_unique<Entry>(
-      std::string(),
-      mojom::JournalEntry::New(mojom::JournalEntryType::kEnd, task_id.value(),
-                               trace_id, base::Time::Now(), event_name,
-                               std::string(details))));
+      std::string(), mojom::JournalEntry::New(
+                         mojom::JournalEntryType::kEnd, task_id.value(), track,
+                         base::Time::Now(), event_name, std::string(details))));
 }
 
 void AggregatedJournal::LogScreenshot(const GURL& url,
@@ -193,8 +193,9 @@
   auto entry = std::make_unique<Entry>(
       url.possibly_invalid_spec(),
       mojom::JournalEntry::New(mojom::JournalEntryType::kInstant,
-                               task_id.value(), /*id=*/0, base::Time::Now(),
-                               "Screenshot", /*details=*/std::string()));
+                               task_id.value(), mojom::JournalTrack::kActor,
+                               base::Time::Now(), "Screenshot",
+                               /*details=*/std::string()));
   entry->jpg_screenshot.emplace(data.begin(), data.end());
   AddEntry(std::move(entry));
 }
@@ -206,8 +207,9 @@
   auto entry = std::make_unique<Entry>(
       url.possibly_invalid_spec(),
       mojom::JournalEntry::New(mojom::JournalEntryType::kInstant,
-                               task_id.value(), /*id=*/0, base::Time::Now(),
-                               "PageContext", /*details=*/std::string()));
+                               task_id.value(), mojom::JournalTrack::kActor,
+                               base::Time::Now(), "PageContext",
+                               /*details=*/std::string()));
   entry->annotated_page_content.emplace(data.begin(), data.end());
   AddEntry(std::move(entry));
 }
diff --git a/chrome/browser/actor/aggregated_journal.h b/chrome/browser/actor/aggregated_journal.h
index 0552266e..6170ada 100644
--- a/chrome/browser/actor/aggregated_journal.h
+++ b/chrome/browser/actor/aggregated_journal.h
@@ -49,7 +49,7 @@
     PendingAsyncEntry(base::PassKey<AggregatedJournal>,
                       base::SafeRef<AggregatedJournal> journal,
                       TaskId task_id,
-                      uint64_t trace_id,
+                      mojom::JournalTrack track,
                       std::string_view event_name);
     ~PendingAsyncEntry();
 
@@ -66,7 +66,7 @@
     bool terminated_ = false;
     base::SafeRef<AggregatedJournal> journal_;
     TaskId task_id_;
-    uint64_t trace_id_;
+    mojom::JournalTrack track_;
     std::string event_name_;
   };
 
@@ -86,12 +86,14 @@
   std::unique_ptr<PendingAsyncEntry> CreatePendingAsyncEntry(
       const GURL& url,
       TaskId task_id,
+      mojom::JournalTrack track,
       std::string_view event_name,
       std::string_view details);
 
   // Log an instant event.
   void Log(const GURL& url,
            TaskId task_id,
+           mojom::JournalTrack track,
            std::string_view event_name,
            std::string_view details);
 
@@ -114,14 +116,13 @@
   base::SafeRef<AggregatedJournal> GetSafeRef();
   void AddEndEvent(base::PassKey<AggregatedJournal>,
                    TaskId task_id,
-                   uint64_t trace_id,
+                   mojom::JournalTrack track,
                    const std::string& event_name,
                    std::string_view details);
 
  private:
   void AddEntry(std::unique_ptr<Entry>);
 
-  uint64_t next_trace_id_;
   base::ObserverList<Observer> observers_;
   EntryBuffer entries_;
   base::WeakPtrFactory<AggregatedJournal> weak_ptr_factory_{this};
diff --git a/chrome/browser/actor/aggregated_journal_serializer.cc b/chrome/browser/actor/aggregated_journal_serializer.cc
index d964874f7..ffc5c0f 100644
--- a/chrome/browser/actor/aggregated_journal_serializer.cc
+++ b/chrome/browser/actor/aggregated_journal_serializer.cc
@@ -119,7 +119,13 @@
   }
   track_event->set_type(pb_type);
   track_event->set_name(entry.data->event);
-  track_event->set_track_uuid(entry.data->task_id);
+  if (entry.data->task_id != 0) {
+    uint64_t track_uuid = entry.data->task_id;
+    if (entry.data->track == mojom::JournalTrack::kFrontEnd) {
+      track_uuid += kFrontEndId;
+    }
+    track_event->set_track_uuid(track_uuid);
+  }
 
   // For Perfetto to read screenshots we need to have the category as
   // "android_screenshot". See
diff --git a/chrome/browser/actor/aggregated_journal_unittest.cc b/chrome/browser/actor/aggregated_journal_unittest.cc
index 3fd42cc..c712a6f 100644
--- a/chrome/browser/actor/aggregated_journal_unittest.cc
+++ b/chrome/browser/actor/aggregated_journal_unittest.cc
@@ -64,7 +64,8 @@
   MockJournalObserver observer(journal);
   EXPECT_CALL(observer, WillAddJournalEntry(testing::_)).Times(1);
 
-  journal.Log(GURL(), TaskId(0), "Test", "Nothing");
+  journal.Log(GURL(), TaskId(0), mojom::JournalTrack::kActor, "Test",
+              "Nothing");
 }
 
 TEST_F(AggregatedJournalTest, SerializerInMemory) {
@@ -73,11 +74,16 @@
                                                  /*max_bytes=*/1024 * 1024);
   serializer.Init();
   auto begin_entry = journal.CreatePendingAsyncEntry(
-      GURL("http://example.com"), TaskId(), "Begin", "Entry");
-  journal.Log(GURL(), TaskId(0), "Test", "Nothing");
-  journal.Log(GURL(), TaskId(0), "Test2", "Nothing");
-  journal.Log(GURL(), TaskId(0), "Test3", "Nothing");
-  journal.Log(GURL(), TaskId(0), "Test4", "Nothing");
+      GURL("http://example.com"), TaskId(), mojom::JournalTrack::kActor,
+      "Begin", "Entry");
+  journal.Log(GURL(), TaskId(0), mojom::JournalTrack::kActor, "Test",
+              "Nothing");
+  journal.Log(GURL(), TaskId(0), mojom::JournalTrack::kActor, "Test2",
+              "Nothing");
+  journal.Log(GURL(), TaskId(0), mojom::JournalTrack::kActor, "Test3",
+              "Nothing");
+  journal.Log(GURL(), TaskId(0), mojom::JournalTrack::kActor, "Test4",
+              "Nothing");
   begin_entry.reset();
 
   std::vector<uint8_t> result = serializer.Snapshot();
@@ -92,7 +98,8 @@
   AggregatedJournal& journal = ActorKeyedService::Get(profile())->GetJournal();
   AggregatedJournalInMemorySerializer serializer(journal, /*max_bytes=*/8);
   serializer.Init();
-  journal.Log(GURL(), TaskId(0), "Test", "Nothing");
+  journal.Log(GURL(), TaskId(0), mojom::JournalTrack::kActor, "Test",
+              "Nothing");
 
   // Nothing will get logged because of the small buffer.
   std::vector<uint8_t> result = serializer.Snapshot();
@@ -104,7 +111,8 @@
   AggregatedJournalInMemorySerializer serializer(journal, /*max_bytes=*/100);
   serializer.Init();
   for (size_t i = 0; i < 10; ++i) {
-    journal.Log(GURL(), TaskId(0), "Test", "Nothing");
+    journal.Log(GURL(), TaskId(0), mojom::JournalTrack::kActor, "Test",
+                "Nothing");
   }
 
   // We should something but at most 100 bytes.
@@ -124,11 +132,16 @@
   EXPECT_TRUE(init_future.Get<bool>());
 
   auto begin_entry = journal.CreatePendingAsyncEntry(
-      GURL("http://example.com"), TaskId(), "Begin", "Entry");
-  journal.Log(GURL(), TaskId(0), "Test", "Nothing");
-  journal.Log(GURL(), TaskId(0), "Test2", "Nothing");
-  journal.Log(GURL(), TaskId(0), "Test3", "Nothing");
-  journal.Log(GURL(), TaskId(0), "Test4", "Nothing");
+      GURL("http://example.com"), TaskId(), mojom::JournalTrack::kActor,
+      "Begin", "Entry");
+  journal.Log(GURL(), TaskId(0), mojom::JournalTrack::kActor, "Test",
+              "Nothing");
+  journal.Log(GURL(), TaskId(0), mojom::JournalTrack::kActor, "Test2",
+              "Nothing");
+  journal.Log(GURL(), TaskId(0), mojom::JournalTrack::kActor, "Test3",
+              "Nothing");
+  journal.Log(GURL(), TaskId(0), mojom::JournalTrack::kActor, "Test4",
+              "Nothing");
   begin_entry.reset();
 
   base::test::TestFuture<void> shutdown_future;
diff --git a/chrome/browser/actor/execution_engine.cc b/chrome/browser/actor/execution_engine.cc
index cbb106f4..88aabb8 100644
--- a/chrome/browser/actor/execution_engine.cc
+++ b/chrome/browser/actor/execution_engine.cc
@@ -110,7 +110,8 @@
 }
 
 void ExecutionEngine::SetState(State state) {
-  journal_->Log(GURL(), task_->id(), "ExecutionEngine::StateChange",
+  journal_->Log(GURL(), task_->id(), mojom::JournalTrack::kActor,
+                "ExecutionEngine::StateChange",
                 absl::StrFormat("State %s -> %s", StateToString(state_),
                                 StateToString(state)));
 
@@ -180,7 +181,8 @@
 
   if (!action_sequence_.empty()) {
     journal_->Log(
-        actions[0]->GetURLForJournal(), task_->id(), "Act Failed",
+        actions[0]->GetURLForJournal(), task_->id(),
+        mojom::JournalTrack::kActor, "Act Failed",
         "Unable to perform action: task already has action in progress");
     PostTaskForActCallback(std::move(callback),
                            MakeResult(mojom::ActionResultCode::kError,
@@ -259,8 +261,8 @@
   tabs::TabInterface* tab = GetNextAction().GetTabHandle().Get();
 
   if (!tab) {
-    journal_->Log(GURL::EmptyGURL(), task_->id(), "Act Failed",
-                  "The tab is no longer present");
+    journal_->Log(GURL::EmptyGURL(), task_->id(), mojom::JournalTrack::kActor,
+                  "Act Failed", "The tab is no longer present");
     CompleteActions(MakeResult(mojom::ActionResultCode::kTabWentAway,
                                "The tab is no longer present."),
                     next_action_index_);
@@ -283,8 +285,8 @@
 
   tabs::TabInterface* tab = GetNextAction().GetTabHandle().Get();
   if (!tab) {
-    journal_->Log(GURL::EmptyGURL(), task_->id(), "Act Failed",
-                  "The tab is no longer present");
+    journal_->Log(GURL::EmptyGURL(), task_->id(), mojom::JournalTrack::kActor,
+                  "Act Failed", "The tab is no longer present");
     CompleteActions(MakeResult(mojom::ActionResultCode::kTabWentAway,
                                "The tab is no longer present."),
                     next_action_index_);
@@ -298,7 +300,8 @@
     // A cross-origin navigation occurred before we got permission. The result
     // is no longer applicable. For now just fail.
     // TODO(mcnee): Handle this gracefully.
-    journal_->Log(GetNextAction().GetURLForJournal(), task_id, "Act Failed",
+    journal_->Log(GetNextAction().GetURLForJournal(), task_id,
+                  mojom::JournalTrack::kActor, "Act Failed",
                   "Acting after cross-origin navigation occurred");
     CompleteActions(MakeResult(mojom::ActionResultCode::kCrossOriginNavigation,
                                "Acting after cross-origin navigation occurred"),
@@ -307,7 +310,8 @@
   }
 
   if (!may_act) {
-    journal_->Log(GetNextAction().GetURLForJournal(), task_id, "Act Failed",
+    journal_->Log(GetNextAction().GetURLForJournal(), task_id,
+                  mojom::JournalTrack::kActor, "Act Failed",
                   "URL blocked for actions");
     CompleteActions(MakeResult(mojom::ActionResultCode::kUrlBlocked,
                                "URL blocked for actions"),
@@ -404,7 +408,8 @@
     if (action_index) {
       url = action_sequence_[*action_index]->GetURLForJournal();
     }
-    journal_->Log(url, task_->id(), "Act Failed", ToDebugString(*result));
+    journal_->Log(url, task_->id(), mojom::JournalTrack::kActor, "Act Failed",
+                  ToDebugString(*result));
   }
 
   // TODO(crbug.com/411462297): Populate observation.
diff --git a/chrome/browser/actor/site_policy.cc b/chrome/browser/actor/site_policy.cc
index 4e40633..2e5ed7d 100644
--- a/chrome/browser/actor/site_policy.cc
+++ b/chrome/browser/actor/site_policy.cc
@@ -59,7 +59,11 @@
                   DecisionCallback callback)
       : callback_(std::move(callback)),
         journal_entry_(
-            journal.CreatePendingAsyncEntry(url, task_id, event_name, "")) {}
+            journal.CreatePendingAsyncEntry(url,
+                                            task_id,
+                                            mojom::JournalTrack::kActor,
+                                            event_name,
+                                            "")) {}
 
   void Reject(std::string_view reason) {
     journal_entry_->EndEntry(reason);
diff --git a/chrome/browser/actor/tools/navigate_tool.cc b/chrome/browser/actor/tools/navigate_tool.cc
index 04f3771..be86427 100644
--- a/chrome/browser/actor/tools/navigate_tool.cc
+++ b/chrome/browser/actor/tools/navigate_tool.cc
@@ -99,7 +99,8 @@
   if (pending_navigation_handle_id_ &&
       navigation_handle->GetNavigationId() == *pending_navigation_handle_id_) {
     journal().Log(
-        url_, task_id(), "NavigateTool::DidFinishNavigation",
+        url_, task_id(), mojom::JournalTrack::kActor,
+        "NavigateTool::DidFinishNavigation",
         absl::StrFormat("id[%d]", navigation_handle->GetNavigationId()));
     auto result =
         navigation_handle->HasCommitted() && !navigation_handle->IsErrorPage()
@@ -114,7 +115,8 @@
 }
 
 void NavigateTool::NavigationHandleCallback(NavigationHandle& handle) {
-  journal().Log(url_, task_id(), "NavigateTool::NavigationHandleCallback",
+  journal().Log(url_, task_id(), mojom::JournalTrack::kActor,
+                "NavigateTool::NavigationHandleCallback",
                 absl::StrFormat("id[%d]", handle.GetNavigationId()));
   pending_navigation_handle_id_ = handle.GetNavigationId();
 }
diff --git a/chrome/browser/actor/tools/observation_delay_controller.cc b/chrome/browser/actor/tools/observation_delay_controller.cc
index f5aa706..bbc5481 100644
--- a/chrome/browser/actor/tools/observation_delay_controller.cc
+++ b/chrome/browser/actor/tools/observation_delay_controller.cc
@@ -38,8 +38,8 @@
     AggregatedJournal::PendingAsyncEntry& parent_journal_entry,
     ReadyCallback callback) {
   journal_entry_ = parent_journal_entry.GetJournal().CreatePendingAsyncEntry(
-      GURL::EmptyGURL(), parent_journal_entry.GetTaskId(), "ObservationDelay",
-      StateToString(state_));
+      GURL::EmptyGURL(), parent_journal_entry.GetTaskId(),
+      mojom::JournalTrack::kActor, "ObservationDelay", StateToString(state_));
 
   switch (state_) {
     case State::kWaitingForLoadStart:
@@ -83,9 +83,9 @@
   // If we aren't waiting, then this new state will be logged when
   // we actually wait.
   if (journal_entry_) {
-    journal_entry_->GetJournal().Log(GURL::EmptyGURL(),
-                                     journal_entry_->GetTaskId(),
-                                     "ObservationDelay", "Done Loading");
+    journal_entry_->GetJournal().Log(
+        GURL::EmptyGURL(), journal_entry_->GetTaskId(),
+        mojom::JournalTrack::kActor, "ObservationDelay", "Done Loading");
   }
   WaitForVisualStateUpdate();
 }
diff --git a/chrome/browser/actor/tools/page_tool.cc b/chrome/browser/actor/tools/page_tool.cc
index f26a194f..98d41f6 100644
--- a/chrome/browser/actor/tools/page_tool.cc
+++ b/chrome/browser/actor/tools/page_tool.cc
@@ -267,7 +267,8 @@
     return MakeResult(mojom::ActionResultCode::kTabWentAway);
   }
 
-  journal().Log(JournalURL(), task_id(), "TimeOfUseValidation",
+  journal().Log(JournalURL(), task_id(), mojom::JournalTrack::kActor,
+                "TimeOfUseValidation",
                 "TabHandle:" + base::ToString(tab->GetHandle()));
 
   RenderFrameHost* frame =
@@ -282,8 +283,8 @@
       last_observation, request_->GetTarget());
 
   if (!observed_target_node_info_) {
-    journal().Log(JournalURL(), task_id(), "TimeOfUseValidation",
-                  "No observed target found in APC.");
+    journal().Log(JournalURL(), task_id(), mojom::JournalTrack::kActor,
+                  "TimeOfUseValidation", "No observed target found in APC.");
   }
 
   // Perform validation for coordinate based target only.
diff --git a/chrome/browser/actor/tools/tool_controller.cc b/chrome/browser/actor/tools/tool_controller.cc
index 0e7a6e30..98d4c5d7 100644
--- a/chrome/browser/actor/tools/tool_controller.cc
+++ b/chrome/browser/actor/tools/tool_controller.cc
@@ -49,7 +49,8 @@
 
 void ToolController::SetState(State state) {
   journal_->Log(active_state_ ? active_state_->tool->JournalURL() : GURL(),
-                task_->id(), "ToolControllerStateChange",
+                task_->id(), mojom::JournalTrack::kActor,
+                "ToolControllerStateChange",
                 absl::StrFormat("State: %s -> %s", StateToString(state_),
                                 StateToString(state)));
 #if DCHECK_IS_ON()
@@ -110,6 +111,7 @@
   if (!IsOk(*create_result.result)) {
     CHECK(!create_result.tool);
     journal_->Log(request.GetURLForJournal(), task_->id(),
+                  mojom::JournalTrack::kActor,
                   "ToolController CreateToolAndValidate Failed",
                   create_result.result->message);
     PostResponseTask(std::move(result_callback),
@@ -121,8 +123,8 @@
   CHECK(tool);
 
   auto journal_event = journal_->CreatePendingAsyncEntry(
-      tool->JournalURL(), task_->id(), tool->JournalEvent(),
-      tool->DebugString());
+      tool->JournalURL(), task_->id(), mojom::JournalTrack::kActor,
+      tool->JournalEvent(), tool->DebugString());
   active_state_.emplace(std::move(tool), std::move(result_callback),
                         std::move(journal_event), last_observation);
 
@@ -161,7 +163,8 @@
       active_state_->tool->TimeOfUseValidation(active_state_->last_observation);
   if (!IsOk(*toctou_result)) {
     journal_->Log(active_state_->tool->JournalURL(), task_->id(),
-                  "TOCTOU Check Failed", ToDebugString(*toctou_result));
+                  mojom::JournalTrack::kActor, "TOCTOU Check Failed",
+                  ToDebugString(*toctou_result));
     CompleteToolRequest(std::move(toctou_result));
     return;
   }
diff --git a/chrome/browser/ash/ambient/ambient_client_impl_unittest.cc b/chrome/browser/ash/ambient/ambient_client_impl_unittest.cc
index 19a047f..4494ec7 100644
--- a/chrome/browser/ash/ambient/ambient_client_impl_unittest.cc
+++ b/chrome/browser/ash/ambient/ambient_client_impl_unittest.cc
@@ -14,12 +14,12 @@
 #include "chrome/browser/ash/login/users/profile_user_manager_controller.h"
 #include "chrome/browser/ash/settings/scoped_testing_cros_settings.h"
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "chromeos/ash/components/install_attributes/stub_install_attributes.h"
 #include "chromeos/ash/components/settings/cros_settings.h"
+#include "components/prefs/pref_service.h"
 #include "components/user_manager/fake_user_manager_delegate.h"
 #include "components/user_manager/scoped_user_manager.h"
 #include "components/user_manager/test_helper.h"
@@ -93,14 +93,13 @@
 
  private:
   content::BrowserTaskEnvironment task_environment_;
-  ScopedTestingLocalState testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
+
   ash::ScopedStubInstallAttributes install_attributes_;
   ash::ScopedTestingCrosSettings testing_cros_settings_;
   user_manager::ScopedUserManager user_manager_{
       std::make_unique<user_manager::UserManagerImpl>(
           std::make_unique<user_manager::FakeUserManagerDelegate>(),
-          testing_local_state_.Get(),
+          TestingBrowserProcess::GetGlobal()->local_state(),
           ash::CrosSettings::Get())};
   std::unique_ptr<ash::ProfileUserManagerController>
       profile_user_manager_controller_;
diff --git a/chrome/browser/ash/app_list/search/search_controller_unittest.cc b/chrome/browser/ash/app_list/search/search_controller_unittest.cc
index 6cc3c81..b26b166f 100644
--- a/chrome/browser/ash/app_list/search/search_controller_unittest.cc
+++ b/chrome/browser/ash/app_list/search/search_controller_unittest.cc
@@ -34,7 +34,6 @@
 #include "chrome/browser/ash/app_list/search/types.h"
 #include "chrome/browser/ash/app_list/test/fake_app_list_model_updater.h"
 #include "chrome/browser/ash/app_list/test/test_app_list_controller_delegate.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/prefs/pref_service.h"
@@ -161,9 +160,6 @@
  protected:
   content::BrowserTaskEnvironment task_environment_;
 
-  // Needed for `DriveIntegrationService`.
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
-
   display::test::TestScreen test_screen_{/*create_dispay=*/true,
                                          /*register_screen=*/true};
   TestingProfile profile_;
diff --git a/chrome/browser/ash/app_mode/arcvm_app/kiosk_arcvm_app_service_unittest.cc b/chrome/browser/ash/app_mode/arcvm_app/kiosk_arcvm_app_service_unittest.cc
index ddd1a15..4404fa5 100644
--- a/chrome/browser/ash/app_mode/arcvm_app/kiosk_arcvm_app_service_unittest.cc
+++ b/chrome/browser/ash/app_mode/arcvm_app/kiosk_arcvm_app_service_unittest.cc
@@ -17,7 +17,6 @@
 #include "chrome/browser/ash/ownership/fake_owner_settings_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/experiences/arc/session/arc_service_manager.h"
@@ -26,7 +25,6 @@
 #include "chromeos/ash/experiences/arc/test/fake_arc_session.h"
 #include "components/exo/shell_surface_util.h"
 #include "components/exo/wm_helper.h"
-#include "components/prefs/testing_pref_service.h"
 #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -87,8 +85,7 @@
 
 class KioskArcvmAppServiceTest : public testing::Test {
  public:
-  KioskArcvmAppServiceTest()
-      : local_state_(TestingBrowserProcess::GetGlobal()) {}
+  KioskArcvmAppServiceTest() = default;
 
   void SetUp() override {
     // TODO(crbug.com/418638940): Refactor to use ChromeAshTestBase.
@@ -103,7 +100,8 @@
                                          kAppClassName, /*sticky=*/true);
     arc_policy_bridge_ =
         arc::ArcPolicyBridge::GetForBrowserContextForTesting(profile_.get());
-    app_manager_ = std::make_unique<KioskArcvmAppManager>(local_state_.Get());
+    app_manager_ = std::make_unique<KioskArcvmAppManager>(
+        TestingBrowserProcess::GetGlobal()->local_state());
     // Initialize KioskArcvmAppService to listen to KioskArcvmAppManager
     // updates.
     KioskArcvmAppService::Get(profile());
@@ -164,9 +162,6 @@
     wm_helper_->NotifyExoWindowCreated(window);
   }
 
- protected:
-  PrefRegistrySimple* registry() { return local_state_.Get()->registry(); }
-
  private:
   // Number of times app tried to be launched.
   size_t launch_requests_ = 0;
@@ -183,7 +178,6 @@
   std::unique_ptr<exo::WMHelper> wm_helper_;
 
   raw_ptr<arc::ArcPolicyBridge, DanglingUntriaged> arc_policy_bridge_;
-  ScopedTestingLocalState local_state_;
 };
 
 TEST_F(KioskArcvmAppServiceTest, LaunchConditions) {
diff --git a/chrome/browser/ash/app_mode/auto_sleep/device_weekly_scheduled_suspend_controller_unittest.cc b/chrome/browser/ash/app_mode/auto_sleep/device_weekly_scheduled_suspend_controller_unittest.cc
index fd4433e7..9d8aca13 100644
--- a/chrome/browser/ash/app_mode/auto_sleep/device_weekly_scheduled_suspend_controller_unittest.cc
+++ b/chrome/browser/ash/app_mode/auto_sleep/device_weekly_scheduled_suspend_controller_unittest.cc
@@ -20,12 +20,12 @@
 #include "chrome/browser/ash/app_mode/auto_sleep/device_weekly_scheduled_suspend_test_policy_builder.h"
 #include "chrome/browser/ash/app_mode/auto_sleep/weekly_interval_timer.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/policy/weekly_time/weekly_time.h"
 #include "chromeos/ash/components/policy/weekly_time/weekly_time_interval.h"
 #include "chromeos/dbus/power/fake_power_manager_client.h"
 #include "chromeos/dbus/power/power_manager_client.h"
+#include "components/prefs/pref_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace ash {
@@ -37,8 +37,7 @@
 
 class DeviceWeeklyScheduledSuspendControllerTest : public testing::Test {
  protected:
-  DeviceWeeklyScheduledSuspendControllerTest()
-      : testing_local_state_(TestingBrowserProcess::GetGlobal()) {}
+  DeviceWeeklyScheduledSuspendControllerTest() = default;
 
   // testing::Test:
   void SetUp() override {
@@ -69,8 +68,8 @@
   }
 
   void UpdatePolicyPref(base::Value::List schedule_list) {
-    testing_local_state_.Get()->SetList(prefs::kDeviceWeeklyScheduledSuspend,
-                                        std::move(schedule_list));
+    TestingBrowserProcess::GetGlobal()->local_state()->SetList(
+        prefs::kDeviceWeeklyScheduledSuspend, std::move(schedule_list));
   }
 
   void UpdatePolicyAndCheckIntervals(
@@ -112,7 +111,7 @@
   void InitController() {
     device_weekly_scheduled_suspend_controller_ =
         std::make_unique<DeviceWeeklyScheduledSuspendController>(
-            testing_local_state_.Get());
+            TestingBrowserProcess::GetGlobal()->local_state());
   }
 
   int user_activity_calls() const { return user_activity_calls_; }
@@ -121,7 +120,6 @@
   base::test::TaskEnvironment task_environment_{
       base::test::TaskEnvironment::MainThreadType::IO,
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
-  ScopedTestingLocalState testing_local_state_;
   std::unique_ptr<DeviceWeeklyScheduledSuspendController>
       device_weekly_scheduled_suspend_controller_;
   int user_activity_calls_;
diff --git a/chrome/browser/ash/app_mode/isolated_web_app/kiosk_iwa_manager_unittest.cc b/chrome/browser/ash/app_mode/isolated_web_app/kiosk_iwa_manager_unittest.cc
index ea9925d..9196c1c9 100644
--- a/chrome/browser/ash/app_mode/isolated_web_app/kiosk_iwa_manager_unittest.cc
+++ b/chrome/browser/ash/app_mode/isolated_web_app/kiosk_iwa_manager_unittest.cc
@@ -18,13 +18,14 @@
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/ash/settings/scoped_testing_cros_settings.h"
 #include "chrome/browser/ash/settings/stub_cros_settings_provider.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/dbus/userdataauth/userdataauth_client.h"
 #include "chromeos/ash/components/policy/device_local_account/device_local_account_type.h"
 #include "chromeos/ash/components/settings/cros_settings.h"
 #include "chromeos/ash/components/settings/cros_settings_names.h"
 #include "components/account_id/account_id.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/testing_pref_service.h"
 #include "components/user_manager/scoped_user_manager.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -119,9 +120,9 @@
 class KioskIwaManagerBaseTest : public testing::Test {
  public:
   KioskIwaManagerBaseTest()
-      : local_state_(TestingBrowserProcess::GetGlobal()),
-        fake_user_manager_(std::make_unique<ash::FakeChromeUserManager>()),
-        iwa_manager_(CHECK_DEREF(local_state_.Get())) {
+      : fake_user_manager_(std::make_unique<ash::FakeChromeUserManager>()),
+        iwa_manager_(
+            CHECK_DEREF(TestingBrowserProcess::GetGlobal()->local_state())) {
     UserDataAuthClient::InitializeFake();
     iwa_manager().AddObserver(&observer());
   }
@@ -161,15 +162,12 @@
         ash::features::kIsolatedWebAppKiosk);
   }
 
-  PrefRegistrySimple* registry() { return local_state_.Get()->registry(); }
-
   MockKioskAppManagerObserver& observer() { return observer_; }
   KioskIwaManager& iwa_manager() { return iwa_manager_; }
 
  private:
   content::BrowserTaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
-  ScopedTestingLocalState local_state_;
   base::test::ScopedFeatureList scoped_feature_list_;
   ash::ScopedTestingCrosSettings scoped_testing_cros_settings_;
   user_manager::TypedScopedUserManager<ash::FakeChromeUserManager>
diff --git a/chrome/browser/ash/app_mode/kiosk_app_launch_error_unittest.cc b/chrome/browser/ash/app_mode/kiosk_app_launch_error_unittest.cc
index fa2323b..6be73df 100644
--- a/chrome/browser/ash/app_mode/kiosk_app_launch_error_unittest.cc
+++ b/chrome/browser/ash/app_mode/kiosk_app_launch_error_unittest.cc
@@ -8,9 +8,9 @@
 
 #include "chrome/browser/ash/app_mode/kiosk_chrome_app_manager.h"
 #include "chrome/grit/generated_resources.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/login/auth/public/auth_failure.h"
+#include "components/prefs/pref_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -34,8 +34,7 @@
 
 class KioskAppLaunchErrorTest : public testing::Test {
  public:
-  KioskAppLaunchErrorTest()
-      : local_state_(TestingBrowserProcess::GetGlobal()) {}
+  KioskAppLaunchErrorTest() = default;
   ~KioskAppLaunchErrorTest() override = default;
 
   // Verify the mapping from the error code to the message.
@@ -43,9 +42,6 @@
                           const std::string& expected_message) const {
     EXPECT_EQ(KioskAppLaunchError::GetErrorMessage(error), expected_message);
   }
-
- private:
-  ScopedTestingLocalState local_state_;
 };
 
 TEST_F(KioskAppLaunchErrorTest, GetErrorMessage) {
diff --git a/chrome/browser/ash/app_mode/metrics/low_disk_metrics_service_unittest.cc b/chrome/browser/ash/app_mode/metrics/low_disk_metrics_service_unittest.cc
index 3ba5aa8..a77d81b 100644
--- a/chrome/browser/ash/app_mode/metrics/low_disk_metrics_service_unittest.cc
+++ b/chrome/browser/ash/app_mode/metrics/low_disk_metrics_service_unittest.cc
@@ -8,10 +8,10 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/task_environment.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/dbus/userdataauth/fake_userdataauth_client.h"
 #include "chromeos/ash/components/dbus/userdataauth/userdataauth_client.h"
+#include "components/prefs/pref_service.h"
 #include "components/prefs/testing_pref_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -21,11 +21,7 @@
     : public testing::TestWithParam<
           std::tuple<KioskLowDiskSeverity, uint64_t>> {
  public:
-  LowDiskMetricsServiceTest()
-      : local_state_(std::make_unique<ScopedTestingLocalState>(
-            TestingBrowserProcess::GetGlobal())) {
-    UserDataAuthClient::InitializeFake();
-  }
+  LowDiskMetricsServiceTest() { UserDataAuthClient::InitializeFake(); }
 
   LowDiskMetricsServiceTest(const LowDiskMetricsServiceTest&) = delete;
   LowDiskMetricsServiceTest& operator=(const LowDiskMetricsServiceTest&) =
@@ -34,19 +30,20 @@
   KioskLowDiskSeverity severity() const { return std::get<0>(GetParam()); }
   uint64_t disk_free_bytes() const { return std::get<1>(GetParam()); }
 
-  TestingPrefServiceSimple* local_state() { return local_state_->Get(); }
-
   void SetUp() override {
     histogram_tester_ = std::make_unique<base::HistogramTester>();
   }
 
   void TearDown() override {
-    local_state()->RemoveUserPref(prefs::kKioskMetrics);
+    TestingBrowserProcess::GetGlobal()->GetTestingLocalState()->RemoveUserPref(
+        prefs::kKioskMetrics);
   }
   base::HistogramTester* histogram_tester() { return histogram_tester_.get(); }
 
   std::optional<KioskLowDiskSeverity> GetLowDiskSeverityFromLocalState() {
-    const auto& metrics_dict = local_state()->GetDict(prefs::kKioskMetrics);
+    const auto& metrics_dict =
+        TestingBrowserProcess::GetGlobal()->local_state()->GetDict(
+            prefs::kKioskMetrics);
     const auto severity_value = metrics_dict.FindInt(kKioskLowDiskSeverity);
     if (!severity_value) {
       return std::nullopt;
@@ -63,12 +60,11 @@
  private:
   base::test::SingleThreadTaskEnvironment task_environment_;
   std::unique_ptr<base::HistogramTester> histogram_tester_;
-  std::unique_ptr<ScopedTestingLocalState> local_state_;
 };
 
 TEST_P(LowDiskMetricsServiceTest, Severity) {
-  auto service =
-      std::make_unique<LowDiskMetricsService>(CHECK_DEREF(local_state()));
+  auto service = std::make_unique<LowDiskMetricsService>(
+      CHECK_DEREF(TestingBrowserProcess::GetGlobal()->local_state()));
 
   histogram_tester()->ExpectTotalCount(kKioskSessionLowDiskSeverityHistogram,
                                        0);
@@ -82,7 +78,8 @@
                                        1);
   EXPECT_EQ(GetLowDiskSeverityFromLocalState().value(), severity());
 
-  service = std::make_unique<LowDiskMetricsService>(CHECK_DEREF(local_state()));
+  service = std::make_unique<LowDiskMetricsService>(
+      CHECK_DEREF(TestingBrowserProcess::GetGlobal()->local_state()));
   histogram_tester()->ExpectBucketCount(
       kKioskSessionLowDiskHighestSeverityHistogram, severity(), 1);
   EXPECT_EQ(GetLowDiskSeverityFromLocalState().value(),
@@ -90,8 +87,8 @@
 }
 
 TEST_F(LowDiskMetricsServiceTest, Update) {
-  auto service =
-      std::make_unique<LowDiskMetricsService>(CHECK_DEREF(local_state()));
+  auto service = std::make_unique<LowDiskMetricsService>(
+      CHECK_DEREF(TestingBrowserProcess::GetGlobal()->local_state()));
 
   SendLowDiskSpaceEvent(kLowDiskMediumThreshold + 1);
   histogram_tester()->ExpectBucketCount(kKioskSessionLowDiskSeverityHistogram,
diff --git a/chrome/browser/ash/app_mode/metrics/network_connectivity_metrics_service_unittest.cc b/chrome/browser/ash/app_mode/metrics/network_connectivity_metrics_service_unittest.cc
index a25034f..43442fc 100644
--- a/chrome/browser/ash/app_mode/metrics/network_connectivity_metrics_service_unittest.cc
+++ b/chrome/browser/ash/app_mode/metrics/network_connectivity_metrics_service_unittest.cc
@@ -8,12 +8,12 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/task_environment.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/network/network_handler.h"
 #include "chromeos/ash/components/network/network_state.h"
 #include "chromeos/ash/components/network/network_state_handler.h"
 #include "chromeos/ash/components/sync_wifi/network_test_helper.h"
+#include "components/prefs/pref_service.h"
 #include "components/prefs/testing_pref_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
@@ -22,23 +22,20 @@
 
 class NetworkConnectivityMetricsServiceTest : public testing::Test {
  public:
-  NetworkConnectivityMetricsServiceTest()
-      : local_state_(std::make_unique<ScopedTestingLocalState>(
-            TestingBrowserProcess::GetGlobal())) {}
+  NetworkConnectivityMetricsServiceTest() = default;
 
   NetworkConnectivityMetricsServiceTest(
       const NetworkConnectivityMetricsServiceTest&) = delete;
   NetworkConnectivityMetricsServiceTest& operator=(
       const NetworkConnectivityMetricsServiceTest&) = delete;
 
-  TestingPrefServiceSimple* local_state() { return local_state_->Get(); }
-
   void SetUp() override {
     helper_.SetUp();
     histogram_tester_ = std::make_unique<base::HistogramTester>();
   }
   void TearDown() override {
-    local_state()->RemoveUserPref(prefs::kKioskMetrics);
+    TestingBrowserProcess::GetGlobal()->GetTestingLocalState()->RemoveUserPref(
+        prefs::kKioskMetrics);
   }
   NetworkStateHandler* network_state_handler() {
     return NetworkHandler::Get()->network_state_handler();
@@ -46,7 +43,8 @@
   base::HistogramTester* histogram_tester() { return histogram_tester_.get(); }
 
   std::optional<int> GetNetworkDropsFromLocalState() {
-    return local_state()
+    return TestingBrowserProcess::GetGlobal()
+        ->local_state()
         ->GetDict(prefs::kKioskMetrics)
         .FindInt(kKioskNetworkDrops);
   }
@@ -91,12 +89,11 @@
   base::test::SingleThreadTaskEnvironment task_environment_;
   std::unique_ptr<base::HistogramTester> histogram_tester_;
   sync_wifi::NetworkTestHelper helper_;
-  std::unique_ptr<ScopedTestingLocalState> local_state_;
 };
 
 TEST_F(NetworkConnectivityMetricsServiceTest, StartNotInitialized) {
   auto service = std::make_unique<NetworkConnectivityMetricsService>(
-      CHECK_DEREF(local_state()));
+      CHECK_DEREF(TestingBrowserProcess::GetGlobal()->local_state()));
   EXPECT_TRUE(network_state_handler()->HasObserver(service.get()));
   EXPECT_FALSE(service->is_online());
   EXPECT_EQ(std::optional<int>(0), GetNetworkDropsFromLocalState());
@@ -105,7 +102,7 @@
 TEST_F(NetworkConnectivityMetricsServiceTest, StartOnlineGoOnline) {
   EXPECT_TRUE(SimulateConnectionSuccess() != nullptr);
   auto service = std::make_unique<NetworkConnectivityMetricsService>(
-      CHECK_DEREF(local_state()));
+      CHECK_DEREF(TestingBrowserProcess::GetGlobal()->local_state()));
   EXPECT_TRUE(network_state_handler()->HasObserver(service.get()));
   EXPECT_TRUE(service->is_online());
   EXPECT_EQ(std::optional<int>(0), GetNetworkDropsFromLocalState());
@@ -119,7 +116,7 @@
 TEST_F(NetworkConnectivityMetricsServiceTest, StartOnlineGoOfflineDrop) {
   const auto* network = SimulateConnectionSuccess();
   auto service = std::make_unique<NetworkConnectivityMetricsService>(
-      CHECK_DEREF(local_state()));
+      CHECK_DEREF(TestingBrowserProcess::GetGlobal()->local_state()));
   EXPECT_TRUE(network_state_handler()->HasObserver(service.get()));
   EXPECT_TRUE(service->is_online());
   EXPECT_EQ(std::optional<int>(0), GetNetworkDropsFromLocalState());
@@ -135,7 +132,7 @@
   SimulateConnectionFailure(network, shill::kErrorUnknownFailure);
 
   auto service = std::make_unique<NetworkConnectivityMetricsService>(
-      CHECK_DEREF(local_state()));
+      CHECK_DEREF(TestingBrowserProcess::GetGlobal()->local_state()));
   EXPECT_TRUE(network_state_handler()->HasObserver(service.get()));
   EXPECT_FALSE(service->is_online());
   EXPECT_EQ(std::optional<int>(0), GetNetworkDropsFromLocalState());
@@ -150,7 +147,7 @@
   SimulateConnectionFailure(CreateNetwork(), shill::kErrorUnknownFailure);
 
   auto service = std::make_unique<NetworkConnectivityMetricsService>(
-      CHECK_DEREF(local_state()));
+      CHECK_DEREF(TestingBrowserProcess::GetGlobal()->local_state()));
   EXPECT_TRUE(network_state_handler()->HasObserver(service.get()));
   EXPECT_FALSE(service->is_online());
   EXPECT_EQ(std::optional<int>(0), GetNetworkDropsFromLocalState());
@@ -165,7 +162,7 @@
   constexpr size_t kMaxNetworkDrops = 5;
 
   auto service = std::make_unique<NetworkConnectivityMetricsService>(
-      CHECK_DEREF(local_state()));
+      CHECK_DEREF(TestingBrowserProcess::GetGlobal()->local_state()));
   EXPECT_TRUE(network_state_handler()->HasObserver(service.get()));
 
   // Disconnect / connect networks kMaxNetworkDrops times.
@@ -184,7 +181,7 @@
   // Check network-drops from Local State gets reported once the next kiosk
   // session starts.
   service = std::make_unique<NetworkConnectivityMetricsService>(
-      CHECK_DEREF(local_state()));
+      CHECK_DEREF(TestingBrowserProcess::GetGlobal()->local_state()));
   histogram_tester()->ExpectBucketCount(kKioskNetworkDropsPerSessionHistogram,
                                         kMaxNetworkDrops, 1);
 }
diff --git a/chrome/browser/ash/app_mode/metrics/periodic_metrics_service_unittest.cc b/chrome/browser/ash/app_mode/metrics/periodic_metrics_service_unittest.cc
index 941d606..b57f801d 100644
--- a/chrome/browser/ash/app_mode/metrics/periodic_metrics_service_unittest.cc
+++ b/chrome/browser/ash/app_mode/metrics/periodic_metrics_service_unittest.cc
@@ -2,17 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/ash/app_mode/metrics/periodic_metrics_service.h"
+
 #include <string>
 
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/task_environment.h"
 #include "base/time/time.h"
-#include "chrome/browser/ash/app_mode/metrics/periodic_metrics_service.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/network/network_handler_test_helper.h"
 #include "chromeos/ash/components/sync_wifi/network_test_helper.h"
+#include "components/prefs/pref_service.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/user_activity/user_activity_detector.h"
@@ -41,11 +42,10 @@
  public:
   BasePeriodicMetricsServiceTest()
       : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
-        local_state_(std::make_unique<ScopedTestingLocalState>(
-            TestingBrowserProcess::GetGlobal())),
         network_handler_test_helper_(
             std::make_unique<NetworkHandlerTestHelper>()),
-        periodic_metrics_service_(local_state()),
+        periodic_metrics_service_(
+            TestingBrowserProcess::GetGlobal()->local_state()),
         histogram_tester_(std::make_unique<base::HistogramTester>()) {}
 
   BasePeriodicMetricsServiceTest(const BasePeriodicMetricsServiceTest&) =
@@ -55,8 +55,6 @@
 
   base::test::TaskEnvironment* task_environment() { return &task_environment_; }
 
-  TestingPrefServiceSimple* local_state() { return local_state_->Get(); }
-
   base::HistogramTester* histogram_tester() { return histogram_tester_.get(); }
 
   void RecordPreviousSessionMetrics() {
@@ -89,7 +87,6 @@
  protected:
   content::BrowserTaskEnvironment task_environment_;
   sync_preferences::TestingPrefServiceSyncable user_prefs_;
-  std::unique_ptr<ScopedTestingLocalState> local_state_;
   std::unique_ptr<NetworkHandlerTestHelper> network_handler_test_helper_;
   PeriodicMetricsService periodic_metrics_service_;
   std::unique_ptr<base::HistogramTester> histogram_tester_;
@@ -146,7 +143,8 @@
 
   void TearDown() override {
     network_handler_test_helper_.reset();
-    local_state()->RemoveUserPref(prefs::kKioskMetrics);
+    TestingBrowserProcess::GetGlobal()->GetTestingLocalState()->RemoveUserPref(
+        prefs::kKioskMetrics);
   }
 
   void MakeOffline() {
@@ -210,7 +208,8 @@
       const UserActivityPeriodicMetricsServiceTest&) = delete;
 
   void TearDown() override {
-    local_state()->RemoveUserPref(prefs::kKioskMetrics);
+    TestingBrowserProcess::GetGlobal()->GetTestingLocalState()->RemoveUserPref(
+        prefs::kKioskMetrics);
   }
 
   void SetDeviceIdleTime(base::TimeDelta idle_time,
diff --git a/chrome/browser/ash/arc/arc_util_unittest.cc b/chrome/browser/ash/arc/arc_util_unittest.cc
index 733d13d..703d0f1 100644
--- a/chrome/browser/ash/arc/arc_util_unittest.cc
+++ b/chrome/browser/ash/arc/arc_util_unittest.cc
@@ -27,7 +27,6 @@
 #include "chrome/browser/ui/ash/login/fake_login_display_host.h"
 #include "chrome/browser/ui/webui/ash/login/consolidated_consent_screen_handler.h"
 #include "chrome/browser/ui/webui/ash/login/demo_preferences_screen_handler.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
@@ -190,7 +189,6 @@
   ash::ScopedCrosSettingsTestHelper cros_settings_test_helper_;
 
  private:
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
   std::unique_ptr<base::test::ScopedCommandLine> command_line_;
   content::BrowserTaskEnvironment task_environment_;
   base::ScopedTempDir data_dir_;
diff --git a/chrome/browser/ash/arc/instance_throttle/arc_provisioning_throttle_observer_unittest.cc b/chrome/browser/ash/arc/instance_throttle/arc_provisioning_throttle_observer_unittest.cc
index a2109fb..d6744a98 100644
--- a/chrome/browser/ash/arc/instance_throttle/arc_provisioning_throttle_observer_unittest.cc
+++ b/chrome/browser/ash/arc/instance_throttle/arc_provisioning_throttle_observer_unittest.cc
@@ -11,7 +11,6 @@
 #include "chrome/browser/ash/arc/session/arc_session_manager.h"
 #include "chrome/browser/ash/arc/test/test_arc_session_manager.h"
 #include "chrome/browser/ash/settings/scoped_testing_cros_settings.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/browser_context_helper/annotated_account_id.h"
@@ -63,7 +62,8 @@
 
     user_manager_.Reset(std::make_unique<user_manager::UserManagerImpl>(
         std::make_unique<user_manager::FakeUserManagerDelegate>(),
-        testing_local_state_.Get(), ash::CrosSettings::Get()));
+        TestingBrowserProcess::GetGlobal()->local_state(),
+        ash::CrosSettings::Get()));
 
     constexpr char kTestingProfileName[] = "test@test";
     const AccountId account_id(AccountId::FromUserEmailGaiaId(
@@ -124,8 +124,6 @@
 
  private:
   content::BrowserTaskEnvironment task_environment_;
-  ScopedTestingLocalState testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
   ash::ScopedStubInstallAttributes install_attributes_;
   ash::ScopedTestingCrosSettings testing_cros_settings_;
   session_manager::SessionManager session_manager_;
diff --git a/chrome/browser/ash/arc/locked_fullscreen/arc_locked_fullscreen_manager_unittest.cc b/chrome/browser/ash/arc/locked_fullscreen/arc_locked_fullscreen_manager_unittest.cc
index d455f48..ec7bb97d 100644
--- a/chrome/browser/ash/arc/locked_fullscreen/arc_locked_fullscreen_manager_unittest.cc
+++ b/chrome/browser/ash/arc/locked_fullscreen/arc_locked_fullscreen_manager_unittest.cc
@@ -17,7 +17,6 @@
 #include "chrome/browser/ash/arc/locked_fullscreen/arc_locked_fullscreen_manager.h"
 #include "chrome/browser/ash/arc/test/test_arc_session_manager.h"
 #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
@@ -29,6 +28,7 @@
 #include "chromeos/ash/experiences/arc/test/arc_util_test_support.h"
 #include "chromeos/ash/experiences/arc/test/fake_arc_session.h"
 #include "components/account_id/account_id.h"
+#include "components/prefs/pref_service.h"
 #include "components/session_manager/core/session_manager.h"
 #include "components/user_manager/fake_user_manager_delegate.h"
 #include "components/user_manager/test_helper.h"
@@ -74,7 +74,8 @@
     // Initialize a testing profile and the user manager. Needed to test ARC.
     user_manager_ = std::make_unique<user_manager::UserManagerImpl>(
         std::make_unique<user_manager::FakeUserManagerDelegate>(),
-        local_state_.Get(), ash::CrosSettings::Get());
+        TestingBrowserProcess::GetGlobal()->local_state(),
+        ash::CrosSettings::Get());
     user_manager_->Initialize();
 
     const AccountId account_id(
@@ -125,7 +126,7 @@
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
   base::test::ScopedFeatureList scoped_feature_list_;
   ash::ScopedCrosSettingsTestHelper cros_settings_helper_;
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
+
   std::unique_ptr<user_manager::UserManagerImpl> user_manager_;
   TestingProfileManager profile_manager_{TestingBrowserProcess::GetGlobal()};
   session_manager::SessionManager session_manager_;
diff --git a/chrome/browser/ash/arc/notification/arc_provision_notification_service_unittest.cc b/chrome/browser/ash/arc/notification/arc_provision_notification_service_unittest.cc
index 9178645..119a9c5 100644
--- a/chrome/browser/ash/arc/notification/arc_provision_notification_service_unittest.cc
+++ b/chrome/browser/ash/arc/notification/arc_provision_notification_service_unittest.cc
@@ -47,10 +47,6 @@
       const ArcProvisionNotificationServiceTest&) = delete;
 
   void SetUp() override {
-    SetUpInternal(/*should_create_session_manager=*/true);
-  }
-
-  void SetUpInternal(bool should_create_session_manager) {
     ash::ConciergeClient::InitializeFake(/*fake_cicerone_client=*/nullptr);
 
     SetArcAvailableCommandLineForTesting(
@@ -62,12 +58,6 @@
         CreateTestArcSessionManager(std::make_unique<ArcSessionRunner>(
             base::BindRepeating(FakeArcSession::Create)));
 
-    if (should_create_session_manager) {
-      // SessionManager is created by
-      // |AshTestHelper::bluetooth_config_test_helper()|.
-      session_manager_ = session_manager::SessionManager::Get();
-    }
-
     // This creates |profile()|, so it has to come after the arc managers.
     BrowserWithTestWindowTest::SetUp();
 
@@ -92,14 +82,16 @@
     BrowserWithTestWindowTest::TearDown();
     arc_session_manager_.reset();
     arc_service_manager_.reset();
-
     ash::ConciergeClient::Shutdown();
   }
 
+  static session_manager::SessionManager* session_manager() {
+    return session_manager::SessionManager::Get();
+  }
+
   std::unique_ptr<ArcServiceManager> arc_service_manager_;
   std::unique_ptr<ArcSessionManager> arc_session_manager_;
   std::unique_ptr<NotificationDisplayServiceTester> display_service_;
-  raw_ptr<session_manager::SessionManager> session_manager_;
 
  private:
   TestingPrefServiceSimple local_state_;
@@ -123,13 +115,13 @@
   arc_session_manager_->Initialize();
 
   // Trigger opt-in flow. The notification gets shown when session starts.
-  session_manager_->SetSessionState(
+  session_manager()->SetSessionState(
       session_manager::SessionState::LOGIN_PRIMARY);
   arc_session_manager_->RequestEnable();
   EXPECT_FALSE(
       display_service_->GetNotification(kArcManagedProvisionNotificationId));
 
-  session_manager_->SetSessionState(session_manager::SessionState::ACTIVE);
+  session_manager()->SetSessionState(session_manager::SessionState::ACTIVE);
   EXPECT_TRUE(
       display_service_->GetNotification(kArcManagedProvisionNotificationId));
   EXPECT_EQ(ArcSessionManager::State::CHECKING_REQUIREMENTS,
@@ -169,7 +161,7 @@
 
   // Enable ARC. The opt-in flow doesn't take place, and no notification is
   // shown when session starts.
-  session_manager_->SetSessionState(
+  session_manager()->SetSessionState(
       session_manager::SessionState::LOGIN_PRIMARY);
   arc_session_manager_->AllowActivation(
       ArcSessionManager::AllowActivationReason::kImmediateActivation);
@@ -177,7 +169,7 @@
   EXPECT_FALSE(
       display_service_->GetNotification(kArcManagedProvisionNotificationId));
 
-  session_manager_->SetSessionState(session_manager::SessionState::ACTIVE);
+  session_manager()->SetSessionState(session_manager::SessionState::ACTIVE);
   EXPECT_FALSE(
       display_service_->GetNotification(kArcManagedProvisionNotificationId));
   EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager_->state());
@@ -206,13 +198,13 @@
   arc_session_manager_->Initialize();
 
   // Trigger opt-in flow. The notification gets shown when session starts.
-  session_manager_->SetSessionState(
+  session_manager()->SetSessionState(
       session_manager::SessionState::LOGIN_PRIMARY);
   arc_session_manager_->RequestEnable();
   EXPECT_FALSE(
       display_service_->GetNotification(kArcManagedProvisionNotificationId));
 
-  session_manager_->SetSessionState(session_manager::SessionState::ACTIVE);
+  session_manager()->SetSessionState(session_manager::SessionState::ACTIVE);
   EXPECT_TRUE(
       display_service_->GetNotification(kArcManagedProvisionNotificationId));
   EXPECT_EQ(ArcSessionManager::State::CHECKING_REQUIREMENTS,
@@ -247,13 +239,13 @@
   arc_session_manager_->Initialize();
 
   // Trigger opt-in flow. The notification gets shown when session starts.
-  session_manager_->SetSessionState(
+  session_manager()->SetSessionState(
       session_manager::SessionState::LOGIN_PRIMARY);
   arc_session_manager_->RequestEnable();
   EXPECT_FALSE(
       display_service_->GetNotification(kArcManagedProvisionNotificationId));
 
-  session_manager_->SetSessionState(session_manager::SessionState::ACTIVE);
+  session_manager()->SetSessionState(session_manager::SessionState::ACTIVE);
   EXPECT_TRUE(
       display_service_->GetNotification(kArcManagedProvisionNotificationId));
   EXPECT_EQ(ArcSessionManager::State::CHECKING_REQUIREMENTS,
@@ -284,13 +276,13 @@
   arc_session_manager_->Initialize();
 
   // Trigger opt-in flow. The notification is not shown when session starts.
-  session_manager_->SetSessionState(
+  session_manager()->SetSessionState(
       session_manager::SessionState::LOGIN_PRIMARY);
   arc_session_manager_->RequestEnable();
   EXPECT_FALSE(
       display_service_->GetNotification(kArcManagedProvisionNotificationId));
 
-  session_manager_->SetSessionState(session_manager::SessionState::ACTIVE);
+  session_manager()->SetSessionState(session_manager::SessionState::ACTIVE);
   EXPECT_FALSE(
       display_service_->GetNotification(kArcManagedProvisionNotificationId));
   EXPECT_EQ(ArcSessionManager::State::CHECKING_REQUIREMENTS,
@@ -323,12 +315,8 @@
       const ArcProvisionNotificationServiceOobeTest&) = delete;
 
   void SetUp() override {
-    // SessionManager is created in FakeLoginDisplayHost. We should not create
-    // another one here.
-    ArcProvisionNotificationServiceTest::SetUpInternal(
-        /*should_create_session_manager=*/false);
-
-    CreateLoginDisplayHost();
+    ArcProvisionNotificationServiceTest::SetUp();
+    fake_login_display_host_ = std::make_unique<ash::FakeLoginDisplayHost>();
   }
 
   void TearDown() override {
@@ -336,10 +324,6 @@
     ArcProvisionNotificationServiceTest::TearDown();
   }
 
-  void CreateLoginDisplayHost() {
-    fake_login_display_host_ = std::make_unique<ash::FakeLoginDisplayHost>();
-  }
-
  private:
   std::unique_ptr<ash::FakeLoginDisplayHost> fake_login_display_host_;
 };
diff --git a/chrome/browser/ash/arc/session/arc_activation_necessity_checker_unittest.cc b/chrome/browser/ash/arc/session/arc_activation_necessity_checker_unittest.cc
index c4efbf6..13739ce 100644
--- a/chrome/browser/ash/arc/session/arc_activation_necessity_checker_unittest.cc
+++ b/chrome/browser/ash/arc/session/arc_activation_necessity_checker_unittest.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/ash/arc/test/test_arc_session_manager.h"
 #include "chrome/browser/ash/settings/scoped_testing_cros_settings.h"
 #include "chrome/browser/policy/profile_policy_connector.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/browser_context_helper/annotated_account_id.h"
@@ -91,7 +90,8 @@
 
     user_manager_.Reset(std::make_unique<user_manager::UserManagerImpl>(
         std::make_unique<user_manager::FakeUserManagerDelegate>(),
-        testing_local_state_.Get(), ash::CrosSettings::Get()));
+        TestingBrowserProcess::GetGlobal()->local_state(),
+        ash::CrosSettings::Get()));
 
     const AccountId account_id =
         AccountId::FromUserEmailGaiaId(kUserEmail, GaiaId("1234567890"));
@@ -136,8 +136,6 @@
  protected:
   content::BrowserTaskEnvironment task_environment_;
   base::test::ScopedFeatureList feature_list_;
-  ScopedTestingLocalState testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
   ash::ScopedStubInstallAttributes install_attributes_;
   ash::ScopedTestingCrosSettings testing_cros_settings_;
   session_manager::SessionManager session_manager_;
diff --git a/chrome/browser/ash/arc/session/arc_play_store_enabled_preference_handler_unittest.cc b/chrome/browser/ash/arc/session/arc_play_store_enabled_preference_handler_unittest.cc
index 9bdcb9b..d318906 100644
--- a/chrome/browser/ash/arc/session/arc_play_store_enabled_preference_handler_unittest.cc
+++ b/chrome/browser/ash/arc/session/arc_play_store_enabled_preference_handler_unittest.cc
@@ -22,7 +22,6 @@
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
 #include "chrome/browser/ui/ash/login/fake_login_display_host.h"
 #include "chrome/grit/generated_resources.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/concierge/concierge_client.h"
@@ -140,8 +139,6 @@
 
  private:
   content::BrowserTaskEnvironment task_environment_;
-  ScopedTestingLocalState scoped_testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
   user_manager::TypedScopedUserManager<ash::FakeChromeUserManager>
       fake_user_manager_;
   session_manager::SessionManager session_manager_;
diff --git a/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc b/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc
index 14a5a4b..8e9e5088 100644
--- a/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc
+++ b/chrome/browser/ash/arc/session/arc_session_manager_unittest.cc
@@ -51,7 +51,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/ash/login/fake_login_display_host.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/browser_context_helper/annotated_account_id.h"
@@ -367,8 +366,6 @@
   }
 
   content::BrowserTaskEnvironment task_environment_;
-  ScopedTestingLocalState scoped_testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
   user_manager::TypedScopedUserManager<ash::FakeChromeUserManager>
       fake_user_manager_;
   session_manager::SessionManager session_manager_;
diff --git a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.cc b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.cc
index 56c4f8c1..257b54b9 100644
--- a/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.cc
+++ b/chrome/browser/ash/arc/tracing/arc_app_performance_tracing.cc
@@ -7,6 +7,7 @@
 #include "ash/constants/ash_features.h"
 #include "ash/display/cros_display_config.h"
 #include "ash/shell.h"
+#include "base/check_is_test.h"
 #include "base/functional/bind.h"
 #include "base/memory/singleton.h"
 #include "base/metrics/histogram_functions.h"
diff --git a/chrome/browser/ash/arc/vmm/arc_vmm_swap_scheduler_unittest.cc b/chrome/browser/ash/arc/vmm/arc_vmm_swap_scheduler_unittest.cc
index 809f584..84bfed6 100644
--- a/chrome/browser/ash/arc/vmm/arc_vmm_swap_scheduler_unittest.cc
+++ b/chrome/browser/ash/arc/vmm/arc_vmm_swap_scheduler_unittest.cc
@@ -12,12 +12,12 @@
 #include "base/time/time.h"
 #include "chrome/browser/ash/arc/vmm/arc_system_state_observation.h"
 #include "chrome/browser/ash/arc/vmm/arc_vmm_manager.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/concierge/fake_concierge_client.h"
 #include "chromeos/ash/experiences/arc/arc_prefs.h"
 #include "chromeos/ash/experiences/arc/session/arc_service_manager.h"
+#include "components/prefs/pref_service.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -55,9 +55,7 @@
 
 class ArcVmmSwapSchedulerTest : public testing::Test {
  public:
-  ArcVmmSwapSchedulerTest() : local_state_(TestingBrowserProcess::GetGlobal()) {
-    ash::ConciergeClient::InitializeFake();
-  }
+  ArcVmmSwapSchedulerTest() { ash::ConciergeClient::InitializeFake(); }
 
   ArcVmmSwapSchedulerTest(const ArcVmmSwapSchedulerTest&) = delete;
   ArcVmmSwapSchedulerTest& operator=(const ArcVmmSwapSchedulerTest&) = delete;
@@ -65,11 +63,13 @@
   ~ArcVmmSwapSchedulerTest() override { ash::ConciergeClient::Shutdown(); }
 
   void SetSwapOutTime(base::Time time) {
-    local_state_.Get()->SetTime(prefs::kArcVmmSwapOutTime, base::Time());
+    TestingBrowserProcess::GetGlobal()->local_state()->SetTime(
+        prefs::kArcVmmSwapOutTime, base::Time());
   }
 
   base::Time GetSwapOutTime() {
-    return local_state_.Get()->GetTime(prefs::kArcVmmSwapOutTime);
+    return TestingBrowserProcess::GetGlobal()->local_state()->GetTime(
+        prefs::kArcVmmSwapOutTime);
   }
 
   base::test::TaskEnvironment* task_environment() { return &task_environment_; }
@@ -77,9 +77,6 @@
  protected:
   content::BrowserTaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
-
- private:
-  ScopedTestingLocalState local_state_;
 };
 
 TEST_F(ArcVmmSwapSchedulerTest, SetSwapEnableDisable) {
diff --git a/chrome/browser/ash/arc/wallpaper/arc_wallpaper_service_unittest.cc b/chrome/browser/ash/arc/wallpaper/arc_wallpaper_service_unittest.cc
index 28bfc51..6a966c2 100644
--- a/chrome/browser/ash/arc/wallpaper/arc_wallpaper_service_unittest.cc
+++ b/chrome/browser/ash/arc/wallpaper/arc_wallpaper_service_unittest.cc
@@ -20,7 +20,6 @@
 #include "chrome/browser/ui/ash/wallpaper/test_wallpaper_controller.h"
 #include "chrome/browser/ui/ash/wallpaper/wallpaper_controller_client_impl.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/cryptohome/system_salt_getter.h"
@@ -117,13 +116,10 @@
 
  private:
   std::unique_ptr<content::BrowserTaskEnvironment> task_environment_;
-  ScopedTestingLocalState scoped_testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
   user_manager::TypedScopedUserManager<ash::FakeChromeUserManager>
       fake_user_manager_;
   arc::ArcServiceManager arc_service_manager_;
-  // testing_profile_ needs to be deleted before arc_service_manager_ and
-  // scoped_testing_local_state_.
+  // testing_profile_ needs to be deleted before arc_service_manager_.
   TestingProfile testing_profile_;
 };
 
diff --git a/chrome/browser/ash/browser_delegate/BUILD.gn b/chrome/browser/ash/browser_delegate/BUILD.gn
index b8e17aa..f4990fb8 100644
--- a/chrome/browser/ash/browser_delegate/BUILD.gn
+++ b/chrome/browser/ash/browser_delegate/BUILD.gn
@@ -15,6 +15,7 @@
 
   public_deps = [
     "//base",
+    "//components/account_id",
     "//components/sessions:session_id",
     "//components/webapps/common",
     "//ui/gfx/geometry",
diff --git a/chrome/browser/ash/browser_delegate/browser_delegate.h b/chrome/browser/ash/browser_delegate/browser_delegate.h
index 6f29d14..32009409 100644
--- a/chrome/browser/ash/browser_delegate/browser_delegate.h
+++ b/chrome/browser/ash/browser_delegate/browser_delegate.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_ASH_BROWSER_DELEGATE_BROWSER_DELEGATE_H_
 
 #include "chrome/browser/ash/browser_delegate/browser_type.h"
+#include "components/account_id/account_id.h"
 #include "components/sessions/core/session_id.h"
 #include "ui/gfx/geometry/rect.h"
 
@@ -42,6 +43,10 @@
   // Returns the browser's unique ID for the current session.
   virtual SessionID GetSessionID() const = 0;
 
+  // Returns the account id associated with the browser. In production, this id
+  // should always be valid (see AccountId::is_valid).
+  virtual const AccountId& GetAccountId() const = 0;
+
   // Returns whether the browser is off the record, i.e. incognito or in a guest
   // session.
   virtual bool IsOffTheRecord() const = 0;
diff --git a/chrome/browser/ash/browser_delegate/browser_delegate_impl.cc b/chrome/browser/ash/browser_delegate/browser_delegate_impl.cc
index 03c882c..d09f551 100644
--- a/chrome/browser/ash/browser_delegate/browser_delegate_impl.cc
+++ b/chrome/browser/ash/browser_delegate/browser_delegate_impl.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ash/browser_delegate/browser_delegate_impl.h"
 
 #include "base/check_deref.h"
+#include "base/check_is_test.h"
 #include "chrome/browser/ash/browser_delegate/browser_type_conversion.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
@@ -14,6 +15,7 @@
 #include "chrome/browser/ui/tabs/tab_model.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
+#include "chromeos/ash/components/browser_context_helper/annotated_account_id.h"
 #include "components/tab_groups/tab_group_id.h"
 #include "components/tab_groups/tab_group_info.h"
 
@@ -36,6 +38,17 @@
   return browser_->session_id();
 }
 
+const AccountId& BrowserDelegateImpl::GetAccountId() const {
+  const AccountId* id =
+      ash::AnnotatedAccountId::Get(browser_->profile()->GetOriginalProfile());
+  if (id) {
+    CHECK(id->is_valid());
+  } else {
+    CHECK_IS_TEST();
+  }
+  return id ? *id : EmptyAccountId();
+}
+
 bool BrowserDelegateImpl::IsOffTheRecord() const {
   return browser_->profile()->IsOffTheRecord();
 }
diff --git a/chrome/browser/ash/browser_delegate/browser_delegate_impl.h b/chrome/browser/ash/browser_delegate/browser_delegate_impl.h
index 05935b4b..6a97f31 100644
--- a/chrome/browser/ash/browser_delegate/browser_delegate_impl.h
+++ b/chrome/browser/ash/browser_delegate/browser_delegate_impl.h
@@ -21,6 +21,7 @@
   Browser& GetBrowser() const override;
   BrowserType GetType() const override;
   SessionID GetSessionID() const override;
+  const AccountId& GetAccountId() const override;
   bool IsOffTheRecord() const override;
   gfx::Rect GetBounds() const override;
   content::WebContents* GetActiveWebContents() const override;
diff --git a/chrome/browser/ash/bruschetta/bruschetta_installer_impl_unittest.cc b/chrome/browser/ash/bruschetta/bruschetta_installer_impl_unittest.cc
index c6031538..8074fab 100644
--- a/chrome/browser/ash/bruschetta/bruschetta_installer_impl_unittest.cc
+++ b/chrome/browser/ash/bruschetta/bruschetta_installer_impl_unittest.cc
@@ -22,7 +22,6 @@
 #include "chrome/browser/ash/bruschetta/bruschetta_service_factory.h"
 #include "chrome/browser/ash/guest_os/dbus_test_helper.h"
 #include "chrome/browser/profiles/profile_key.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/attestation/attestation_client.h"
@@ -34,6 +33,7 @@
 #include "chromeos/ash/components/system/fake_statistics_provider.h"
 #include "chromeos/ash/components/system/statistics_provider.h"
 #include "components/prefs/pref_service.h"
+#include "components/prefs/testing_pref_service.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest-spi.h"
@@ -146,7 +146,7 @@
     ash::disks::DiskMountManager::InitializeForTesting(&*disk_mount_manager_);
 
     installer_ = std::make_unique<BruschettaInstallerImpl>(
-        &profile_, *local_state_.Get(),
+        &profile_, *TestingBrowserProcess::GetGlobal()->GetTestingLocalState(),
         base::BindOnce(&BruschettaInstallerTest::CloseCallback,
                        base::Unretained(this)));
 
@@ -603,7 +603,6 @@
 
   content::BrowserTaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
 
   base::RunLoop run_loop_, run_loop_2_;
 
diff --git a/chrome/browser/ash/child_accounts/on_device_controls/app_controls_notifier_unittest.cc b/chrome/browser/ash/child_accounts/on_device_controls/app_controls_notifier_unittest.cc
index bf365536..7d33850 100644
--- a/chrome/browser/ash/child_accounts/on_device_controls/app_controls_notifier_unittest.cc
+++ b/chrome/browser/ash/child_accounts/on_device_controls/app_controls_notifier_unittest.cc
@@ -36,9 +36,6 @@
  public:
   AppControlsNotifierTest() {
     scoped_feature_list_.InitAndEnableFeature(features::kOnDeviceAppControls);
-
-    statistics_provider_.SetMachineStatistic(ash::system::kRegionKey,
-                                             kEligibleDeviceRegionKey);
   }
   AppControlsNotifierTest(const AppControlsNotifierTest&) = delete;
   AppControlsNotifierTest& operator=(const AppControlsNotifierTest&) = delete;
@@ -47,6 +44,11 @@
   // BrowserWithTestWindowTest:
   void SetUp() override {
     BrowserWithTestWindowTest::SetUp();
+
+    statistics_provider_.emplace();
+    statistics_provider_->SetMachineStatistic(ash::system::kRegionKey,
+                                              kEligibleDeviceRegionKey);
+
     TestingBrowserProcess::GetGlobal()->SetSystemNotificationHelper(
         std::make_unique<SystemNotificationHelper>());
     tester_ = std::make_unique<NotificationDisplayServiceTester>(profile());
@@ -77,7 +79,7 @@
  private:
   std::unique_ptr<AppControlsNotifier> app_controls_notifier_;
   std::unique_ptr<NotificationDisplayServiceTester> tester_;
-  ash::system::ScopedFakeStatisticsProvider statistics_provider_;
+  std::optional<ash::system::ScopedFakeStatisticsProvider> statistics_provider_;
 };
 
 TEST_F(AppControlsNotifierTest, ShowAppControlsNotification) {
diff --git a/chrome/browser/ash/crosapi/crosapi_util_unittest.cc b/chrome/browser/ash/crosapi/crosapi_util_unittest.cc
index d40f7bd..65c1f3e 100644
--- a/chrome/browser/ash/crosapi/crosapi_util_unittest.cc
+++ b/chrome/browser/ash/crosapi/crosapi_util_unittest.cc
@@ -16,7 +16,6 @@
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/ash/policy/core/user_cloud_policy_manager_ash.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
@@ -29,6 +28,7 @@
 #include "components/policy/core/common/cloud/mock_cloud_external_data_manager.h"
 #include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
 #include "components/policy/proto/device_management_backend.pb.h"
+#include "components/prefs/testing_pref_service.h"
 #include "components/user_manager/scoped_user_manager.h"
 #include "components/user_manager/test_helper.h"
 #include "content/public/test/browser_task_environment.h"
@@ -110,7 +110,6 @@
 
   // The order of these members is relevant for both construction and
   // destruction timing.
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
   content::BrowserTaskEnvironment task_environment_;
   user_manager::TypedScopedUserManager<ash::FakeChromeUserManager>
       fake_user_manager_;
diff --git a/chrome/browser/ash/crostini/crostini_export_import_unittest.cc b/chrome/browser/ash/crostini/crostini_export_import_unittest.cc
index 9d43b55..4e29171 100644
--- a/chrome/browser/ash/crostini/crostini_export_import_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_export_import_unittest.cc
@@ -19,7 +19,6 @@
 #include "chrome/browser/ash/guest_os/guest_os_share_path_factory.h"
 #include "chrome/browser/notifications/notification_display_service_factory.h"
 #include "chrome/browser/notifications/notification_display_service_tester.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/chunneld/chunneld_client.h"
@@ -221,9 +220,6 @@
   base::FilePath tarball_;
 
   content::BrowserTaskEnvironment task_environment_;
-
-  // Needed for `DriveIntegrationService`, which `GuestOsSharePath` depends on.
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
 };
 
 TEST_F(CrostiniExportImportTest, TestNotAllowed) {
diff --git a/chrome/browser/ash/crostini/crostini_installer_unittest.cc b/chrome/browser/ash/crostini/crostini_installer_unittest.cc
index 9361d36..f072fe8 100644
--- a/chrome/browser/ash/crostini/crostini_installer_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_installer_unittest.cc
@@ -19,7 +19,6 @@
 #include "chrome/browser/ash/crostini/crostini_types.mojom.h"
 #include "chrome/browser/notifications/system_notification_helper.h"
 #include "chrome/test/base/browser_process_platform_part_test_api_chromeos.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/chunneld/chunneld_client.h"
@@ -89,10 +88,7 @@
     base::test::TestFuture<void> result_future_;
   };
 
-  CrostiniInstallerTest()
-      : local_state_(std::make_unique<ScopedTestingLocalState>(
-            TestingBrowserProcess::GetGlobal())),
-        browser_part_(g_browser_process->platform_part()) {}
+  CrostiniInstallerTest() : browser_part_(g_browser_process->platform_part()) {}
 
   CrostiniInstallerTest(const CrostiniInstallerTest&) = delete;
   CrostiniInstallerTest& operator=(const CrostiniInstallerTest&) = delete;
@@ -201,7 +197,6 @@
   std::unique_ptr<CrostiniInstaller> crostini_installer_;
 
  private:
-  std::unique_ptr<ScopedTestingLocalState> local_state_;
   scoped_refptr<component_updater::FakeComponentManagerAsh> component_manager_;
   BrowserProcessPlatformPartTestApi browser_part_;
 };
diff --git a/chrome/browser/ash/crostini/crostini_manager_unittest.cc b/chrome/browser/ash/crostini/crostini_manager_unittest.cc
index 712abeb..62df170 100644
--- a/chrome/browser/ash/crostini/crostini_manager_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_manager_unittest.cc
@@ -41,7 +41,6 @@
 #include "chrome/browser/ui/views/crostini/crostini_ansible_software_config_view.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/test/base/browser_process_platform_part_test_api_chromeos.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/anomaly_detector/anomaly_detector_client.h"
@@ -155,8 +154,6 @@
   CrostiniManagerTest()
       : task_environment_(content::BrowserTaskEnvironment::REAL_IO_THREAD,
                           base::test::TaskEnvironment::TimeSource::MOCK_TIME),
-        local_state_(std::make_unique<ScopedTestingLocalState>(
-            TestingBrowserProcess::GetGlobal())),
         browser_part_(g_browser_process->platform_part()) {
     ash::AnomalyDetectorClient::InitializeFake();
     ash::ChunneldClient::InitializeFake();
@@ -256,7 +253,6 @@
   content::BrowserTaskEnvironment task_environment_;
 
  private:
-  std::unique_ptr<ScopedTestingLocalState> local_state_;
   scoped_refptr<component_updater::FakeComponentManagerAsh> component_manager_;
   BrowserProcessPlatformPartTestApi browser_part_;
 };
diff --git a/chrome/browser/ash/crostini/crostini_util_unittest.cc b/chrome/browser/ash/crostini/crostini_util_unittest.cc
index 1959522..0c9e128 100644
--- a/chrome/browser/ash/crostini/crostini_util_unittest.cc
+++ b/chrome/browser/ash/crostini/crostini_util_unittest.cc
@@ -13,7 +13,6 @@
 #include "chrome/browser/ash/crostini/crostini_test_helper.h"
 #include "chrome/browser/ash/guest_os/guest_os_pref_names.h"
 #include "chrome/test/base/browser_process_platform_part_test_api_chromeos.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/chunneld/chunneld_client.h"
@@ -24,6 +23,7 @@
 #include "chromeos/ash/components/dbus/dlcservice/dlcservice_client.h"
 #include "chromeos/ash/components/dbus/seneschal/seneschal_client.h"
 #include "components/component_updater/ash/fake_component_manager_ash.h"
+#include "components/prefs/pref_service.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -37,8 +37,6 @@
   CrostiniUtilTest()
       : app_id_(crostini::CrostiniTestHelper::GenerateAppId(kDesktopFileId)),
         task_environment_(content::BrowserTaskEnvironment::REAL_IO_THREAD),
-        local_state_(std::make_unique<ScopedTestingLocalState>(
-            TestingBrowserProcess::GetGlobal())),
         browser_part_(g_browser_process->platform_part()) {
     ash::ChunneldClient::InitializeFake();
     ash::CiceroneClient::InitializeFake();
@@ -98,7 +96,6 @@
 
  private:
   content::BrowserTaskEnvironment task_environment_;
-  std::unique_ptr<ScopedTestingLocalState> local_state_;
   scoped_refptr<component_updater::FakeComponentManagerAsh> component_manager_;
   BrowserProcessPlatformPartTestApi browser_part_;
 };
diff --git a/chrome/browser/ash/customization/customization_document_unittest.cc b/chrome/browser/ash/customization/customization_document_unittest.cc
index 8bfd395..bcf3f31 100644
--- a/chrome/browser/ash/customization/customization_document_unittest.cc
+++ b/chrome/browser/ash/customization/customization_document_unittest.cc
@@ -16,7 +16,6 @@
 #include "chrome/browser/extensions/external_provider_impl.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/network/network_handler.h"
@@ -276,8 +275,6 @@
 
  private:
   content::BrowserTaskEnvironment task_environment_;
-  ScopedTestingLocalState scoped_testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
   NetworkHandlerTestHelper network_handler_test_helper_;
   system::ScopedFakeStatisticsProvider fake_statistics_provider_;
   ScopedCrosSettingsTestHelper scoped_cros_settings_test_helper_;
diff --git a/chrome/browser/ash/dbus/proxy_resolution_service_provider_unittest.cc b/chrome/browser/ash/dbus/proxy_resolution_service_provider_unittest.cc
index 2a87066..c6ac1a74 100644
--- a/chrome/browser/ash/dbus/proxy_resolution_service_provider_unittest.cc
+++ b/chrome/browser/ash/dbus/proxy_resolution_service_provider_unittest.cc
@@ -10,12 +10,12 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "chrome/browser/ash/net/system_proxy_manager.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/dbus/services/service_provider_test_helper.h"
 #include "chromeos/ash/components/dbus/system_proxy/system_proxy_client.h"
 #include "chromeos/ash/components/install_attributes/stub_install_attributes.h"
 #include "chromeos/ash/components/network/network_handler_test_helper.h"
+#include "components/prefs/pref_service.h"
 #include "dbus/message.h"
 #include "dbus/object_path.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
@@ -224,9 +224,7 @@
 class ProxyResolutionServiceWithSystemProxyTest
     : public ProxyResolutionServiceProviderTest {
  public:
-  ProxyResolutionServiceWithSystemProxyTest()
-      : ProxyResolutionServiceProviderTest(),
-        local_state_(TestingBrowserProcess::GetGlobal()) {}
+  ProxyResolutionServiceWithSystemProxyTest() = default;
   ~ProxyResolutionServiceWithSystemProxyTest() override = default;
 
   // testing::Test
@@ -236,7 +234,8 @@
     ProxyResolutionServiceProviderTest::SetUp();
 
     SystemProxyClient::InitializeFake();
-    SystemProxyManager::Initialize(local_state_.Get());
+    SystemProxyManager::Initialize(
+        TestingBrowserProcess::GetGlobal()->local_state());
     SystemProxyManager::Get()->SetSystemServicesProxyUrlForTest(
         "system-proxy:3128");
   }
@@ -270,9 +269,6 @@
     EXPECT_TRUE(reader.PopString(&result->error));
   }
 
- protected:
-  ScopedTestingLocalState local_state_;
-
  private:
   NetworkHandlerTestHelper network_handler_test_helper_;
   base::test::ScopedFeatureList scoped_feature_list_;
diff --git a/chrome/browser/ash/exo/chrome_security_delegate_unittest.cc b/chrome/browser/ash/exo/chrome_security_delegate_unittest.cc
index 5885fc1..a2a67f8 100644
--- a/chrome/browser/ash/exo/chrome_security_delegate_unittest.cc
+++ b/chrome/browser/ash/exo/chrome_security_delegate_unittest.cc
@@ -22,7 +22,6 @@
 #include "chrome/browser/ash/guest_os/guest_os_share_path.h"
 #include "chrome/browser/ash/guest_os/guest_os_share_path_factory.h"
 #include "chrome/browser/ash/plugin_vm/plugin_vm_util.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/chunneld/chunneld_client.h"
@@ -127,9 +126,6 @@
 
   content::BrowserTaskEnvironment task_environment_;
 
-  // Needed for `DriveIntegrationService`, which `GuestOsSharePath` depends on.
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
-
   std::unique_ptr<TestingProfile> profile_;
   std::unique_ptr<crostini::CrostiniTestHelper> test_helper_;
 
diff --git a/chrome/browser/ash/extensions/extensions_permissions_tracker_unittest.cc b/chrome/browser/ash/extensions/extensions_permissions_tracker_unittest.cc
index 41fcc1e..e21dffe 100644
--- a/chrome/browser/ash/extensions/extensions_permissions_tracker_unittest.cc
+++ b/chrome/browser/ash/extensions/extensions_permissions_tracker_unittest.cc
@@ -9,7 +9,6 @@
 #include "base/memory/raw_ptr.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/login/login_state/scoped_test_public_session_login_state.h"
@@ -74,8 +73,7 @@
  public:
   ExtensionsPermissionsTrackerTest()
       : prefs_(profile_.GetTestingPrefService()),
-        registry_(ExtensionRegistry::Get(&profile_)),
-        testing_local_state_(TestingBrowserProcess::GetGlobal()) {}
+        registry_(ExtensionRegistry::Get(&profile_)) {}
 
   ExtensionsPermissionsTrackerTest(const ExtensionsPermissionsTrackerTest&) =
       delete;
@@ -116,23 +114,22 @@
   TestingProfile profile_;
   raw_ptr<sync_preferences::TestingPrefServiceSyncable> prefs_;
   raw_ptr<ExtensionRegistry> registry_;
-  ScopedTestingLocalState testing_local_state_;
   std::unique_ptr<MockExtensionsPermissionsTracker> permissions_tracker_;
 };
 
 TEST_F(ExtensionsPermissionsTrackerTest, EmptyForceList) {
-  EXPECT_TRUE(testing_local_state_.Get()->GetBoolean(
+  EXPECT_TRUE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kManagedSessionUseFullLoginWarning));
 
   SetupEmptyForceList();
   CreateExtensionsPermissionsTracker();
 
-  EXPECT_FALSE(testing_local_state_.Get()->GetBoolean(
+  EXPECT_FALSE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kManagedSessionUseFullLoginWarning));
 }
 
 TEST_F(ExtensionsPermissionsTrackerTest, SafeForceListInstalled) {
-  EXPECT_TRUE(testing_local_state_.Get()->GetBoolean(
+  EXPECT_TRUE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kManagedSessionUseFullLoginWarning));
 
   SetupForceList();
@@ -146,7 +143,7 @@
                               std::end(kSafePermissionsSet2));
   AddExtensionWithIdAndPermissions(kExtensionId2, v2);
 
-  EXPECT_FALSE(testing_local_state_.Get()->GetBoolean(
+  EXPECT_FALSE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kManagedSessionUseFullLoginWarning));
 }
 
@@ -163,7 +160,7 @@
   AddExtensionWithIdAndPermissions(kExtensionId1, v1);
   AddExtensionWithIdAndPermissions(kExtensionId2, v2);
 
-  EXPECT_TRUE(testing_local_state_.Get()->GetBoolean(
+  EXPECT_TRUE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kManagedSessionUseFullLoginWarning));
 }
 
@@ -179,7 +176,7 @@
                               std::end(kSafePermissionsSet2));
   AddExtensionWithIdAndPermissions(kExtensionId2, v2);
 
-  EXPECT_TRUE(testing_local_state_.Get()->GetBoolean(
+  EXPECT_TRUE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kManagedSessionUseFullLoginWarning));
 }
 
@@ -195,7 +192,7 @@
                               std::end(kSafePermissionsSet2));
   AddExtensionWithIdAndPermissions(kExtensionId2, v2);
 
-  EXPECT_FALSE(testing_local_state_.Get()->GetBoolean(
+  EXPECT_FALSE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kManagedSessionUseFullLoginWarning));
 
   dict.Set(kExtensionId3, kExtensionUrl3);
@@ -205,7 +202,7 @@
                               std::end(kUnsafePermissionsSet1));
   AddExtensionWithIdAndPermissions(kExtensionId3, v3);
 
-  EXPECT_TRUE(testing_local_state_.Get()->GetBoolean(
+  EXPECT_TRUE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kManagedSessionUseFullLoginWarning));
 }
 
@@ -221,12 +218,12 @@
                               std::end(kSafePermissionsSet2));
   AddExtensionWithIdAndPermissions(kExtensionId2, v2);
 
-  EXPECT_TRUE(testing_local_state_.Get()->GetBoolean(
+  EXPECT_TRUE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kManagedSessionUseFullLoginWarning));
 
   dict.Remove(kExtensionId1);
   prefs_->SetManagedPref(pref_names::kInstallForceList, std::move(dict));
-  EXPECT_FALSE(testing_local_state_.Get()->GetBoolean(
+  EXPECT_FALSE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kManagedSessionUseFullLoginWarning));
 }
 
@@ -238,14 +235,14 @@
                               std::end(kSafePermissionsSet1));
   AddExtensionWithIdAndPermissions(kExtensionId1, v1);
 
-  EXPECT_TRUE(testing_local_state_.Get()->GetBoolean(
+  EXPECT_TRUE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kManagedSessionUseFullLoginWarning));
 
   std::vector<std::string> v2(std::begin(kSafePermissionsSet2),
                               std::end(kSafePermissionsSet2));
   AddExtensionWithIdAndPermissions(kExtensionId2, v2);
 
-  EXPECT_FALSE(testing_local_state_.Get()->GetBoolean(
+  EXPECT_FALSE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kManagedSessionUseFullLoginWarning));
 }
 
@@ -257,14 +254,14 @@
                               std::end(kSafePermissionsSet1));
   AddExtensionWithIdAndPermissions(kExtensionId1, v1);
 
-  EXPECT_TRUE(testing_local_state_.Get()->GetBoolean(
+  EXPECT_TRUE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kManagedSessionUseFullLoginWarning));
 
   std::vector<std::string> v2(std::begin(kUnsafePermissionsSet1),
                               std::end(kUnsafePermissionsSet1));
   AddExtensionWithIdAndPermissions(kExtensionId2, v2);
 
-  EXPECT_TRUE(testing_local_state_.Get()->GetBoolean(
+  EXPECT_TRUE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kManagedSessionUseFullLoginWarning));
 }
 
@@ -280,19 +277,19 @@
                               std::end(kUnsafePermissionsSet1));
   AddExtensionWithIdAndPermissions(kExtensionId2, v2);
 
-  EXPECT_TRUE(testing_local_state_.Get()->GetBoolean(
+  EXPECT_TRUE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kManagedSessionUseFullLoginWarning));
 
   dict.Remove(kExtensionId1);
   prefs_->SetManagedPref(pref_names::kInstallForceList, dict.Clone());
 
-  EXPECT_TRUE(testing_local_state_.Get()->GetBoolean(
+  EXPECT_TRUE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kManagedSessionUseFullLoginWarning));
 
   dict.Remove(kExtensionId2);
   prefs_->SetManagedPref(pref_names::kInstallForceList, dict.Clone());
 
-  EXPECT_FALSE(testing_local_state_.Get()->GetBoolean(
+  EXPECT_FALSE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kManagedSessionUseFullLoginWarning));
 }
 
@@ -312,7 +309,7 @@
                               std::end(kUnsafePermissionsSet1));
   AddExtensionWithIdAndPermissions(kExtensionId3, v3);
 
-  EXPECT_FALSE(testing_local_state_.Get()->GetBoolean(
+  EXPECT_FALSE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kManagedSessionUseFullLoginWarning));
 }
 
diff --git a/chrome/browser/ash/extensions/file_manager/event_router_unittest.cc b/chrome/browser/ash/extensions/file_manager/event_router_unittest.cc
index 3d763a70..a98f89e 100644
--- a/chrome/browser/ash/extensions/file_manager/event_router_unittest.cc
+++ b/chrome/browser/ash/extensions/file_manager/event_router_unittest.cc
@@ -21,10 +21,10 @@
 #include "chrome/browser/ash/fileapi/file_system_backend.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/disks/fake_disk_mount_manager.h"
+#include "components/prefs/pref_service.h"
 #include "content/public/test/browser_task_environment.h"
 #include "extensions/browser/event_router.h"
 #include "extensions/browser/test_event_router.h"
@@ -119,8 +119,7 @@
 
 class FileManagerEventRouterTest : public testing::Test {
  public:
-  FileManagerEventRouterTest()
-      : scoped_testing_local_state_(TestingBrowserProcess::GetGlobal()) {}
+  FileManagerEventRouterTest() = default;
   FileManagerEventRouterTest(const FileManagerEventRouterTest&) = delete;
   FileManagerEventRouterTest& operator=(const FileManagerEventRouterTest&) =
       delete;
@@ -167,7 +166,6 @@
     return io_task::EntryStatus(std::move(url), base::File::FILE_OK);
   }
 
-  ScopedTestingLocalState scoped_testing_local_state_;
   content::BrowserTaskEnvironment task_environment_;
   display::test::TestScreen test_screen_{/*create_display=*/true,
                                          /*register_screen=*/true};
@@ -408,8 +406,8 @@
   ~FileManagerEventRouterLocalFilesTest() override = default;
 
   void SetLocalUserFilesPolicy(bool allowed) {
-    scoped_testing_local_state_.Get()->SetBoolean(prefs::kLocalUserFilesAllowed,
-                                                  allowed);
+    TestingBrowserProcess::GetGlobal()->local_state()->SetBoolean(
+        prefs::kLocalUserFilesAllowed, allowed);
   }
 
  private:
diff --git a/chrome/browser/ash/file_manager/copy_or_move_io_task_unittest.cc b/chrome/browser/ash/file_manager/copy_or_move_io_task_unittest.cc
index 64d29bca..0230422c 100644
--- a/chrome/browser/ash/file_manager/copy_or_move_io_task_unittest.cc
+++ b/chrome/browser/ash/file_manager/copy_or_move_io_task_unittest.cc
@@ -28,10 +28,10 @@
 #include "chrome/browser/ash/file_manager/path_util.h"
 #include "chrome/browser/ash/file_manager/volume_manager.h"
 #include "chrome/browser/ash/file_manager/volume_manager_factory.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/disks/fake_disk_mount_manager.h"
+#include "components/prefs/pref_service.h"
 #include "content/public/test/browser_task_environment.h"
 #include "storage/browser/file_system/file_system_url.h"
 #include "storage/browser/quota/quota_manager_proxy.h"
@@ -94,8 +94,7 @@
 
 class CopyOrMoveIOTaskTestBase : public testing::Test {
  public:
-  CopyOrMoveIOTaskTestBase()
-      : scoped_testing_local_state_(TestingBrowserProcess::GetGlobal()) {}
+  CopyOrMoveIOTaskTestBase() = default;
 
  protected:
   void SetUp() override {
@@ -116,7 +115,6 @@
         base::FilePath::FromUTF8Unsafe(path));
   }
 
-  ScopedTestingLocalState scoped_testing_local_state_;
   content::BrowserTaskEnvironment task_environment_;
   ash::disks::FakeDiskMountManager disk_mount_manager_;
   TestingProfile profile_;
diff --git a/chrome/browser/ash/file_manager/path_util_unittest.cc b/chrome/browser/ash/file_manager/path_util_unittest.cc
index e1c130c7..86a3c298 100644
--- a/chrome/browser/ash/file_manager/path_util_unittest.cc
+++ b/chrome/browser/ash/file_manager/path_util_unittest.cc
@@ -42,7 +42,6 @@
 #include "chrome/browser/download/download_prefs.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/common/extensions/api/file_system_provider_capabilities/file_system_provider_capabilities_handler.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
@@ -62,6 +61,7 @@
 #include "chromeos/ash/experiences/arc/test/fake_file_system_instance.h"
 #include "components/account_id/account_id.h"
 #include "components/drive/drive_pref_names.h"
+#include "components/prefs/pref_service.h"
 #include "components/user_manager/scoped_user_manager.h"
 #include "content/public/test/browser_task_environment.h"
 #include "google_apis/gaia/gaia_id.h"
@@ -111,9 +111,6 @@
  protected:
   content::BrowserTaskEnvironment task_environment_;
 
-  // Needed for `DriveIntegrationService`.
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
-
   user_manager::TypedScopedUserManager<ash::FakeChromeUserManager>
       user_manager_{std::make_unique<ash::FakeChromeUserManager>()};
   std::unique_ptr<TestingProfile> profile_;
@@ -810,9 +807,6 @@
  protected:
   content::BrowserTaskEnvironment task_environment_;
 
-  // Needed for `DriveIntegrationService`.
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
-
   arc::FakeFileSystemInstance fake_file_system_;
   user_manager::TypedScopedUserManager<ash::FakeChromeUserManager>
       fake_user_manager_;
diff --git a/chrome/browser/ash/file_manager/trash_io_task_unittest.cc b/chrome/browser/ash/file_manager/trash_io_task_unittest.cc
index 7694ce0..557373d5 100644
--- a/chrome/browser/ash/file_manager/trash_io_task_unittest.cc
+++ b/chrome/browser/ash/file_manager/trash_io_task_unittest.cc
@@ -17,7 +17,6 @@
 #include "chrome/browser/ash/drive/drive_integration_service_factory.h"
 #include "chrome/browser/ash/file_manager/trash_common_util.h"
 #include "chrome/browser/ash/file_manager/trash_unittest_base.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "components/account_id/account_id.h"
 #include "components/drive/drive_pref_names.h"
@@ -196,9 +195,6 @@
 }
 
 TEST_F(TrashIOTaskTest, SupportedDirectoryShouldSucceed) {
-  // Needed for `DriveIntegrationService`.
-  ScopedTestingLocalState local_state(TestingBrowserProcess::GetGlobal());
-
   // Force the drive integration service to be created, this ensures the code
   // path that adds the drive mount point is exercised.
   drive::DriveIntegrationServiceFactory::GetForProfile(profile_.get());
diff --git a/chrome/browser/ash/file_manager/volume_manager_unittest.cc b/chrome/browser/ash/file_manager/volume_manager_unittest.cc
index 95ce2f45..6b4956f 100644
--- a/chrome/browser/ash/file_manager/volume_manager_unittest.cc
+++ b/chrome/browser/ash/file_manager/volume_manager_unittest.cc
@@ -40,7 +40,6 @@
 #include "chrome/browser/download/download_dir_util.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
diff --git a/chrome/browser/ash/growth/campaigns_manager_client_unittest.cc b/chrome/browser/ash/growth/campaigns_manager_client_unittest.cc
index 074147ae..df53544 100644
--- a/chrome/browser/ash/growth/campaigns_manager_client_unittest.cc
+++ b/chrome/browser/ash/growth/campaigns_manager_client_unittest.cc
@@ -14,7 +14,6 @@
 #include "chrome/browser/ash/growth/metrics.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/test/base/browser_process_platform_part_test_api_chromeos.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "components/component_updater/ash/fake_component_manager_ash.h"
diff --git a/chrome/browser/ash/guest_os/guest_os_share_path_unittest.cc b/chrome/browser/ash/guest_os/guest_os_share_path_unittest.cc
index 165d1e2..62dc1f9 100644
--- a/chrome/browser/ash/guest_os/guest_os_share_path_unittest.cc
+++ b/chrome/browser/ash/guest_os/guest_os_share_path_unittest.cc
@@ -30,7 +30,6 @@
 #include "chrome/browser/ash/settings/scoped_testing_cros_settings.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/test/base/browser_process_platform_part_test_api_chromeos.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/chunneld/chunneld_client.h"
@@ -214,10 +213,7 @@
                         expected_failure_reason, success, failure_reason);
   }
 
-  GuestOsSharePathTest()
-      : local_state_(std::make_unique<ScopedTestingLocalState>(
-            TestingBrowserProcess::GetGlobal())),
-        browser_part_(g_browser_process->platform_part()) {
+  GuestOsSharePathTest() : browser_part_(g_browser_process->platform_part()) {
     ash::ChunneldClient::InitializeFake();
     ash::CiceroneClient::InitializeFake();
     ash::ConciergeClient::InitializeFake();
@@ -274,7 +270,8 @@
     // Setup for DriveFS.
     user_manager_.Reset(std::make_unique<user_manager::UserManagerImpl>(
         std::make_unique<user_manager::FakeUserManagerDelegate>(),
-        local_state_->Get(), ash::CrosSettings::Get()));
+        TestingBrowserProcess::GetGlobal()->local_state(),
+        ash::CrosSettings::Get()));
     account_id_ = AccountId::FromUserEmailGaiaId(
         profile()->GetProfileUserName(), GaiaId("12345"));
     ASSERT_TRUE(user_manager::TestHelper(user_manager::UserManager::Get())
@@ -354,7 +351,6 @@
   std::unique_ptr<arc::ArcSessionManager> arc_session_manager_;
 
  private:
-  std::unique_ptr<ScopedTestingLocalState> local_state_;
   scoped_refptr<component_updater::FakeComponentManagerAsh> component_manager_;
   BrowserProcessPlatformPartTestApi browser_part_;
 };
diff --git a/chrome/browser/ash/input_method/editor_consent_enums.h b/chrome/browser/ash/input_method/editor_consent_enums.h
index c032b231..f97c4f0 100644
--- a/chrome/browser/ash/input_method/editor_consent_enums.h
+++ b/chrome/browser/ash/input_method/editor_consent_enums.h
@@ -38,6 +38,9 @@
   kBlockedBySetting,
   // Blocked because the text is too long.
   kBlockedByTextLength,
+  // Blocked because the selection is invalid. E.g., selection causes the utf
+  // conversion to fail.
+  kBlockedByInvalidSelection,
   // Blocked because the focused text input residing in a url found in the
   // url denylist.
   kBlockedByUrl,
diff --git a/chrome/browser/ash/input_method/editor_context.cc b/chrome/browser/ash/input_method/editor_context.cc
index 56c4e44..057f160c 100644
--- a/chrome/browser/ash/input_method/editor_context.cc
+++ b/chrome/browser/ash/input_method/editor_context.cc
@@ -56,8 +56,9 @@
   observer_->OnContextUpdated();
 }
 
-void EditorContext::OnTextSelectionLengthChanged(size_t text_length) {
-  selected_text_length_ = text_length;
+void EditorContext::OnTextSelectionChanged(
+    const EditorTextSelection& text_selection) {
+  text_selection_ = text_selection;
   observer_->OnContextUpdated();
 }
 
@@ -88,7 +89,11 @@
 }
 
 size_t EditorContext::selected_text_length() {
-  return selected_text_length_;
+  return text_selection_.non_whitespace_selected_text_length;
+}
+
+bool EditorContext::is_selection_valid() {
+  return text_selection_.is_valid_selection;
 }
 
 }  // namespace ash::input_method
diff --git a/chrome/browser/ash/input_method/editor_context.h b/chrome/browser/ash/input_method/editor_context.h
index ceb683d..5ac4b79 100644
--- a/chrome/browser/ash/input_method/editor_context.h
+++ b/chrome/browser/ash/input_method/editor_context.h
@@ -18,6 +18,11 @@
 
 namespace ash::input_method {
 
+struct EditorTextSelection {
+  bool is_valid_selection = true;
+  size_t non_whitespace_selected_text_length = 0;
+};
+
 // Holds any "interesting" context for the Editor feature. This includes; the
 // currently active input method, size of the currently selected text, among
 // other tidbits.
@@ -50,8 +55,8 @@
       const TextInputMethod::InputContext& input_context,
       const TextFieldContextualInfo& text_field_contextual_info);
   void OnActivateIme(std::string_view engine_id);
+  void OnTextSelectionChanged(const EditorTextSelection& text_selection);
   void OnTabletModeUpdated(bool tablet_mode_enabled);
-  void OnTextSelectionLengthChanged(size_t new_length);
 
   // Getters
   std::string active_country_code();
@@ -61,6 +66,7 @@
   std::string_view app_id();
   GURL active_url();
   size_t selected_text_length();
+  bool is_selection_valid();
 
  private:
   // Not owned by this class
@@ -75,7 +81,7 @@
   std::string app_id_;
   GURL active_url_;
   bool tablet_mode_enabled_ = false;
-  size_t selected_text_length_ = 0;
+  EditorTextSelection text_selection_;
 };
 
 }  // namespace ash::input_method
diff --git a/chrome/browser/ash/input_method/editor_event_proxy.cc b/chrome/browser/ash/input_method/editor_event_proxy.cc
index b4b16db..4b67664 100644
--- a/chrome/browser/ash/input_method/editor_event_proxy.cc
+++ b/chrome/browser/ash/input_method/editor_event_proxy.cc
@@ -4,35 +4,19 @@
 
 #include "chrome/browser/ash/input_method/editor_event_proxy.h"
 
-#include "base/strings/utf_offset_string_conversions.h"
+#include "chromeos/ash/services/orca/public/mojom/orca_service.mojom.h"
 
 namespace ash::input_method {
 
-namespace {
-
-orca::mojom::ContextPtr CreateContext(const std::u16string& text,
-                                      gfx::Range range) {
-  std::vector<size_t> offsets = {range.start(), range.end()};
-  const std::string text_utf8 =
-      base::UTF16ToUTF8AndAdjustOffsets(text, &offsets);
-
-  auto context = orca::mojom::Context::New();
-  context->surrounding_text = orca::mojom::SurroundingText::New(
-      text_utf8, gfx::Range(offsets[0], offsets[1]));
-  return context;
-}
-
-}  // namespace
-
 EditorEventProxy::EditorEventProxy(
     mojo::PendingAssociatedRemote<orca::mojom::EditorEventSink> remote)
     : editor_event_sink_remote_(std::move(remote)) {}
 
 EditorEventProxy::~EditorEventProxy() = default;
 
-void EditorEventProxy::OnSurroundingTextChanged(const std::u16string& text,
-                                                gfx::Range range) {
-  editor_event_sink_remote_->OnContextUpdated(CreateContext(text, range));
+void EditorEventProxy::OnSurroundingTextChanged(
+    orca::mojom::ContextPtr context) {
+  editor_event_sink_remote_->OnContextUpdated(std::move(context));
 }
 
 }  // namespace ash::input_method
diff --git a/chrome/browser/ash/input_method/editor_event_proxy.h b/chrome/browser/ash/input_method/editor_event_proxy.h
index 9c29c350..481ba6e 100644
--- a/chrome/browser/ash/input_method/editor_event_proxy.h
+++ b/chrome/browser/ash/input_method/editor_event_proxy.h
@@ -10,7 +10,6 @@
 #include "chromeos/ash/services/orca/public/mojom/orca_service.mojom.h"
 #include "mojo/public/cpp/bindings/associated_remote.h"
 #include "mojo/public/cpp/bindings/pending_associated_remote.h"
-#include "ui/gfx/range/range.h"
 
 namespace ash::input_method {
 
@@ -20,7 +19,7 @@
       mojo::PendingAssociatedRemote<orca::mojom::EditorEventSink> remote);
   ~EditorEventProxy();
 
-  void OnSurroundingTextChanged(const std::u16string& text, gfx::Range range);
+  void OnSurroundingTextChanged(orca::mojom::ContextPtr context);
 
  private:
   mojo::AssociatedRemote<orca::mojom::EditorEventSink>
diff --git a/chrome/browser/ash/input_method/editor_mediator.cc b/chrome/browser/ash/input_method/editor_mediator.cc
index ff01fa1..4fa2088 100644
--- a/chrome/browser/ash/input_method/editor_mediator.cc
+++ b/chrome/browser/ash/input_method/editor_mediator.cc
@@ -12,6 +12,7 @@
 #include "base/check_op.h"
 #include "base/containers/contains.h"
 #include "base/containers/fixed_flat_set.h"
+#include "base/strings/utf_offset_string_conversions.h"
 #include "chrome/browser/ash/input_method/editor_consent_enums.h"
 #include "chrome/browser/ash/input_method/editor_geolocation_provider.h"
 #include "chrome/browser/ash/input_method/editor_metrics_enums.h"
@@ -38,6 +39,29 @@
 
 constexpr std::u16string_view kAnnouncementViewName = u"Orca";
 
+std::optional<orca::mojom::ContextPtr> CreateContext(const std::u16string& text,
+                                                     gfx::Range range) {
+  std::vector<size_t> offsets = {range.start(), range.end()};
+
+  const std::string text_utf8 =
+      base::UTF16ToUTF8AndAdjustOffsets(text, &offsets);
+
+  // In some rare cases such as crbug.com/425874277, the utf16 to utf8 conversion is not
+  // successful.
+  if (offsets[0] == std::u16string::npos ||
+      offsets[1] == std::u16string::npos) {
+    LOG(ERROR) << "The selection range is not valid";
+    return std::nullopt;
+  }
+
+  auto context = orca::mojom::Context::New();
+
+  context->surrounding_text = orca::mojom::SurroundingText::New(
+      text_utf8, gfx::Range(offsets[0], offsets[1]));
+
+  return context;
+}
+
 crosapi::mojom::MagicBoostController::TransitionAction
 ConvertToMagicBoostTransitionAction(EditorNoticeTransitionAction action) {
   switch (action) {
@@ -278,14 +302,24 @@
 
   mako_bubble_coordinator_.CacheContextCaretBounds();
 
-  size_t selected_length =
+  size_t non_whitespace_selected_text_length =
       chromeos::editor_helpers::NonWhitespaceAndSymbolsLength(
           surrounding_text_.text, surrounding_text_.selection_range);
-  editor_context_.OnTextSelectionLengthChanged(selected_length);
 
-  if (IsServiceConnected()) {
+  auto context =
+      CreateContext(surrounding_text_.text, surrounding_text_.selection_range);
+
+  EditorTextSelection text_selection = {
+      .is_valid_selection = (context != std::nullopt),
+      .non_whitespace_selected_text_length =
+          non_whitespace_selected_text_length,
+  };
+
+  editor_context_.OnTextSelectionChanged(text_selection);
+
+  if (IsServiceConnected() && context.has_value()) {
     service_connection_->editor_event_proxy()->OnSurroundingTextChanged(
-        surrounding_text_.text, surrounding_text_.selection_range);
+        std::move(context.value()));
   }
 }
 
diff --git a/chrome/browser/ash/input_method/editor_metrics_enums.h b/chrome/browser/ash/input_method/editor_metrics_enums.h
index d05e848..4da008b 100644
--- a/chrome/browser/ash/input_method/editor_metrics_enums.h
+++ b/chrome/browser/ash/input_method/editor_metrics_enums.h
@@ -156,7 +156,10 @@
   //  Increase by 1 when the feature is blocked because there is an associated
   //  policy that disables the feature.
   kBlockedByPolicy = 47,
-  kMaxValue = kBlockedByPolicy,
+  kBlockedByInvalidSelection = 48,
+  //  Increase by 1 when the feature is blocked because the current selection is
+  //  invalid, e.g. selection that causes the utf conversion to fail.
+  kMaxValue = kBlockedByInvalidSelection,
 };
 
 }  // namespace ash::input_method
diff --git a/chrome/browser/ash/input_method/editor_metrics_recorder.cc b/chrome/browser/ash/input_method/editor_metrics_recorder.cc
index 210c48f..97cce20 100644
--- a/chrome/browser/ash/input_method/editor_metrics_recorder.cc
+++ b/chrome/browser/ash/input_method/editor_metrics_recorder.cc
@@ -190,6 +190,8 @@
       return EditorStates::kBlockedByUnknownCapability;
     case EditorBlockedReason::kBlockedByUnsupportedCapability:
       return EditorStates::kBlockedByUnsupportedCapability;
+    case EditorBlockedReason::kBlockedByInvalidSelection:
+      return EditorStates::kBlockedByInvalidSelection;
   }
 }
 
diff --git a/chrome/browser/ash/input_method/editor_metrics_recorder_unittest.cc b/chrome/browser/ash/input_method/editor_metrics_recorder_unittest.cc
index 552d650..c470336 100644
--- a/chrome/browser/ash/input_method/editor_metrics_recorder_unittest.cc
+++ b/chrome/browser/ash/input_method/editor_metrics_recorder_unittest.cc
@@ -122,6 +122,7 @@
                              EditorStates::kBlockedByUnsupportedCapability,
                              EditorStates::kBlockedByUnknownCapability,
                              EditorStates::kBlockedByPolicy,
+                             EditorStates::kBlockedByInvalidSelection,
                          }));
 
 TEST_P(EditorStateMetrics, RecordsForWrite) {
diff --git a/chrome/browser/ash/input_method/editor_panel_manager_unittest.cc b/chrome/browser/ash/input_method/editor_panel_manager_unittest.cc
index 7a10a79..fa03d1b 100644
--- a/chrome/browser/ash/input_method/editor_panel_manager_unittest.cc
+++ b/chrome/browser/ash/input_method/editor_panel_manager_unittest.cc
@@ -257,11 +257,10 @@
   EditorPanelManagerDelegateForTesting editor_panel_manager_delegate(
       EditorOpportunityMode::kRewrite,
       chromeos::editor_menu::EditorConsentStatus::kApproved,
-      {
-          EditorBlockedReason::kBlockedByApp,
-          EditorBlockedReason::kBlockedByInputMethod,
-          EditorBlockedReason::kBlockedBySetting,
-      });
+      {EditorBlockedReason::kBlockedByApp,
+       EditorBlockedReason::kBlockedByInputMethod,
+       EditorBlockedReason::kBlockedBySetting,
+       EditorBlockedReason::kBlockedByInvalidSelection});
   EditorPanelManagerImpl manager(&editor_panel_manager_delegate);
   base::HistogramTester histogram_tester;
 
@@ -279,7 +278,10 @@
                                      EditorStates::kBlockedByInputMethod, 1);
   histogram_tester.ExpectBucketCount("InputMethod.Manta.Orca.States.Rewrite",
                                      EditorStates::kBlockedBySetting, 1);
-  histogram_tester.ExpectTotalCount("InputMethod.Manta.Orca.States.Rewrite", 5);
+  histogram_tester.ExpectBucketCount("InputMethod.Manta.Orca.States.Rewrite",
+                                     EditorStates::kBlockedByInvalidSelection,
+                                     1);
+  histogram_tester.ExpectTotalCount("InputMethod.Manta.Orca.States.Rewrite", 6);
 }
 
 TEST_F(EditorPanelManagerTest, LogMetricWhenPromoCardIsExplicitlyDismissed) {
diff --git a/chrome/browser/ash/input_method/editor_switch.cc b/chrome/browser/ash/input_method/editor_switch.cc
index c18d3ec..cb71c5c 100644
--- a/chrome/browser/ash/input_method/editor_switch.cc
+++ b/chrome/browser/ash/input_method/editor_switch.cc
@@ -380,6 +380,10 @@
     blocked_reasons.push_back(EditorBlockedReason::kBlockedBySetting);
   }
 
+  if (!context_->is_selection_valid()) {
+    blocked_reasons.push_back(EditorBlockedReason::kBlockedByInvalidSelection);
+  }
+
   if (!IsTriggerableFromTextLength(context_->selected_text_length())) {
     blocked_reasons.push_back(EditorBlockedReason::kBlockedByTextLength);
   }
@@ -440,6 +444,7 @@
                  chromeos::editor_menu::EditorEnterprisePolicy::kDisallowed) &&
          // user pref value
          profile_->GetPrefs()->GetBoolean(prefs::kOrcaEnabled) &&
+         context_->is_selection_valid() &&
          context_->selected_text_length() <= kTextLengthMaxLimit &&
          (!base::FeatureList::IsEnabled(features::kOrcaOnlyInEnglishLocales) ||
           IsSystemInEnglishLanguage());
diff --git a/chrome/browser/ash/input_method/editor_switch_unittest.cc b/chrome/browser/ash/input_method/editor_switch_unittest.cc
index cde0ab95..11632791 100644
--- a/chrome/browser/ash/input_method/editor_switch_unittest.cc
+++ b/chrome/browser/ash/input_method/editor_switch_unittest.cc
@@ -258,6 +258,7 @@
   net::NetworkChangeNotifier::ConnectionType network_status;
   bool user_pref;
   chromeos::editor_menu::EditorConsentStatus consent_status;
+  bool is_selection_valid;
   size_t num_chars_selected;
 
   EditorMode expected_editor_mode;
@@ -285,6 +286,7 @@
             .user_pref = true,
             .consent_status =
                 chromeos::editor_menu::EditorConsentStatus::kDeclined,
+            .is_selection_valid = true,
             .num_chars_selected = 0,
             .expected_editor_mode = EditorMode::kSoftBlocked,
             .expected_editor_opportunity_mode = EditorOpportunityMode::kWrite,
@@ -305,6 +307,7 @@
             .user_pref = true,
             .consent_status =
                 chromeos::editor_menu::EditorConsentStatus::kApproved,
+            .is_selection_valid = true,
             .num_chars_selected = 0,
             .expected_editor_mode = EditorMode::kSoftBlocked,
             .expected_editor_opportunity_mode =
@@ -325,6 +328,7 @@
          .user_pref = true,
          .consent_status =
              chromeos::editor_menu::EditorConsentStatus::kApproved,
+         .is_selection_valid = true,
          .num_chars_selected = 0,
          .expected_editor_mode = EditorMode::kWrite,
          .expected_editor_opportunity_mode = EditorOpportunityMode::kWrite,
@@ -342,6 +346,7 @@
          .user_pref = true,
          .consent_status =
              chromeos::editor_menu::EditorConsentStatus::kApproved,
+         .is_selection_valid = true,
          .num_chars_selected = 0,
          .expected_editor_mode = EditorMode::kWrite,
          .expected_editor_opportunity_mode = EditorOpportunityMode::kWrite,
@@ -360,6 +365,7 @@
          .user_pref = true,
          .consent_status =
              chromeos::editor_menu::EditorConsentStatus::kApproved,
+         .is_selection_valid = true,
          .num_chars_selected = 0,
          .expected_editor_mode = EditorMode::kWrite,
          .expected_editor_opportunity_mode = EditorOpportunityMode::kWrite,
@@ -378,6 +384,7 @@
          .user_pref = true,
          .consent_status =
              chromeos::editor_menu::EditorConsentStatus::kApproved,
+         .is_selection_valid = true,
          .num_chars_selected = 0,
          .expected_editor_mode = EditorMode::kSoftBlocked,
          .expected_editor_opportunity_mode = EditorOpportunityMode::kWrite,
@@ -396,6 +403,7 @@
          .user_pref = true,
          .consent_status =
              chromeos::editor_menu::EditorConsentStatus::kApproved,
+         .is_selection_valid = true,
          .num_chars_selected = 0,
          .expected_editor_mode = EditorMode::kWrite,
          .expected_editor_opportunity_mode = EditorOpportunityMode::kWrite,
@@ -413,6 +421,7 @@
          .user_pref = false,
          .consent_status =
              chromeos::editor_menu::EditorConsentStatus::kApproved,
+         .is_selection_valid = true,
          .num_chars_selected = 0,
          .expected_editor_mode = EditorMode::kSoftBlocked,
          .expected_editor_opportunity_mode = EditorOpportunityMode::kWrite,
@@ -430,6 +439,7 @@
          .user_pref = true,
          .consent_status =
              chromeos::editor_menu::EditorConsentStatus::kApproved,
+         .is_selection_valid = true,
          .num_chars_selected = 0,
          .expected_editor_mode = EditorMode::kSoftBlocked,
          .expected_editor_opportunity_mode = EditorOpportunityMode::kWrite,
@@ -448,6 +458,7 @@
          .user_pref = true,
          .consent_status =
              chromeos::editor_menu::EditorConsentStatus::kApproved,
+         .is_selection_valid = true,
          .num_chars_selected = 0,
          .expected_editor_mode = EditorMode::kSoftBlocked,
          .expected_editor_opportunity_mode = EditorOpportunityMode::kWrite,
@@ -466,11 +477,31 @@
          .user_pref = true,
          .consent_status =
              chromeos::editor_menu::EditorConsentStatus::kApproved,
+         .is_selection_valid = true,
          .num_chars_selected = 10001,
          .expected_editor_mode = EditorMode::kSoftBlocked,
          .expected_editor_opportunity_mode = EditorOpportunityMode::kRewrite,
          .expected_blocked_reasons =
              {EditorBlockedReason::kBlockedByTextLength}},
+        {.test_name = "DoNotTriggerFeatureWhenTheSelectionIsInvalid",
+         .additional_enabled_flags = {},
+         .email = "testuser@gmail.com",
+         .active_engine_id = "xkb:us::eng",
+         .locale = "en-us",
+         .url = kAllowedTestUrl,
+         .input_type = ui::TEXT_INPUT_TYPE_TEXT,
+         .app_type = chromeos::AppType::BROWSER,
+         .is_in_tablet_mode = false,
+         .network_status = net::NetworkChangeNotifier::CONNECTION_UNKNOWN,
+         .user_pref = true,
+         .consent_status =
+             chromeos::editor_menu::EditorConsentStatus::kApproved,
+         .is_selection_valid = false,
+         .num_chars_selected = 100,
+         .expected_editor_mode = EditorMode::kSoftBlocked,
+         .expected_editor_opportunity_mode = EditorOpportunityMode::kRewrite,
+         .expected_blocked_reasons =
+             {EditorBlockedReason::kBlockedByInvalidSelection}},
         {.test_name =
              "TriggersConsentIfSettingToggleIsOnAndUserHasNotGivenConsent",
          .additional_enabled_flags = {},
@@ -484,6 +515,7 @@
          .network_status = net::NetworkChangeNotifier::CONNECTION_UNKNOWN,
          .user_pref = true,
          .consent_status = chromeos::editor_menu::EditorConsentStatus::kPending,
+         .is_selection_valid = true,
          .num_chars_selected = 100,
          .expected_editor_mode = EditorMode::kConsentNeeded,
          .expected_editor_opportunity_mode = EditorOpportunityMode::kRewrite,
@@ -501,6 +533,7 @@
          .user_pref = true,
          .consent_status =
              chromeos::editor_menu::EditorConsentStatus::kApproved,
+         .is_selection_valid = true,
          .num_chars_selected = 0,
          .expected_editor_mode = EditorMode::kWrite,
          .expected_editor_opportunity_mode = EditorOpportunityMode::kWrite,
@@ -518,6 +551,7 @@
          .user_pref = true,
          .consent_status =
              chromeos::editor_menu::EditorConsentStatus::kApproved,
+         .is_selection_valid = true,
          .num_chars_selected = 100,
          .expected_editor_mode = EditorMode::kRewrite,
          .expected_editor_opportunity_mode = EditorOpportunityMode::kRewrite,
@@ -536,6 +570,7 @@
          .user_pref = true,
          .consent_status =
              chromeos::editor_menu::EditorConsentStatus::kApproved,
+         .is_selection_valid = true,
          .num_chars_selected = 100,
          .expected_editor_mode = EditorMode::kRewrite,
          .expected_editor_opportunity_mode = EditorOpportunityMode::kRewrite,
@@ -554,6 +589,7 @@
          .user_pref = true,
          .consent_status =
              chromeos::editor_menu::EditorConsentStatus::kApproved,
+         .is_selection_valid = true,
          .num_chars_selected = 100,
          .expected_editor_mode = EditorMode::kRewrite,
          .expected_editor_opportunity_mode = EditorOpportunityMode::kRewrite,
@@ -572,10 +608,12 @@
          .user_pref = true,
          .consent_status =
              chromeos::editor_menu::EditorConsentStatus::kApproved,
+         .is_selection_valid = true,
          .num_chars_selected = 100,
          .expected_editor_mode = EditorMode::kSoftBlocked,
          .expected_editor_opportunity_mode = EditorOpportunityMode::kRewrite,
          .expected_blocked_reasons = {}},
+
     }),
     [](const testing::TestParamInfo<EditorSwitchTriggerTest::ParamType>& info) {
       return info.param.test_name;
@@ -622,7 +660,8 @@
       TextInputMethod::InputContext(test_case.input_type),
       CreateFakeTextFieldContextualInfo(test_case.app_type, test_case.url,
                                         test_case.app_id));
-  context.OnTextSelectionLengthChanged(test_case.num_chars_selected);
+  context.OnTextSelectionChanged(EditorTextSelection(
+      test_case.is_selection_valid, test_case.num_chars_selected));
 
   ASSERT_TRUE(editor_switch.IsAllowedForUse());
   EXPECT_EQ(editor_switch.GetEditorMode(), test_case.expected_editor_mode);
@@ -709,7 +748,8 @@
       TextInputMethod::InputContext(ui::TEXT_INPUT_TYPE_TEXT),
       CreateFakeTextFieldContextualInfo(chromeos::AppType::BROWSER, test_url,
                                         ""));
-  context.OnTextSelectionLengthChanged(10);
+
+  context.OnTextSelectionChanged(EditorTextSelection(true, 100));
 
   EXPECT_TRUE(editor_switch.IsAllowedForUse());
   EXPECT_EQ(editor_switch.GetEditorMode(), expected_mode);
@@ -831,7 +871,7 @@
       TextInputMethod::InputContext(ui::TEXT_INPUT_TYPE_TEXT),
       CreateFakeTextFieldContextualInfo(chromeos::AppType::BROWSER,
                                         kAllowedTestUrl, ""));
-  context_.OnTextSelectionLengthChanged(0);
+  context_.OnTextSelectionChanged(EditorTextSelection(true, 0));
 
   EXPECT_TRUE(editor_switch.IsAllowedForUse());
   EXPECT_EQ(editor_switch.GetEditorMode(), expected_mode);
@@ -925,7 +965,7 @@
       TextInputMethod::InputContext(ui::TEXT_INPUT_TYPE_TEXT),
       CreateFakeTextFieldContextualInfo(chromeos::AppType::BROWSER,
                                         kAllowedTestUrl, ""));
-  context_.OnTextSelectionLengthChanged(0);
+  context_.OnTextSelectionChanged(EditorTextSelection(true, 0));
 
   EXPECT_TRUE(editor_switch.IsAllowedForUse());
   EXPECT_EQ(editor_switch.GetEditorMode(), expected_mode);
diff --git a/chrome/browser/ash/kerberos/kerberos_credentials_manager_unittest.cc b/chrome/browser/ash/kerberos/kerberos_credentials_manager_unittest.cc
index 3425e0e..b88d0947 100644
--- a/chrome/browser/ash/kerberos/kerberos_credentials_manager_unittest.cc
+++ b/chrome/browser/ash/kerberos/kerberos_credentials_manager_unittest.cc
@@ -21,11 +21,11 @@
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/notifications/notification_display_service_tester.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/kerberos/kerberos_client.h"
 #include "chromeos/ash/components/dbus/kerberos/kerberos_service.pb.h"
+#include "components/prefs/testing_pref_service.h"
 #include "components/user_manager/scoped_user_manager.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/test/browser_task_environment.h"
@@ -145,8 +145,7 @@
   using Account = kerberos::Account;
   using Accounts = std::vector<Account>;
 
-  KerberosCredentialsManagerTest()
-      : local_state_(TestingBrowserProcess::GetGlobal()) {
+  KerberosCredentialsManagerTest() {
     SessionManagerClient::InitializeFakeInMemory();
     KerberosClient::InitializeFake();
     client_test_interface()->SetTaskDelay(base::TimeDelta());
@@ -167,8 +166,8 @@
     display_service_ =
         std::make_unique<NotificationDisplayServiceTester>(profile_.get());
 
-    mgr_ = std::make_unique<KerberosCredentialsManager>(local_state_.Get(),
-                                                        profile_.get());
+    mgr_ = std::make_unique<KerberosCredentialsManager>(
+        TestingBrowserProcess::GetGlobal()->local_state(), profile_.get());
 
     mgr_->AddObserver(&observer_);
   }
@@ -189,7 +188,7 @@
   }
 
   void SetPref(const char* name, base::Value value) {
-    local_state_.Get()->SetManagedPref(
+    TestingBrowserProcess::GetGlobal()->GetTestingLocalState()->SetManagedPref(
         name, std::make_unique<base::Value>(std::move(value)));
   }
 
@@ -357,7 +356,6 @@
 
   content::BrowserTaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
-  ScopedTestingLocalState local_state_;
   user_manager::TypedScopedUserManager<FakeChromeUserManager> user_manager_{
       std::make_unique<FakeChromeUserManager>()};
   std::unique_ptr<TestingProfile> profile_;
@@ -690,7 +688,8 @@
 TEST_F(KerberosCredentialsManagerTest,
        RemoveAccountRemoveLastAccountDeletesKerberosFiles) {
   auto files_handler = std::make_unique<MockKerberosFilesHandler>(
-      *local_state_.Get(), mgr_->GetGetKerberosFilesCallbackForTesting());
+      *TestingBrowserProcess::GetGlobal()->local_state(),
+      mgr_->GetGetKerberosFilesCallbackForTesting());
   EXPECT_CALL(*files_handler, DeleteFiles());
   mgr_->SetKerberosFilesHandlerForTesting(std::move(files_handler));
   AddAccountAndAuthenticate(kPrincipal, kUnmanaged, kerberos::ERROR_NONE,
diff --git a/chrome/browser/ash/login/app_mode/test/kiosk_enterprise_input_api_browsertest.cc b/chrome/browser/ash/login/app_mode/test/kiosk_enterprise_input_api_browsertest.cc
index a5d223e..f5d60fd 100644
--- a/chrome/browser/ash/login/app_mode/test/kiosk_enterprise_input_api_browsertest.cc
+++ b/chrome/browser/ash/login/app_mode/test/kiosk_enterprise_input_api_browsertest.cc
@@ -10,23 +10,28 @@
 
 #include "base/check.h"
 #include "base/check_deref.h"
+#include "base/functional/bind.h"
 #include "base/memory/scoped_refptr.h"
-#include "base/strings/strcat.h"
-#include "chrome/browser/ash/app_mode/fake_cws.h"
-#include "chrome/browser/ash/app_mode/test/kiosk_mixin.h"
-#include "chrome/browser/ash/app_mode/test/kiosk_test_utils.h"
-#include "chrome/browser/ash/login/test/device_state_mixin.h"
-#include "chrome/browser/ash/login/test/scoped_policy_update.h"
+#include "base/path_service.h"
+#include "chrome/browser/ash/login/app_mode/test/web_kiosk_base_test.h"
+#include "chrome/browser/ash/policy/test_support/embedded_policy_test_server_mixin.h"
 #include "chrome/browser/policy/extension_force_install_mixin.h"
+#include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/test/base/mixin_based_in_process_browser_test.h"
+#include "chrome/common/chrome_paths.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "chromeos/ash/components/dbus/session_manager/fake_session_manager_client.h"
+#include "components/policy/core/common/cloud/cloud_policy_constants.h"
 #include "components/policy/core/common/cloud/test/policy_builder.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/browser_test_utils.h"
-#include "content/public/test/test_navigation_observer.h"
-#include "extensions/test/extension_test_message_listener.h"
+#include "device_management_backend.pb.h"
+#include "extensions/common/extension_id.h"
+#include "net/http/http_status_code.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/ime/ash/input_method_manager.h"
@@ -42,35 +47,49 @@
 constexpr std::string_view kBrPorMethodId = "xkb:br::por";
 constexpr std::string_view kFrFraMethodId = "xkb:fr::fra";
 
-// Corresponds to the Chrome extension under:
-// //chrome/test/data/chromeos/app_mode/apps_and_extensions/input_extension/src
-//
-// This extension exercises the `chrome.enterprise.kioskInput` API.
-constexpr std::string_view kExtensionId = "elhlgakmbkdkoajdlnfkhjbpgmbpjdig";
+constexpr std::string_view kCompanionExtensionId =
+    "pogfhljmaechjalhkendaaoldheklnmk";
 
-// Serves the input extension in `fake_cws` and configures `user_policy`` to
-// force install it.
-void ConfigureInputExtension(FakeCWS& fake_cws,
-                             ScopedUserPolicyUpdate& user_policy) {
-  constexpr std::string_view kVersion = "1.0.0";
-  auto crx_file = base::StrCat({kExtensionId, "-", kVersion, ".crx"});
+std::unique_ptr<net::test_server::HttpResponse> ServeSimpleHtmlPage(
+    const net::test_server::HttpRequest& request) {
+  auto response = std::make_unique<net::test_server::BasicHttpResponse>();
+  response->set_code(net::HTTP_OK);
+  response->set_content_type("text/html");
+  response->set_content(
+      "<!DOCTYPE html>"
+      "<html lang=\"en\">"
+      "<head><title>Test Page</title></head>"
+      "<body>A simple kiosk web page.</body>"
+      "</html>");
+  return response;
+}
 
-  fake_cws.SetUpdateCrx(kExtensionId, crx_file, kVersion);
-  user_policy.policy_payload()
-      ->mutable_extensioninstallforcelist()
-      ->mutable_value()
-      ->add_entries(kExtensionId);
+void SetUpDeviceLocalAccountPolicy(
+    const std::string& account_id,
+    policy::UserPolicyBuilder& user_policy_builder) {
+  enterprise_management::PolicyData& policy_data =
+      user_policy_builder.policy_data();
+  policy_data.set_public_key_version(1);
+  policy_data.set_policy_type(
+      policy::dm_protocol::kChromePublicAccountPolicyType);
+  policy_data.set_username(account_id);
+  policy_data.set_settings_entity_id(account_id);
+  user_policy_builder.SetDefaultSigningKey();
+
+  auto& session_manager = CHECK_DEREF(FakeSessionManagerClient::Get());
+  session_manager.set_device_local_account_policy(
+      std::string(account_id), user_policy_builder.GetBlob());
 }
 
 std::string CurrentInputMethod() {
-  auto& manager = CHECK_DEREF(InputMethodManager::Get());
+  InputMethodManager& manager = CHECK_DEREF(InputMethodManager::Get());
   InputMethodManager::State& state =
       CHECK_DEREF(manager.GetActiveIMEState().get());
   return state.GetCurrentInputMethod().id();
 }
 
 std::string ToExtensionBasedInputMethod(std::string_view method) {
-  auto& manager = CHECK_DEREF(InputMethodManager::Get());
+  InputMethodManager& manager = CHECK_DEREF(InputMethodManager::Get());
   std::vector<std::string> extension_based_input_methods{std::string(method)};
   CHECK(manager.GetMigratedInputMethodIDs(&extension_based_input_methods));
   return extension_based_input_methods[0];
@@ -81,7 +100,7 @@
 }
 
 bool EnableInputMethods(const std::vector<std::string_view>& methods) {
-  auto& manager = CHECK_DEREF(InputMethodManager::Get());
+  InputMethodManager& manager = CHECK_DEREF(InputMethodManager::Get());
   InputMethodManager::State& state =
       CHECK_DEREF(manager.GetActiveIMEState().get());
   std::vector<std::string> extension_based_input_methods(methods.begin(),
@@ -93,13 +112,12 @@
 content::EvalJsResult SendMessageToExtension(content::WebContents& web_contents,
                                              std::string message,
                                              std::string data) {
-  // `chrome.runtime` only gets defined once `web_contents` finishes loading.
-  content::TestNavigationObserver(&web_contents).WaitForNavigationFinished();
   constexpr std::string_view kScript = R"(
     chrome.runtime.sendMessage($1, { message: $2, data: $3 })
   )";
   return content::EvalJs(
-      &web_contents, content::JsReplace(kScript, kExtensionId, message, data));
+      &web_contents,
+      content::JsReplace(kScript, kCompanionExtensionId, message, data));
 }
 
 content::EvalJsResult IsExtensionApiAvailable(
@@ -122,15 +140,9 @@
          std::string(input_method) + ".";
 }
 
-// The app used to configure `KioskMixin`.
-KioskMixin::DefaultServerWebAppOption AppInConfig() {
-  return KioskMixin::SimpleWebAppOption();
-}
-
 }  // namespace
 
-class KioskEnterpriseInputApiBrowserTest
-    : public MixinBasedInProcessBrowserTest {
+class KioskEnterpriseInputApiBrowserTest : public WebKioskBaseTest {
  public:
   KioskEnterpriseInputApiBrowserTest() = default;
   KioskEnterpriseInputApiBrowserTest(
@@ -140,23 +152,21 @@
 
   ~KioskEnterpriseInputApiBrowserTest() override = default;
 
+ protected:
   void SetUpInProcessBrowserTestFixture() override {
-    MixinBasedInProcessBrowserTest::SetUpInProcessBrowserTestFixture();
-    ConfigureInputExtension(
-        kiosk_.fake_cws(),
-        *kiosk_.device_state_mixin().RequestDeviceLocalAccountPolicyUpdate(
-            AppInConfig().account_id));
+    WebKioskBaseTest::SetUpInProcessBrowserTestFixture();
+    SetUpDeviceLocalAccountPolicy(app_account_id(),
+                                  device_local_acount_policy_builder_);
   }
 
   void SetUpOnMainThread() override {
-    MixinBasedInProcessBrowserTest::SetUpOnMainThread();
-    ExtensionTestMessageListener extension_ready("ready");
-    extension_ready.set_extension_id(std::string(kExtensionId));
-    ASSERT_TRUE(kiosk::test::WaitKioskLaunched());
-    ASSERT_TRUE(extension_ready.WaitUntilSatisfied());
+    InitializeWebAppServer();
+    WebKioskBaseTest::SetUpOnMainThread();
+    InitializeRegularOnlineKiosk();
+    ForceInstallAndWaitExtensionReady();
   }
 
-  content::WebContents& GetAppWebContents() {
+  content::WebContents& app_web_contents() {
     SelectFirstBrowser();
     BrowserView* browser_view =
         BrowserView::GetBrowserViewForBrowser(browser());
@@ -164,16 +174,55 @@
   }
 
  private:
-  KioskMixin kiosk_{&mixin_host_,
-                    /*cached_configuration=*/
-                    {/*name=*/{},
-                     KioskMixin::AutoLaunchAccount{AppInConfig().account_id},
-                     {AppInConfig()}}};
+  void InitializeWebAppServer() {
+    web_app_server_.RegisterRequestHandler(
+        base::BindRepeating(&ServeSimpleHtmlPage));
+    ASSERT_TRUE(web_app_server_handle_ =
+                    web_app_server_.StartAndReturnHandle());
+    SetAppInstallUrl(web_app_server_.base_url());
+  }
+
+  void ForceInstallAndWaitExtensionReady() {
+    constexpr std::string_view kCompanionExtensionPath =
+        "extensions/api_test/enterprise_kiosk_input/";
+    constexpr std::string_view kCompanionExtensionPemPath =
+        "extensions/api_test/enterprise_kiosk_input.pem";
+    base::FilePath test_data_dir =
+        base::PathService::CheckedGet(chrome::DIR_TEST_DATA);
+
+    extension_force_install_mixin_.InitWithEmbeddedPolicyMixin(
+        &app_profile(), &policy_test_server_mixin_,
+        &device_local_acount_policy_builder_,
+        /*account_id=*/app_account_id(),
+        /*policy_type=*/policy::dm_protocol::kChromePublicAccountPolicyType);
+
+    extensions::ExtensionId extension_id;
+    bool did_install = extension_force_install_mixin_.ForceInstallFromSourceDir(
+        test_data_dir.AppendASCII(kCompanionExtensionPath),
+        test_data_dir.AppendASCII(kCompanionExtensionPemPath),
+        ExtensionForceInstallMixin::WaitMode::kReadyMessageReceived,
+        &extension_id);
+    ASSERT_TRUE(did_install);
+    ASSERT_EQ(kCompanionExtensionId, extension_id);
+  }
+
+  std::string app_account_id() { return web_app_server_.base_url().spec(); }
+
+  Profile& app_profile() {
+    return CHECK_DEREF(ProfileManager::GetPrimaryUserProfile());
+  }
+
+  net::test_server::EmbeddedTestServer web_app_server_;
+  net::test_server::EmbeddedTestServerHandle web_app_server_handle_;
+
+  policy::UserPolicyBuilder device_local_acount_policy_builder_;
+  EmbeddedPolicyTestServerMixin policy_test_server_mixin_{&mixin_host_};
+  ExtensionForceInstallMixin extension_force_install_mixin_{&mixin_host_};
 };
 
 IN_PROC_BROWSER_TEST_F(KioskEnterpriseInputApiBrowserTest,
                        CompanionExtensionCanAccessApi) {
-  ASSERT_EQ(true, IsExtensionApiAvailable(GetAppWebContents()));
+  ASSERT_EQ(true, IsExtensionApiAvailable(app_web_contents()));
 }
 
 IN_PROC_BROWSER_TEST_F(KioskEnterpriseInputApiBrowserTest,
@@ -193,7 +242,7 @@
   EXPECT_THAT(CurrentInputMethod(), HasMethodId(kUsEngMethodId));
 
   EXPECT_EQ(true,
-            SetInputMethodViaExtension(GetAppWebContents(), enabled_method_id));
+            SetInputMethodViaExtension(app_web_contents(), enabled_method_id));
   EXPECT_THAT(CurrentInputMethod(), HasMethodId(enabled_method_id));
 }
 
@@ -204,9 +253,8 @@
   EXPECT_THAT(CurrentInputMethod(), HasMethodId(kUsEngMethodId));
 
   std::string_view disabled_method_id = kBrPorMethodId;
-  EXPECT_EQ(
-      CouldNotChangeInputError(disabled_method_id),
-      SetInputMethodViaExtension(GetAppWebContents(), disabled_method_id));
+  EXPECT_EQ(CouldNotChangeInputError(disabled_method_id),
+            SetInputMethodViaExtension(app_web_contents(), disabled_method_id));
   EXPECT_THAT(CurrentInputMethod(), HasMethodId(kUsEngMethodId));
 }
 
diff --git a/chrome/browser/ash/login/demo_mode/demo_login_controller_unittest.cc b/chrome/browser/ash/login/demo_mode/demo_login_controller_unittest.cc
index 52b4c1e6..6e198f6 100644
--- a/chrome/browser/ash/login/demo_mode/demo_login_controller_unittest.cc
+++ b/chrome/browser/ash/login/demo_mode/demo_login_controller_unittest.cc
@@ -25,7 +25,6 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part.h"
 #include "chrome/browser/ui/ash/login/mock_login_display_host.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/dbus/dbus_thread_manager.h"
 #include "chromeos/ash/components/dbus/session_manager/fake_session_manager_client.h"
@@ -41,6 +40,7 @@
 #include "components/policy/core/common/cloud/mock_cloud_policy_manager.h"
 #include "components/policy/core/common/cloud/mock_cloud_policy_service.h"
 #include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
+#include "components/prefs/pref_service.h"
 #include "components/session_manager/core/session_manager.h"
 #include "components/user_manager/fake_user_manager_delegate.h"
 #include "components/user_manager/scoped_user_manager.h"
@@ -282,7 +282,6 @@
       policy_controller_;
 
   testing::NiceMock<ash::MockLoginDisplayHost> mock_login_display_host_;
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
   system::FakeStatisticsProvider statistics_provider_;
 
   // Required for `user_manager::UserList`:
@@ -294,7 +293,7 @@
   user_manager::ScopedUserManager user_manager_{
       std::make_unique<user_manager::UserManagerImpl>(
           std::make_unique<user_manager::FakeUserManagerDelegate>(),
-          TestingBrowserProcess::GetGlobal()->GetTestingLocalState())};
+          TestingBrowserProcess::GetGlobal()->local_state())};
   session_manager::SessionManager session_manager_;
   std::unique_ptr<ExistingUserController> existing_user_controller_;
 
diff --git a/chrome/browser/ash/login/demo_mode/demo_mode_dimensions_unittest.cc b/chrome/browser/ash/login/demo_mode/demo_mode_dimensions_unittest.cc
index 3ac784e..3a6bfa0 100644
--- a/chrome/browser/ash/login/demo_mode/demo_mode_dimensions_unittest.cc
+++ b/chrome/browser/ash/login/demo_mode/demo_mode_dimensions_unittest.cc
@@ -3,17 +3,18 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/ash/login/demo_mode/demo_mode_dimensions.h"
+
 #include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
 #include "base/metrics/field_trial.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/ash/login/demo_mode/demo_mode_test_utils.h"
 #include "chrome/browser/ash/login/demo_mode/demo_session.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/install_attributes/stub_install_attributes.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "components/policy/proto/device_management_backend.pb.h"
+#include "components/prefs/pref_service.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -22,31 +23,33 @@
 class DemoModeDimensionsTest : public testing::Test {
  public:
   DemoModeDimensionsTest()
-      : local_state_(TestingBrowserProcess::GetGlobal()),
-        scoped_install_attributes_(StubInstallAttributes::CreateDemoMode()) {}
+      : scoped_install_attributes_(StubInstallAttributes::CreateDemoMode()) {}
 
   ~DemoModeDimensionsTest() override = default;
 
  protected:
-  ScopedTestingLocalState local_state_;
   ScopedStubInstallAttributes scoped_install_attributes_;
   base::test::ScopedFeatureList feature_list_;
 };
 
 TEST_F(DemoModeDimensionsTest, Country) {
-  local_state_.Get()->SetString(prefs::kDemoModeCountry, "DE");
+  TestingBrowserProcess::GetGlobal()->local_state()->SetString(
+      prefs::kDemoModeCountry, "DE");
   ASSERT_EQ(ash::demo_mode::Country(), "DE");
-  local_state_.Get()->SetString(prefs::kDemoModeCountry, "ca");
+  TestingBrowserProcess::GetGlobal()->local_state()->SetString(
+      prefs::kDemoModeCountry, "ca");
   ASSERT_EQ(ash::demo_mode::Country(), "CA");
 }
 
 TEST_F(DemoModeDimensionsTest, RetailerName) {
-  local_state_.Get()->SetString(prefs::kDemoModeRetailerId, "retailer");
+  TestingBrowserProcess::GetGlobal()->local_state()->SetString(
+      prefs::kDemoModeRetailerId, "retailer");
   ASSERT_EQ(ash::demo_mode::RetailerName(), "retailer");
 }
 
 TEST_F(DemoModeDimensionsTest, StoreNumber) {
-  local_state_.Get()->SetString(prefs::kDemoModeStoreId, "1234");
+  TestingBrowserProcess::GetGlobal()->local_state()->SetString(
+      prefs::kDemoModeStoreId, "1234");
   ASSERT_EQ(ash::demo_mode::StoreNumber(), "1234");
 }
 
@@ -68,9 +71,12 @@
       {chromeos::features::kCloudGamingDevice,
        ash::features::kFeatureManagementFeatureAwareDeviceDemoMode},
       {});
-  local_state_.Get()->SetString(prefs::kDemoModeCountry, "CA");
-  local_state_.Get()->SetString(prefs::kDemoModeRetailerId, "retailer");
-  local_state_.Get()->SetString(prefs::kDemoModeStoreId, "1234");
+  TestingBrowserProcess::GetGlobal()->local_state()->SetString(
+      prefs::kDemoModeCountry, "CA");
+  TestingBrowserProcess::GetGlobal()->local_state()->SetString(
+      prefs::kDemoModeRetailerId, "retailer");
+  TestingBrowserProcess::GetGlobal()->local_state()->SetString(
+      prefs::kDemoModeStoreId, "1234");
 
   enterprise_management::DemoModeDimensions expected;
   expected.set_country("CA");
diff --git a/chrome/browser/ash/login/demo_mode/demo_session_unittest.cc b/chrome/browser/ash/login/demo_mode/demo_session_unittest.cc
index eb191ebc1..b524476 100644
--- a/chrome/browser/ash/login/demo_mode/demo_session_unittest.cc
+++ b/chrome/browser/ash/login/demo_mode/demo_session_unittest.cc
@@ -32,7 +32,6 @@
 #include "chrome/browser/ui/ash/wallpaper/test_wallpaper_controller.h"
 #include "chrome/browser/ui/ash/wallpaper/wallpaper_controller_client_impl.h"
 #include "chrome/test/base/browser_process_platform_part_test_api_chromeos.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
diff --git a/chrome/browser/ash/login/demo_mode/demo_setup_controller_unittest.cc b/chrome/browser/ash/login/demo_mode/demo_setup_controller_unittest.cc
index 62d1dc8..55877bc 100644
--- a/chrome/browser/ash/login/demo_mode/demo_setup_controller_unittest.cc
+++ b/chrome/browser/ash/login/demo_mode/demo_setup_controller_unittest.cc
@@ -27,7 +27,6 @@
 #include "chrome/browser/ash/settings/device_settings_service.h"
 #include "chrome/browser/browser_process_platform_part.h"
 #include "chrome/browser/component_updater/cros_component_installer_chromeos.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/cryptohome/system_salt_getter.h"
 #include "chromeos/ash/components/dbus/dbus_thread_manager.h"
@@ -36,6 +35,7 @@
 #include "chromeos/ash/components/system/fake_statistics_provider.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
+#include "components/prefs/pref_service.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -116,8 +116,7 @@
 
 class DemoSetupControllerTest : public testing::Test {
  protected:
-  DemoSetupControllerTest()
-      : testing_local_state_(TestingBrowserProcess::GetGlobal()) {}
+  DemoSetupControllerTest() = default;
 
   DemoSetupControllerTest(const DemoSetupControllerTest&) = delete;
   DemoSetupControllerTest& operator=(const DemoSetupControllerTest&) = delete;
@@ -155,7 +154,6 @@
   base::HistogramTester histogram_tester_;
 
  private:
-  ScopedTestingLocalState testing_local_state_;
   ScopedStubInstallAttributes test_install_attributes_;
   system::ScopedFakeStatisticsProvider statistics_provider_;
 };
diff --git a/chrome/browser/ash/login/enrollment/enrollment_screen_unittest.cc b/chrome/browser/ash/login/enrollment/enrollment_screen_unittest.cc
index f37adfa3..57aa5ba 100644
--- a/chrome/browser/ash/login/enrollment/enrollment_screen_unittest.cc
+++ b/chrome/browser/ash/login/enrollment/enrollment_screen_unittest.cc
@@ -37,13 +37,13 @@
 #include "chrome/browser/ui/ash/login/fake_login_display_host.h"
 #include "chrome/browser/ui/webui/ash/login/online_login_utils.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/install_attributes/stub_install_attributes.h"
 #include "chromeos/ash/components/network/network_handler_test_helper.h"
 #include "chromeos/ash/components/network/portal_detector/mock_network_portal_detector.h"
 #include "chromeos/ash/components/system/fake_statistics_provider.h"
 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
+#include "components/prefs/pref_service.h"
 #include "components/prefs/testing_pref_service.h"
 #include "google_apis/gaia/gaia_id.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -327,7 +327,7 @@
   }
 
   TestingPrefServiceSimple& local_state() {
-    return *scoped_testing_local_state_.Get();
+    return *TestingBrowserProcess::GetGlobal()->GetTestingLocalState();
   }
 
   MockEnrollmentLauncher& mock_enrollment_launcher() {
@@ -377,10 +377,6 @@
   // Used by `enrollment_screen_`.
   ScopedStubInstallAttributes test_install_attributes_;
 
-  // Used by `EnrollmentRequisitionManager` and `StartupUtils`.
-  ScopedTestingLocalState scoped_testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
-
   // Used by `EnrollmentRequisitionManager`.
   system::ScopedFakeStatisticsProvider fake_statistics_provider_;
 
diff --git a/chrome/browser/ash/login/enterprise_user_session_metrics_unittest.cc b/chrome/browser/ash/login/enterprise_user_session_metrics_unittest.cc
index c923ef2c..bd48cb56 100644
--- a/chrome/browser/ash/login/enterprise_user_session_metrics_unittest.cc
+++ b/chrome/browser/ash/login/enterprise_user_session_metrics_unittest.cc
@@ -9,7 +9,6 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "base/time/time.h"
 #include "chrome/browser/ash/login/demo_mode/demo_session.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/install_attributes/stub_install_attributes.h"
 #include "chromeos/ash/components/login/auth/public/user_context.h"
@@ -33,8 +32,7 @@
 class EnterpriseUserSessionMetricsTest : public testing::Test {
  public:
   EnterpriseUserSessionMetricsTest()
-      : local_state_(TestingBrowserProcess::GetGlobal()),
-        install_attributes_(std::make_unique<ScopedStubInstallAttributes>(
+      : install_attributes_(std::make_unique<ScopedStubInstallAttributes>(
             StubInstallAttributes::CreateCloudManaged("test-domain",
                                                       "FAKE_DEVICE_ID"))) {}
 
@@ -47,7 +45,6 @@
 
  protected:
   content::BrowserTaskEnvironment task_environment_;
-  ScopedTestingLocalState local_state_;
   std::unique_ptr<ScopedStubInstallAttributes> install_attributes_;
 };
 
diff --git a/chrome/browser/ash/login/existing_user_controller_auto_login_unittest.cc b/chrome/browser/ash/login/existing_user_controller_auto_login_unittest.cc
index 25a61dc1..4bb7954b 100644
--- a/chrome/browser/ash/login/existing_user_controller_auto_login_unittest.cc
+++ b/chrome/browser/ash/login/existing_user_controller_auto_login_unittest.cc
@@ -12,7 +12,6 @@
 #include "chrome/browser/ash/settings/device_settings_service.h"
 #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/browser/ui/ash/login/mock_login_display_host.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/dbus/session_manager/fake_session_manager_client.h"
 #include "chromeos/ash/components/login/auth/auth_events_recorder.h"
@@ -44,8 +43,7 @@
 class ExistingUserControllerAutoLoginTest : public ::testing::Test {
  protected:
   ExistingUserControllerAutoLoginTest()
-      : local_state_(TestingBrowserProcess::GetGlobal()),
-        fake_user_manager_(std::make_unique<FakeChromeUserManager>()) {
+      : fake_user_manager_(std::make_unique<FakeChromeUserManager>()) {
     auth_events_recorder_ = ash::AuthEventsRecorder::CreateForTesting();
   }
 
@@ -137,7 +135,6 @@
  private:
   std::unique_ptr<MockLoginDisplayHost> mock_login_display_host_;
   content::BrowserTaskEnvironment task_environment_;
-  ScopedTestingLocalState local_state_;
 
   // Required by ExistingUserController:
   FakeSessionManagerClient fake_session_manager_client_;
diff --git a/chrome/browser/ash/login/existing_user_controller_base_test.cc b/chrome/browser/ash/login/existing_user_controller_base_test.cc
index bf84955..efdd6f9e 100644
--- a/chrome/browser/ash/login/existing_user_controller_base_test.cc
+++ b/chrome/browser/ash/login/existing_user_controller_base_test.cc
@@ -11,8 +11,7 @@
 namespace ash {
 
 ExistingUserControllerBaseTest::ExistingUserControllerBaseTest()
-    : scoped_local_state_(TestingBrowserProcess::GetGlobal()),
-      fake_user_manager_(std::make_unique<FakeChromeUserManager>()),
+    : fake_user_manager_(std::make_unique<FakeChromeUserManager>()),
       auth_events_recorder_(ash::AuthEventsRecorder::CreateForTesting()) {}
 
 ExistingUserControllerBaseTest::~ExistingUserControllerBaseTest() = default;
diff --git a/chrome/browser/ash/login/existing_user_controller_base_test.h b/chrome/browser/ash/login/existing_user_controller_base_test.h
index 3a82644..c720c47f 100644
--- a/chrome/browser/ash/login/existing_user_controller_base_test.h
+++ b/chrome/browser/ash/login/existing_user_controller_base_test.h
@@ -8,7 +8,6 @@
 #include <memory>
 
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "components/account_id/account_id.h"
 #include "components/user_manager/scoped_user_manager.h"
 #include "content/public/test/browser_task_environment.h"
@@ -56,7 +55,6 @@
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
 
  private:
-  ScopedTestingLocalState scoped_local_state_;
   user_manager::TypedScopedUserManager<ash::FakeChromeUserManager>
       fake_user_manager_;
   std::unique_ptr<AuthEventsRecorder> auth_events_recorder_;
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/session_context_unittest.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/session_context_unittest.cc
index 4af1265..1cc5c89 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/session_context_unittest.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/session_context_unittest.cc
@@ -10,7 +10,6 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/ash/login/oobe_quick_start/oobe_quick_start_pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/test/browser_task_environment.h"
@@ -31,7 +30,7 @@
 
 class SessionContextTest : public testing::Test {
  public:
-  SessionContextTest() : local_state_(TestingBrowserProcess::GetGlobal()) {}
+  SessionContextTest() = default;
   SessionContextTest(const SessionContextTest&) = delete;
   SessionContextTest& operator=(const SessionContextTest&) = delete;
 
@@ -40,7 +39,9 @@
     session_context_->FillOrResetSession();
   }
 
-  PrefService* GetLocalState() { return local_state_.Get(); }
+  PrefService* GetLocalState() {
+    return TestingBrowserProcess::GetGlobal()->local_state();
+  }
 
   std::string GetSecondarySharedSecretString() {
     SessionContext::SharedSecret secondary_shared_secret =
@@ -53,7 +54,6 @@
  protected:
   base::test::SingleThreadTaskEnvironment task_environment_;
   std::unique_ptr<SessionContext> session_context_;
-  ScopedTestingLocalState local_state_;
 };
 
 TEST_F(SessionContextTest, GetPrepareForUpdateInfo) {
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc
index 3b30de9..7df6b2b6 100644
--- a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_impl_unittest.cc
@@ -25,7 +25,6 @@
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker.h"
 #include "chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_connection_broker_factory.h"
 #include "chrome/browser/ash/nearby/fake_quick_start_connectivity_service.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/nearby/common/connections_manager/fake_nearby_connection.h"
 #include "chromeos/ash/components/nearby/common/connections_manager/fake_nearby_connections_manager.h"
@@ -395,8 +394,6 @@
   FakeConnectionLifecycleListener connection_lifecycle_listener_;
   raw_ptr<FakeConnection::Factory> connection_factory_ = nullptr;
   base::HistogramTester histogram_tester_;
-  ScopedTestingLocalState scoped_local_state_{
-      TestingBrowserProcess::GetGlobal()};
 
   std::unique_ptr<FakeQuickStartDecoder> fake_quick_start_decoder_ =
       std::make_unique<FakeQuickStartDecoder>();
diff --git a/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller_unittest.cc b/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller_unittest.cc
index fa729ef..c17bf0e 100644
--- a/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller_unittest.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/target_device_bootstrap_controller_unittest.cc
@@ -26,7 +26,6 @@
 #include "chrome/browser/ash/login/oobe_quick_start/oobe_quick_start_pref_names.h"
 #include "chrome/browser/ash/login/oobe_quick_start/second_device_auth_broker.h"
 #include "chrome/browser/ash/nearby/fake_quick_start_connectivity_service.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/quick_start/quick_start_metrics.h"
 #include "chromeos/ash/components/quick_start/types.h"
@@ -115,8 +114,7 @@
 
   static constexpr char kSourceDeviceId[] = "fake-source-device-id";
 
-  TargetDeviceBootstrapControllerTest()
-      : local_state_(TestingBrowserProcess::GetGlobal()) {}
+  TargetDeviceBootstrapControllerTest() = default;
 
   TargetDeviceBootstrapControllerTest(TargetDeviceBootstrapControllerTest&) =
       delete;
@@ -174,7 +172,9 @@
     bootstrap_controller_->OnNotifySourceOfUpdateResponse(ack_successful);
   }
 
-  PrefService* GetLocalState() { return local_state_.Get(); }
+  PrefService* GetLocalState() {
+    return TestingBrowserProcess::GetGlobal()->local_state();
+  }
 
   void ExpectQuickStartConnectivityServiceCleanupCalled() {
     EXPECT_TRUE(
@@ -212,7 +212,6 @@
   raw_ptr<FakeAccessibilityManagerWrapper, DanglingUntriaged>
       fake_accessibility_manager_ = nullptr;
   std::unique_ptr<TargetDeviceBootstrapController> bootstrap_controller_;
-  ScopedTestingLocalState local_state_;
   base::HistogramTester histogram_tester_;
   const Base64UrlString kFakeChallengeBytes_ =
       *Base64UrlTranscode(Base64String(kFakeChallengeBytesBase64));
diff --git a/chrome/browser/ash/login/reporting/login_logout_reporter_unittest.cc b/chrome/browser/ash/login/reporting/login_logout_reporter_unittest.cc
index adf4de1..be4737a5 100644
--- a/chrome/browser/ash/login/reporting/login_logout_reporter_unittest.cc
+++ b/chrome/browser/ash/login/reporting/login_logout_reporter_unittest.cc
@@ -12,7 +12,6 @@
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/ash/policy/reporting/user_event_reporter_helper_testing.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/login/auth/public/auth_failure.h"
@@ -168,16 +167,13 @@
 class LoginLogoutReporterTest
     : public ::testing::TestWithParam<LoginLogoutReporterTestCase> {
  protected:
-  LoginLogoutReporterTest()
-      : local_state_(TestingBrowserProcess::GetGlobal()) {}
+  LoginLogoutReporterTest() = default;
 
   void SetUp() override { test_helper_.Init(); }
 
   void TearDown() override { test_helper_.Shutdown(); }
 
   LoginLogoutTestHelper test_helper_;
-
-  ScopedTestingLocalState local_state_;
 };
 
 TEST_F(LoginLogoutReporterTest, ReportAffiliatedLogin) {
@@ -346,16 +342,13 @@
 
 class LoginFailureReporterTest : public ::testing::TestWithParam<AuthFailure> {
  protected:
-  LoginFailureReporterTest()
-      : local_state_(TestingBrowserProcess::GetGlobal()) {}
+  LoginFailureReporterTest() = default;
 
   void SetUp() override { test_helper_.Init(); }
 
   void TearDown() override { test_helper_.Shutdown(); }
 
   LoginLogoutTestHelper test_helper_;
-
-  ScopedTestingLocalState local_state_;
 };
 
 TEST_F(LoginFailureReporterTest, ReportAffiliatedLoginFailure_OwnerRequired) {
diff --git a/chrome/browser/ash/login/saml/password_sync_token_login_checker_unittest.cc b/chrome/browser/ash/login/saml/password_sync_token_login_checker_unittest.cc
index 30a3247..66405e11 100644
--- a/chrome/browser/ash/login/saml/password_sync_token_login_checker_unittest.cc
+++ b/chrome/browser/ash/login/saml/password_sync_token_login_checker_unittest.cc
@@ -11,7 +11,6 @@
 #include "base/time/time.h"
 #include "chrome/browser/ash/login/saml/password_sync_token_checkers_collection.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "components/user_manager/scoped_user_manager.h"
 #include "components/user_manager/user_names.h"
@@ -47,15 +46,13 @@
       base::test::TaskEnvironment::MainThreadType::UI,
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
 
-  ScopedTestingLocalState scoped_local_state_;
   std::unique_ptr<net::BackoffEntry> sync_token_retry_backoff_;
   user_manager::TypedScopedUserManager<ash::FakeChromeUserManager>
       fake_user_manager_;
   std::unique_ptr<PasswordSyncTokenLoginChecker> checker_;
 };
 
-PasswordSyncTokenLoginCheckerTest::PasswordSyncTokenLoginCheckerTest()
-    : scoped_local_state_(TestingBrowserProcess::GetGlobal()) {
+PasswordSyncTokenLoginCheckerTest::PasswordSyncTokenLoginCheckerTest() {
   fake_user_manager_.Reset(std::make_unique<ash::FakeChromeUserManager>());
 
   sync_token_retry_backoff_ = std::make_unique<net::BackoffEntry>(
diff --git a/chrome/browser/ash/login/screens/update_required_screen_unittest.cc b/chrome/browser/ash/login/screens/update_required_screen_unittest.cc
index e4385516..868dc1b 100644
--- a/chrome/browser/ash/login/screens/update_required_screen_unittest.cc
+++ b/chrome/browser/ash/login/screens/update_required_screen_unittest.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/ash/login/wizard_context.h"
 #include "chrome/browser/ash/settings/scoped_testing_cros_settings.h"
 #include "chrome/browser/ui/webui/ash/login/fake_update_required_screen_handler.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/dbus/update_engine/fake_update_engine_client.h"
 #include "chromeos/ash/components/dbus/update_engine/update_engine_client.h"
@@ -39,8 +38,7 @@
 
 class UpdateRequiredScreenUnitTest : public testing::Test {
  public:
-  UpdateRequiredScreenUnitTest()
-      : local_state_(TestingBrowserProcess::GetGlobal()) {}
+  UpdateRequiredScreenUnitTest() = default;
 
   UpdateRequiredScreenUnitTest(const UpdateRequiredScreenUnitTest&) = delete;
   UpdateRequiredScreenUnitTest& operator=(const UpdateRequiredScreenUnitTest&) =
@@ -114,7 +112,6 @@
  private:
   // Test versions of core browser infrastructure.
   content::BrowserTaskEnvironment task_environment_;
-  ScopedTestingLocalState local_state_;
   ScopedTestingCrosSettings scoped_testing_cros_settings_;
   // This is used for `GetEnterpriseDisplayDomain`.
   ScopedStubInstallAttributes test_install_attributes_;
diff --git a/chrome/browser/ash/login/screens/update_screen_unittest.cc b/chrome/browser/ash/login/screens/update_screen_unittest.cc
index 8149893..acb86c6c 100644
--- a/chrome/browser/ash/login/screens/update_screen_unittest.cc
+++ b/chrome/browser/ash/login/screens/update_screen_unittest.cc
@@ -15,7 +15,6 @@
 #include "chrome/browser/ash/login/screens/mock_update_screen.h"
 #include "chrome/browser/ash/login/startup_utils.h"
 #include "chrome/browser/ash/login/wizard_context.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/dbus/update_engine/fake_update_engine_client.h"
 #include "chromeos/ash/components/dbus/update_engine/update_engine_client.h"
@@ -34,7 +33,7 @@
 
 class UpdateScreenUnitTest : public testing::Test {
  public:
-  UpdateScreenUnitTest() : local_state_(TestingBrowserProcess::GetGlobal()) {}
+  UpdateScreenUnitTest() = default;
 
   UpdateScreenUnitTest(const UpdateScreenUnitTest&) = delete;
   UpdateScreenUnitTest& operator=(const UpdateScreenUnitTest&) = delete;
@@ -130,7 +129,6 @@
   // Test versions of core browser infrastructure.
   base::test::SingleThreadTaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
-  ScopedTestingLocalState local_state_;
   std::unique_ptr<NetworkHandlerTestHelper> network_handler_test_helper_;
 };
 
diff --git a/chrome/browser/ash/login/session/session_length_limiter_unittest.cc b/chrome/browser/ash/login/session/session_length_limiter_unittest.cc
index 79222f2c..1fdcecf95 100644
--- a/chrome/browser/ash/login/session/session_length_limiter_unittest.cc
+++ b/chrome/browser/ash/login/session/session_length_limiter_unittest.cc
@@ -19,7 +19,6 @@
 #include "base/values.h"
 #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/demo_mode/utils/demo_session_utils.h"
 #include "chromeos/ash/components/install_attributes/stub_install_attributes.h"
@@ -120,12 +119,9 @@
 
  private:
   TestingPrefServiceSimple& local_state() {
-    return *scoped_testing_local_state_.Get();
+    return *TestingBrowserProcess::GetGlobal()->GetTestingLocalState();
   }
 
-  ScopedTestingLocalState scoped_testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
-
   bool user_activity_seen_;
 
   raw_ptr<MockSessionLengthLimiterDelegate, DanglingUntriaged>
diff --git a/chrome/browser/ash/login/signin/offline_signin_limiter_unittest.cc b/chrome/browser/ash/login/signin/offline_signin_limiter_unittest.cc
index ff2f4f47..90826ee 100644
--- a/chrome/browser/ash/login/signin/offline_signin_limiter_unittest.cc
+++ b/chrome/browser/ash/login/signin/offline_signin_limiter_unittest.cc
@@ -19,7 +19,6 @@
 #include "chrome/browser/ash/login/signin/offline_signin_limiter_factory.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/pref_registry/pref_registry_syncable.h"
@@ -90,7 +89,6 @@
   std::unique_ptr<OfflineSigninLimiter> limiter_;
   base::test::ScopedPowerMonitorTestSource test_power_monitor_source_;
 
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
   std::unique_ptr<user_manager::KnownUser> known_user_;
   std::optional<session_manager::SessionManager> session_manager_;
 };
@@ -139,7 +137,8 @@
   session_manager_.emplace();
   fake_user_manager_.Reset(std::make_unique<ash::FakeChromeUserManager>());
   profile_ = std::make_unique<TestingProfile>();
-  known_user_ = std::make_unique<user_manager::KnownUser>(local_state_.Get());
+  known_user_ = std::make_unique<user_manager::KnownUser>(
+      TestingBrowserProcess::GetGlobal()->local_state());
 }
 
 void OfflineSigninLimiterTest::TearDown() {
diff --git a/chrome/browser/ash/login/smart_lock/smart_lock_service_unittest.cc b/chrome/browser/ash/login/smart_lock/smart_lock_service_unittest.cc
index 79e180bb..d864225 100644
--- a/chrome/browser/ash/login/smart_lock/smart_lock_service_unittest.cc
+++ b/chrome/browser/ash/login/smart_lock/smart_lock_service_unittest.cc
@@ -27,7 +27,6 @@
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
 #include "chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_dialog.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/dbus_thread_manager.h"
@@ -322,11 +321,6 @@
   // Must outlive TestingProfiles.
   content::BrowserTaskEnvironment task_environment_;
 
-  // PrefService which contains the browser process' local storage. It should be
-  // destructed after TestingProfile.
-  ScopedTestingLocalState scoped_testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
-
   user_manager::TypedScopedUserManager<ash::FakeChromeUserManager>
       fake_user_manager_;
   std::unique_ptr<TestingProfile> profile_;
diff --git a/chrome/browser/ash/login/startup_utils_unittest.cc b/chrome/browser/ash/login/startup_utils_unittest.cc
index 330daab..9fb82d62 100644
--- a/chrome/browser/ash/login/startup_utils_unittest.cc
+++ b/chrome/browser/ash/login/startup_utils_unittest.cc
@@ -9,7 +9,6 @@
 #include "base/test/task_environment.h"
 #include "chrome/browser/ash/policy/enrollment/enrollment_test_helper.h"
 #include "chrome/browser/prefs/browser_prefs.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/system/fake_statistics_provider.h"
 #include "components/prefs/testing_pref_service.h"
@@ -26,9 +25,6 @@
   base::test::TaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
 
-  ScopedTestingLocalState scoped_testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
-
   ash::system::ScopedFakeStatisticsProvider statistics_provider_;
   base::test::ScopedCommandLine command_line_;
   policy::test::EnrollmentTestHelper enrollment_test_helper_{
diff --git a/chrome/browser/ash/login/user_online_signin_notifier_unittest.cc b/chrome/browser/ash/login/user_online_signin_notifier_unittest.cc
index 3ca6f521..9cde52b6 100644
--- a/chrome/browser/ash/login/user_online_signin_notifier_unittest.cc
+++ b/chrome/browser/ash/login/user_online_signin_notifier_unittest.cc
@@ -13,7 +13,6 @@
 #include "chrome/browser/ash/login/user_online_signin_notifier.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "components/user_manager/known_user.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/browser/ash/login/users/avatar/user_image_manager_impl_unittest.cc b/chrome/browser/ash/login/users/avatar/user_image_manager_impl_unittest.cc
index 2b5f51f..69c10e6 100644
--- a/chrome/browser/ash/login/users/avatar/user_image_manager_impl_unittest.cc
+++ b/chrome/browser/ash/login/users/avatar/user_image_manager_impl_unittest.cc
@@ -15,7 +15,6 @@
 #include "chrome/browser/ash/login/users/avatar/user_image_manager_test_util.h"
 #include "chrome/browser/ash/login/users/default_user_image/default_user_images.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
@@ -100,7 +99,6 @@
   }
 
  private:
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
   content::BrowserTaskEnvironment task_environment_;
   TestingProfileManager profile_manager_{TestingBrowserProcess::GetGlobal()};
   user_manager::TypedScopedUserManager<FakeChromeUserManager>
diff --git a/chrome/browser/ash/login/users/multi_user_sign_in_policy_controller_unittest.cc b/chrome/browser/ash/login/users/multi_user_sign_in_policy_controller_unittest.cc
index ceb1b3f7..6747c6b3 100644
--- a/chrome/browser/ash/login/users/multi_user_sign_in_policy_controller_unittest.cc
+++ b/chrome/browser/ash/login/users/multi_user_sign_in_policy_controller_unittest.cc
@@ -29,7 +29,6 @@
 #include "chrome/browser/policy/networking/policy_cert_service_factory.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
@@ -199,13 +198,12 @@
 
   TestingProfile* profile(int index) { return user_profiles_[index]; }
 
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
   content::BrowserTaskEnvironment task_environment_;
   TypedScopedUserManager<ash::FakeChromeUserManager> fake_user_manager_{
       std::make_unique<ash::FakeChromeUserManager>()};
   std::unique_ptr<user_manager::MultiUserSignInPolicyController> controller_{
       std::make_unique<user_manager::MultiUserSignInPolicyController>(
-          local_state_.Get(),
+          TestingBrowserProcess::GetGlobal()->local_state(),
           fake_user_manager_.Get())};
   std::unique_ptr<TestingProfileManager> profile_manager_;
 
diff --git a/chrome/browser/ash/login/users/profile_user_manager_controller_unittest.cc b/chrome/browser/ash/login/users/profile_user_manager_controller_unittest.cc
index c53b5d20..7ecc0577 100644
--- a/chrome/browser/ash/login/users/profile_user_manager_controller_unittest.cc
+++ b/chrome/browser/ash/login/users/profile_user_manager_controller_unittest.cc
@@ -7,7 +7,6 @@
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
@@ -43,10 +42,9 @@
  private:
   content::BrowserTaskEnvironment task_environment_;
   ScopedCrosSettingsTestHelper settings_helper_;
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
   user_manager::TypedScopedUserManager<user_manager::FakeUserManager>
-      user_manager_{
-          std::make_unique<user_manager::FakeUserManager>(local_state_.Get())};
+      user_manager_{std::make_unique<user_manager::FakeUserManager>(
+          TestingBrowserProcess::GetGlobal()->local_state())};
   // To follow the destruction order in the production, declare controller's
   // pointer first.
   std::unique_ptr<ProfileUserManagerController> controller_;
diff --git a/chrome/browser/ash/login/users/user_manager_unittest.cc b/chrome/browser/ash/login/users/user_manager_unittest.cc
index 7df86cda..c8b3afb 100644
--- a/chrome/browser/ash/login/users/user_manager_unittest.cc
+++ b/chrome/browser/ash/login/users/user_manager_unittest.cc
@@ -34,7 +34,6 @@
 #include "chrome/browser/profiles/profile_test_util.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/fake_profile_manager.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/cryptohome/cryptohome_parameters.h"
 #include "chromeos/ash/components/dbus/concierge/concierge_client.h"
@@ -46,6 +45,7 @@
 #include "components/account_id/account_id.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
+#include "components/prefs/testing_pref_service.h"
 #include "components/user_manager/known_user.h"
 #include "components/user_manager/scoped_user_manager.h"
 #include "components/user_manager/test_helper.h"
@@ -147,10 +147,6 @@
     // Instantiate ProfileHelper.
     ash::ProfileHelper::Get();
 
-    // Register an in-memory local settings instance.
-    local_state_ = std::make_unique<ScopedTestingLocalState>(
-        TestingBrowserProcess::GetGlobal());
-
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     TestingBrowserProcess::GetGlobal()->SetProfileManager(
         std::make_unique<FakeProfileManager>(temp_dir_.GetPath()));
@@ -168,9 +164,6 @@
 
     TestingBrowserProcess::GetGlobal()->SetProfileManager(nullptr);
 
-    // Unregister the in-memory local settings instance.
-    local_state_.reset();
-
     base::RunLoop().RunUntilIdle();
     ConciergeClient::Shutdown();
 
@@ -203,7 +196,8 @@
       user_manager_.reset();
     }
     user_manager_ = std::make_unique<user_manager::UserManagerImpl>(
-        std::make_unique<UserManagerDelegateImpl>(), local_state_->Get());
+        std::make_unique<UserManagerDelegateImpl>(),
+        TestingBrowserProcess::GetGlobal()->local_state());
     policy_user_manager_controller_ =
         std::make_unique<PolicyUserManagerController>(
             user_manager_.get(), ash::CrosSettings::Get(),
@@ -264,22 +258,24 @@
 
     SetKioskAccountPrefs(policy::DeviceLocalAccount::EphemeralMode::kDisable,
                          /* account_id= */ email, /* type=kArcKiosk */ 2);
-    local_state_->Get()->Set(
+    TestingBrowserProcess::GetGlobal()->local_state()->Set(
         user_manager::prefs::kDeviceLocalAccountsWithSavedData,
         base::Value(base::Value::List().Append(email)));
-    user_manager::KnownUser(local_state_->Get())
+    user_manager::KnownUser(TestingBrowserProcess::GetGlobal()->local_state())
         .SaveKnownUser(
             AccountId::FromUserEmailGaiaId(email, GaiaId("fake_gaia_id")));
   }
 
   size_t GetArcKioskAccountsWithSavedDataCount() {
-    return local_state_->Get()
+    return TestingBrowserProcess::GetGlobal()
+        ->local_state()
         ->GetList(user_manager::prefs::kDeviceLocalAccountsWithSavedData)
         .size();
   }
 
   size_t GetKnownUsersCount() {
-    return user_manager::KnownUser(local_state_->Get())
+    return user_manager::KnownUser(
+               TestingBrowserProcess::GetGlobal()->local_state())
         .GetKnownAccountIds()
         .size();
   }
@@ -306,8 +302,6 @@
   system::ScopedFakeStatisticsProvider fake_statistics_provider_;
 
   ScopedCrosSettingsTestHelper settings_helper_;
-  // local_state_ should be destructed after ProfileManager.
-  std::unique_ptr<ScopedTestingLocalState> local_state_;
 
   std::unique_ptr<user_manager::UserManagerImpl> user_manager_;
   std::unique_ptr<PolicyUserManagerController> policy_user_manager_controller_;
@@ -491,7 +485,8 @@
       kAccountId0, user_manager::TestHelper::GetFakeUsernameHash(kAccountId0));
   ResetUserManager();
 
-  EXPECT_EQ(1U, local_state_->Get()
+  EXPECT_EQ(1U, TestingBrowserProcess::GetGlobal()
+                    ->local_state()
                     ->GetList(user_manager::prefs::kRegularUsersPref)
                     .size());
   EXPECT_EQ(2U, user_manager::UserManager::Get()->GetPersistedUsers().size());
@@ -501,7 +496,8 @@
       /* owner= */ kOwnerAccountId.GetUserEmail());
   RetrieveTrustedDevicePolicies();
 
-  EXPECT_TRUE(local_state_->Get()
+  EXPECT_TRUE(TestingBrowserProcess::GetGlobal()
+                  ->local_state()
                   ->GetList(user_manager::prefs::kRegularUsersPref)
                   .empty());
   EXPECT_EQ(1U, user_manager::UserManager::Get()->GetPersistedUsers().size());
@@ -678,7 +674,8 @@
   user_manager::UserManager::Get()->UserLoggedIn(
       kOwnerAccountId,
       user_manager::TestHelper::GetFakeUsernameHash(kOwnerAccountId));
-  user_manager::KnownUser known_user(local_state_->Get());
+  user_manager::KnownUser known_user(
+      TestingBrowserProcess::GetGlobal()->local_state());
   EXPECT_EQ(user_manager::ProfileRequiresPolicy::kUnknown,
             known_user.GetProfileRequiresPolicy(kOwnerAccountId));
   ResetUserManager();
diff --git a/chrome/browser/ash/login/version_updater/version_updater_unittest.cc b/chrome/browser/ash/login/version_updater/version_updater_unittest.cc
index dcf6fde..00ab2e8 100644
--- a/chrome/browser/ash/login/version_updater/version_updater_unittest.cc
+++ b/chrome/browser/ash/login/version_updater/version_updater_unittest.cc
@@ -15,7 +15,6 @@
 #include "chrome/browser/ash/login/startup_utils.h"
 #include "chrome/browser/ash/login/version_updater/mock_version_updater_delegate.h"
 #include "chrome/browser/ash/login/version_updater/update_time_estimator.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/dbus/update_engine/fake_update_engine_client.h"
 #include "chromeos/ash/components/dbus/update_engine/update_engine_client.h"
@@ -51,7 +50,7 @@
 
 class VersionUpdaterUnitTest : public testing::Test {
  public:
-  VersionUpdaterUnitTest() : local_state_(TestingBrowserProcess::GetGlobal()) {}
+  VersionUpdaterUnitTest() = default;
 
   VersionUpdaterUnitTest(const VersionUpdaterUnitTest&) = delete;
   VersionUpdaterUnitTest& operator=(const VersionUpdaterUnitTest&) = delete;
@@ -152,8 +151,6 @@
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
 
  private:
-  ScopedTestingLocalState local_state_;
-
   int checks_count_ = 0;
 };
 
diff --git a/chrome/browser/ash/net/network_pref_state_observer_unittest.cc b/chrome/browser/ash/net/network_pref_state_observer_unittest.cc
index 7809007..bfd9326 100644
--- a/chrome/browser/ash/net/network_pref_state_observer_unittest.cc
+++ b/chrome/browser/ash/net/network_pref_state_observer_unittest.cc
@@ -13,7 +13,6 @@
 #include "base/values.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "chromeos/ash/components/network/network_handler.h"
diff --git a/chrome/browser/ash/net/system_proxy_manager_unittest.cc b/chrome/browser/ash/net/system_proxy_manager_unittest.cc
index 5b7ca89..42bb100f 100644
--- a/chrome/browser/ash/net/system_proxy_manager_unittest.cc
+++ b/chrome/browser/ash/net/system_proxy_manager_unittest.cc
@@ -12,7 +12,6 @@
 #include "chrome/browser/ash/settings/scoped_testing_cros_settings.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/system_proxy/system_proxy_client.h"
@@ -107,7 +106,7 @@
 // with RunLoop::Run() with explicit RunLoop::QuitClosure().
 class SystemProxyManagerTest : public testing::Test {
  public:
-  SystemProxyManagerTest() : local_state_(TestingBrowserProcess::GetGlobal()) {}
+  SystemProxyManagerTest() = default;
   ~SystemProxyManagerTest() override = default;
 
   // testing::Test
@@ -118,12 +117,13 @@
 
     profile_ = std::make_unique<TestingProfile>();
     SystemProxyClient::InitializeFake();
-    system_proxy_manager_ =
-        std::make_unique<SystemProxyManager>(local_state_.Get());
+    system_proxy_manager_ = std::make_unique<SystemProxyManager>(
+        TestingBrowserProcess::GetGlobal()->local_state());
     // Listen for pref changes for the primary profile.
     system_proxy_manager_->StartObservingPrimaryProfilePrefs(profile_.get());
-    NetworkHandler::Get()->InitializePrefServices(profile_->GetPrefs(),
-                                                  local_state_.Get());
+    NetworkHandler::Get()->InitializePrefServices(
+        profile_->GetPrefs(),
+        TestingBrowserProcess::GetGlobal()->local_state());
   }
 
   void TearDown() override {
@@ -149,7 +149,6 @@
 
   content::BrowserTaskEnvironment task_environment_;
   std::unique_ptr<NetworkHandlerTestHelper> network_handler_test_helper_;
-  ScopedTestingLocalState local_state_;
   std::unique_ptr<SystemProxyManager> system_proxy_manager_;
   std::unique_ptr<TestingProfile> profile_;
 };
@@ -163,7 +162,8 @@
   EXPECT_EQ(++expected_set_auth_details_call_count,
             client_test_interface()->GetSetAuthenticationDetailsCallCount());
 
-  local_state_.Get()->SetBoolean(prefs::kKerberosEnabled, true);
+  TestingBrowserProcess::GetGlobal()->local_state()->SetBoolean(
+      prefs::kKerberosEnabled, true);
   EXPECT_EQ(++expected_set_auth_details_call_count,
             client_test_interface()->GetSetAuthenticationDetailsCallCount());
 
@@ -194,7 +194,8 @@
   EXPECT_TRUE(request.kerberos_enabled());
 
   // Disable kerberos.
-  local_state_.Get()->SetBoolean(prefs::kKerberosEnabled, false);
+  TestingBrowserProcess::GetGlobal()->local_state()->SetBoolean(
+      prefs::kKerberosEnabled, false);
   request = client_test_interface()->GetLastAuthenticationDetailsRequest();
   EXPECT_FALSE(request.kerberos_enabled());
 }
diff --git a/chrome/browser/ash/notifications/multi_capture_notifications_unittest.cc b/chrome/browser/ash/notifications/multi_capture_notifications_unittest.cc
index ad64ac9..36b931c4 100644
--- a/chrome/browser/ash/notifications/multi_capture_notifications_unittest.cc
+++ b/chrome/browser/ash/notifications/multi_capture_notifications_unittest.cc
@@ -45,7 +45,7 @@
 namespace {
 constexpr base::TimeDelta kMinimumNotificationPresenceTime = base::Seconds(6);
 constexpr char kUserMail[] = "testingprofile@chromium.org";
-constexpr GaiaId::Literal kFakeGaia("fakegaia");
+constexpr GaiaId::Literal kFakeGaia("fakegaia123");
 }  // namespace
 
 namespace ash {
diff --git a/chrome/browser/ash/notifications/update_required_notification_unittest.cc b/chrome/browser/ash/notifications/update_required_notification_unittest.cc
index 30ba9386..488a26f 100644
--- a/chrome/browser/ash/notifications/update_required_notification_unittest.cc
+++ b/chrome/browser/ash/notifications/update_required_notification_unittest.cc
@@ -20,7 +20,6 @@
 #include "chrome/browser/notifications/notification_display_service_tester.h"
 #include "chrome/browser/notifications/system_notification_helper.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/dbus/shill/shill_service_client.h"
 #include "chromeos/ash/components/dbus/update_engine/fake_update_engine_client.h"
@@ -104,7 +103,6 @@
 
  private:
   bool user_managed_ = true;
-  ScopedTestingLocalState local_state_;
   ScopedTestingCrosSettings scoped_testing_cros_settings_;
   std::unique_ptr<NotificationDisplayServiceTester> notification_service_;
   ScopedStubInstallAttributes scoped_stub_install_attributes_;
@@ -115,8 +113,7 @@
   std::unique_ptr<NetworkHandlerTestHelper> network_handler_test_helper_;
 };
 
-UpdateRequiredNotificationTest::UpdateRequiredNotificationTest()
-    : local_state_(TestingBrowserProcess::GetGlobal()) {
+UpdateRequiredNotificationTest::UpdateRequiredNotificationTest() {
   ON_CALL(*this, IsDeviceEnterpriseManaged)
       .WillByDefault(testing::Return(true));
   ON_CALL(*this, IsUserLoggedIn).WillByDefault(testing::Return(true));
diff --git a/chrome/browser/ash/ownership/owner_key_loader_unittest.cc b/chrome/browser/ash/ownership/owner_key_loader_unittest.cc
index fba2eae..28f0590 100644
--- a/chrome/browser/ash/ownership/owner_key_loader_unittest.cc
+++ b/chrome/browser/ash/ownership/owner_key_loader_unittest.cc
@@ -21,7 +21,6 @@
 #include "chrome/browser/ash/ownership/ownership_histograms.h"
 #include "chrome/browser/ash/settings/device_settings_service.h"
 #include "chrome/browser/net/fake_nss_service.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/policy/device_policy/device_policy_builder.h"
@@ -113,8 +112,6 @@
   }
 
   content::BrowserTaskEnvironment task_environment_;
-  ScopedTestingLocalState scoped_local_state_{
-      TestingBrowserProcess::GetGlobal()};
 
   std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager_;
   raw_ptr<ash::FakeChromeUserManager> user_manager_ = nullptr;
diff --git a/chrome/browser/ash/ownership/owner_settings_service_ash_unittest.cc b/chrome/browser/ash/ownership/owner_settings_service_ash_unittest.cc
index 42dfd434e..d2d19ca5 100644
--- a/chrome/browser/ash/ownership/owner_settings_service_ash_unittest.cc
+++ b/chrome/browser/ash/ownership/owner_settings_service_ash_unittest.cc
@@ -25,7 +25,6 @@
 #include "chrome/browser/ash/settings/device_settings_test_helper.h"
 #include "chrome/browser/net/fake_nss_service.h"
 #include "chrome/common/chrome_paths.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/settings/cros_settings.h"
@@ -109,8 +108,7 @@
 class OwnerSettingsServiceAshTest : public DeviceSettingsTestBase {
  public:
   OwnerSettingsServiceAshTest()
-      : local_state_(TestingBrowserProcess::GetGlobal()),
-        user_data_dir_override_(chrome::DIR_USER_DATA) {}
+      : user_data_dir_override_(chrome::DIR_USER_DATA) {}
 
   OwnerSettingsServiceAshTest(const OwnerSettingsServiceAshTest&) = delete;
   OwnerSettingsServiceAshTest& operator=(const OwnerSettingsServiceAshTest&) =
@@ -179,7 +177,6 @@
  protected:
   base::test::ScopedFeatureList feature_list_;
   raw_ptr<OwnerSettingsServiceAsh, DanglingUntriaged> service_ = nullptr;
-  ScopedTestingLocalState local_state_;
   std::unique_ptr<DeviceSettingsProvider> provider_;
   base::ScopedPathOverride user_data_dir_override_;
   bool management_settings_set_ = false;
diff --git a/chrome/browser/ash/plugin_vm/plugin_vm_manager_impl_unittest.cc b/chrome/browser/ash/plugin_vm/plugin_vm_manager_impl_unittest.cc
index 091cd2ad..fd243afa 100644
--- a/chrome/browser/ash/plugin_vm/plugin_vm_manager_impl_unittest.cc
+++ b/chrome/browser/ash/plugin_vm/plugin_vm_manager_impl_unittest.cc
@@ -23,7 +23,6 @@
 #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h"
 #include "chrome/browser/ui/ash/shelf/shelf_controller_helper.h"
 #include "chrome/browser/ui/ash/shelf/shelf_spinner_controller.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/chunneld/chunneld_client.h"
@@ -154,9 +153,6 @@
 
   content::BrowserTaskEnvironment task_environment_;
 
-  // Needed for `DriveIntegrationService`, which `GuestOsSharePath` depends on.
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
-
   std::unique_ptr<TestingProfile> testing_profile_;
   std::unique_ptr<PluginVmTestHelper> test_helper_;
   std::unique_ptr<NotificationDisplayServiceTester> display_service_;
diff --git a/chrome/browser/ash/policy/core/browser_policy_connector_ash_unittest.cc b/chrome/browser/ash/policy/core/browser_policy_connector_ash_unittest.cc
index cb58ab48..497ae3fa 100644
--- a/chrome/browser/ash/policy/core/browser_policy_connector_ash_unittest.cc
+++ b/chrome/browser/ash/policy/core/browser_policy_connector_ash_unittest.cc
@@ -11,7 +11,6 @@
 #include "chrome/browser/ash/wallpaper_handlers/test_wallpaper_fetcher_delegate.h"
 #include "chrome/browser/ui/ash/wallpaper/test_wallpaper_controller.h"
 #include "chrome/browser/ui/ash/wallpaper/wallpaper_controller_client_impl.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/settings/cros_settings_names.h"
 #include "components/account_id/account_id.h"
@@ -28,8 +27,6 @@
 namespace policy {
 
 TEST(BrowserPolicyConnectorAshTest, UserManager) {
-  ScopedTestingLocalState testing_local_state{
-      TestingBrowserProcess::GetGlobal()};
   content::BrowserTaskEnvironment task_environment;
   constexpr auto kAccountId = AccountId::Literal::FromUserEmailGaiaId(
       "test@example.com", GaiaId::Literal("1234567890"));
@@ -47,7 +44,7 @@
   user_manager::ScopedUserManager user_manager(
       std::make_unique<user_manager::UserManagerImpl>(
           std::make_unique<user_manager::FakeUserManagerDelegate>(),
-          TestingBrowserProcess::GetGlobal()->GetTestingLocalState()));
+          TestingBrowserProcess::GetGlobal()->local_state()));
   ash::UserImageManagerRegistry user_image_manager_registry(user_manager.Get());
 
   {
diff --git a/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash_unittest.cc b/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash_unittest.cc
index f32a59c..56be70f6f6 100644
--- a/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash_unittest.cc
+++ b/chrome/browser/ash/policy/core/device_cloud_policy_manager_ash_unittest.cc
@@ -40,7 +40,6 @@
 #include "chrome/browser/device_identity/device_oauth2_token_service_factory.h"
 #include "chrome/browser/policy/messaging_layer/public/report_client_test_util.h"
 #include "chrome/browser/prefs/browser_prefs.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/attestation/fake_certificate.h"
@@ -230,7 +229,7 @@
     manager_->SetSigninProfileSchemaRegistry(&schema_registry_);
 
     user_manager_ = std::make_unique<user_manager::FakeUserManager>(
-        scoped_testing_local_state_.Get());
+        TestingBrowserProcess::GetGlobal()->local_state());
     manager_->OnUserManagerCreated(user_manager_.get());
 
     // SharedURLLoaderFactory and LocalState singletons have to be set since
@@ -242,7 +241,7 @@
     ash::SystemSaltGetter::Initialize();
     DeviceOAuth2TokenServiceFactory::Initialize(
         test_url_loader_factory_.GetSafeWeakWrapper(),
-        scoped_testing_local_state_.Get());
+        TestingBrowserProcess::GetGlobal()->local_state());
 
     url_fetcher_response_code_ = net::HTTP_OK;
     url_fetcher_response_string_ =
@@ -314,7 +313,7 @@
   }
 
   void InitDeviceCloudPolicyInitializer() {
-    manager_->Initialize(scoped_testing_local_state_.Get());
+    manager_->Initialize(TestingBrowserProcess::GetGlobal()->local_state());
     EnrollmentRequisitionManager::Initialize();
     initializer_ = std::make_unique<DeviceCloudPolicyInitializer>(
         &device_management_service_, install_attributes_.get(),
@@ -373,9 +372,6 @@
   std::unique_ptr<reporting::ReportingClient::TestEnvironment>
       reporting_test_enviroment_;
 
-  ScopedTestingLocalState scoped_testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
-
   std::unique_ptr<ash::InstallAttributes> install_attributes_;
 
   net::HttpStatusCode url_fetcher_response_code_;
@@ -412,7 +408,7 @@
   FlushDeviceSettings();
   EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
 
-  manager_->Initialize(scoped_testing_local_state_.Get());
+  manager_->Initialize(TestingBrowserProcess::GetGlobal()->local_state());
 
   PolicyBundle bundle;
   EXPECT_TRUE(manager_->policies().Equals(bundle));
diff --git a/chrome/browser/ash/policy/core/device_cloud_policy_store_ash_unittest.cc b/chrome/browser/ash/policy/core/device_cloud_policy_store_ash_unittest.cc
index 2b50e18..d88d12b5 100644
--- a/chrome/browser/ash/policy/core/device_cloud_policy_store_ash_unittest.cc
+++ b/chrome/browser/ash/policy/core/device_cloud_policy_store_ash_unittest.cc
@@ -19,7 +19,6 @@
 #include "base/values.h"
 #include "chrome/browser/ash/settings/device_settings_test_helper.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/dbus/dbus_thread_manager.h"
 #include "chromeos/ash/components/dbus/device_management/fake_install_attributes_client.h"
@@ -33,6 +32,8 @@
 #include "components/policy/policy_constants.h"
 #include "components/policy/proto/chrome_device_policy.pb.h"
 #include "components/policy/proto/device_management_backend.pb.h"
+#include "components/prefs/pref_service.h"
+#include "components/prefs/testing_pref_service.h"
 #include "content/public/test/test_utils.h"
 #include "crypto/rsa_private_key.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -59,8 +60,7 @@
       const DeviceCloudPolicyStoreAshTest&) = delete;
 
  protected:
-  DeviceCloudPolicyStoreAshTest()
-      : local_state_(TestingBrowserProcess::GetGlobal()) {}
+  DeviceCloudPolicyStoreAshTest() = default;
 
   ~DeviceCloudPolicyStoreAshTest() override = default;
 
@@ -155,7 +155,6 @@
     store_->AddObserver(&observer_);
   }
 
-  ScopedTestingLocalState local_state_;
   std::unique_ptr<ash::InstallAttributes> install_attributes_;
 
   std::unique_ptr<DeviceCloudPolicyStoreAsh> store_;
@@ -315,8 +314,8 @@
 TEST_F(DeviceCloudPolicyStoreAshTest, StoreDeviceIdValidationEnabled) {
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndEnableFeature(features::kDeviceIdValidation);
-  local_state_.Get()->SetManagedPref(prefs::kEnrollmentVersionOS,
-                                     base::Value("128"));
+  TestingBrowserProcess::GetGlobal()->GetTestingLocalState()->SetManagedPref(
+      prefs::kEnrollmentVersionOS, base::Value("128"));
   PrepareExistingPolicy();
 
   // Set the device_id created by the policy generator. Expected to be valid.
@@ -335,8 +334,8 @@
 TEST_F(DeviceCloudPolicyStoreAshTest, StoreDeviceIdValidationEnabledError) {
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndEnableFeature(features::kDeviceIdValidation);
-  local_state_.Get()->SetManagedPref(prefs::kEnrollmentVersionOS,
-                                     base::Value("128"));
+  TestingBrowserProcess::GetGlobal()->GetTestingLocalState()->SetManagedPref(
+      prefs::kEnrollmentVersionOS, base::Value("128"));
   PrepareExistingPolicy();
 
   device_policy_->policy_data().mutable_device_id()->assign("bad-device-id");
diff --git a/chrome/browser/ash/policy/core/device_local_account_policy_service_unittest.cc b/chrome/browser/ash/policy/core/device_local_account_policy_service_unittest.cc
index 0a812cb1..674bd9d 100644
--- a/chrome/browser/ash/policy/core/device_local_account_policy_service_unittest.cc
+++ b/chrome/browser/ash/policy/core/device_local_account_policy_service_unittest.cc
@@ -343,7 +343,7 @@
 
 TEST_F(DeviceLocalAccountPolicyServiceTest, LoadValidationFailure) {
   device_local_account_policy_.policy_data().set_policy_type(
-      dm_protocol::kChromeUserPolicyType);
+      dm_protocol::GetChromeUserPolicyType());
   InstallDeviceLocalAccountPolicy(kAccount1);
   AddDeviceLocalAccountToPolicy(kAccount1);
   EXPECT_CALL(service_observer_, OnPolicyUpdated(account_1_user_id_));
@@ -395,7 +395,7 @@
   ASSERT_TRUE(broker->core()->store());
 
   device_local_account_policy_.policy_data().set_policy_type(
-      dm_protocol::kChromeUserPolicyType);
+      dm_protocol::GetChromeUserPolicyType());
   device_local_account_policy_.Build();
   broker->core()->store()->Store(device_local_account_policy_.policy());
   EXPECT_CALL(service_observer_, OnPolicyUpdated(account_1_user_id_));
diff --git a/chrome/browser/ash/policy/core/user_cloud_policy_manager_ash.cc b/chrome/browser/ash/policy/core/user_cloud_policy_manager_ash.cc
index 83e26db..224a8229 100644
--- a/chrome/browser/ash/policy/core/user_cloud_policy_manager_ash.cc
+++ b/chrome/browser/ash/policy/core/user_cloud_policy_manager_ash.cc
@@ -152,7 +152,7 @@
     const AccountId& account_id,
     const scoped_refptr<base::SequencedTaskRunner>& task_runner)
     : CloudPolicyManager(
-          dm_protocol::kChromeUserPolicyType,
+          dm_protocol::GetChromeUserPolicyType(),
           std::string(),
           std::move(store),
           task_runner,
diff --git a/chrome/browser/ash/policy/core/user_cloud_policy_manager_ash_unittest.cc b/chrome/browser/ash/policy/core/user_cloud_policy_manager_ash_unittest.cc
index 28f460f..a40f1cc1 100644
--- a/chrome/browser/ash/policy/core/user_cloud_policy_manager_ash_unittest.cc
+++ b/chrome/browser/ash/policy/core/user_cloud_policy_manager_ash_unittest.cc
@@ -196,7 +196,7 @@
     policy_proto.mutable_homepagelocation()->set_value("http://chromium.org");
     ASSERT_TRUE(
         policy_proto.SerializeToString(policy_data_.mutable_policy_value()));
-    policy_data_.set_policy_type(dm_protocol::kChromeUserPolicyType);
+    policy_data_.set_policy_type(dm_protocol::GetChromeUserPolicyType());
     policy_data_.set_device_id(kDeviceId);
     policy_data_.set_request_token(kDMToken);
     policy_data_.set_device_id("id987");
diff --git a/chrome/browser/ash/policy/core/user_cloud_policy_store_ash_unittest.cc b/chrome/browser/ash/policy/core/user_cloud_policy_store_ash_unittest.cc
index a30ed1e3..1607769 100644
--- a/chrome/browser/ash/policy/core/user_cloud_policy_store_ash_unittest.cc
+++ b/chrome/browser/ash/policy/core/user_cloud_policy_store_ash_unittest.cc
@@ -441,7 +441,7 @@
   EXPECT_EQ(initial_public_key, store_->policy_signature_public_key());
 
   // Store the correct policy signed with the new public key.
-  policy_.policy_data().set_policy_type(dm_protocol::kChromeUserPolicyType);
+  policy_.policy_data().set_policy_type(dm_protocol::GetChromeUserPolicyType());
   policy_.Build();
   std::string new_public_key = policy_.GetPublicNewSigningKeyAsString();
   ASSERT_FALSE(new_public_key.empty());
diff --git a/chrome/browser/ash/policy/dlp/test/dlp_files_test_with_mounts.h b/chrome/browser/ash/policy/dlp/test/dlp_files_test_with_mounts.h
index 957077fa..84d4bbb 100644
--- a/chrome/browser/ash/policy/dlp/test/dlp_files_test_with_mounts.h
+++ b/chrome/browser/ash/policy/dlp/test/dlp_files_test_with_mounts.h
@@ -11,7 +11,6 @@
 #include "chrome/browser/chromeos/policy/dlp/test/dlp_files_test_base.h"
 #include "chrome/browser/enterprise/data_controls/dlp_reporting_manager_test_helper.h"
 #include "chrome/browser/policy/messaging_layer/public/report_client_test_util.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "components/enterprise/common/proto/synced/dlp_policy_event.pb.h"
 #include "storage/browser/file_system/external_mount_points.h"
@@ -42,9 +41,6 @@
   std::unique_ptr<KeyedService> SetFilesPolicyNotificationManager(
       content::BrowserContext* context);
 
-  // Needed for `DriveIntegrationService`.
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
-
   raw_ptr<MockFilesPolicyNotificationManager, DanglingUntriaged> fpnm_ =
       nullptr;
   std::unique_ptr<DlpFilesControllerAsh> files_controller_;
diff --git a/chrome/browser/ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler_unittest.cc b/chrome/browser/ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler_unittest.cc
index 2d7e96b..5834e86 100644
--- a/chrome/browser/ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler_unittest.cc
+++ b/chrome/browser/ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler_unittest.cc
@@ -18,12 +18,12 @@
 #include "chrome/browser/browser_process_platform_part.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/install_attributes/stub_install_attributes.h"
 #include "chromeos/dbus/power/fake_power_manager_client.h"
 #include "components/account_id/account_id.h"
 #include "components/policy/proto/chrome_device_policy.pb.h"
+#include "components/prefs/pref_service.h"
 #include "components/user_manager/fake_user_manager.h"
 #include "components/user_manager/scoped_user_manager.h"
 #include "content/public/test/browser_task_environment.h"
@@ -44,8 +44,7 @@
   using NotificationType = ash::AdbSideloadingPolicyChangeNotification::Type;
 
   AdbSideloadingAllowanceModePolicyHandlerTest()
-      : local_state_(TestingBrowserProcess::GetGlobal()),
-        user_manager_(new ash::FakeChromeUserManager()),
+      : user_manager_(new ash::FakeChromeUserManager()),
         user_manager_enabler_(base::WrapUnique(user_manager_.get())),
         mock_notification_(new ash::MockAdbSideloadingPolicyChangeNotification(
             TestingBrowserProcess::GetGlobal()
@@ -55,7 +54,8 @@
 
     adb_sideloading_allowance_mode_policy_handler_ =
         std::make_unique<AdbSideloadingAllowanceModePolicyHandler>(
-            ash::CrosSettings::Get(), local_state_.Get(),
+            ash::CrosSettings::Get(),
+            TestingBrowserProcess::GetGlobal()->local_state(),
             chromeos::PowerManagerClient::Get(),
             // Ownership is moved to AdbSideloadingAllowanceModePolicyHandler.
             base::WrapUnique(mock_notification_.get()));
@@ -115,7 +115,7 @@
     // Fake that the first notification had been displayed more than 24 hours
     // ago.
     base::Time yesterday = base::Time::Now() - base::Hours(25);
-    local_state_.Get()->SetInt64(
+    TestingBrowserProcess::GetGlobal()->local_state()->SetInt64(
         prefs::kAdbSideloadingPowerwashPlannedNotificationShownTime,
         yesterday.ToDeltaSinceWindowsEpoch().InSeconds());
   }
@@ -123,7 +123,6 @@
   bool is_arc_sideloading_enabled_ = false;
 
   content::BrowserTaskEnvironment task_environment_;
-  ScopedTestingLocalState local_state_;
   raw_ptr<ash::FakeChromeUserManager, DanglingUntriaged> user_manager_;
   user_manager::ScopedUserManager user_manager_enabler_;
 
@@ -254,12 +253,12 @@
       ->SetNotificationTimerForTesting(std::move(mock_timer));
 
   // First all the preferences should have their default values
-  EXPECT_FALSE(local_state_.Get()->GetBoolean(
+  EXPECT_FALSE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kAdbSideloadingDisallowedNotificationShown));
-  EXPECT_EQ(local_state_.Get()->GetTime(
+  EXPECT_EQ(TestingBrowserProcess::GetGlobal()->local_state()->GetTime(
                 prefs::kAdbSideloadingPowerwashPlannedNotificationShownTime),
             base::Time::Min());
-  EXPECT_FALSE(local_state_.Get()->GetBoolean(
+  EXPECT_FALSE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kAdbSideloadingPowerwashOnNextRebootNotificationShown));
 
   EnableSideloading();
@@ -268,46 +267,46 @@
   base::RunLoop().RunUntilIdle();
 
   // Check that the preference for this notification is set
-  EXPECT_TRUE(local_state_.Get()->GetBoolean(
+  EXPECT_TRUE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kAdbSideloadingDisallowedNotificationShown));
 
   SetDevicePolicyToDisallowWithPowerwash();
   base::RunLoop().RunUntilIdle();
 
   // Check that the other notification's preference is reset
-  EXPECT_FALSE(local_state_.Get()->GetBoolean(
+  EXPECT_FALSE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kAdbSideloadingDisallowedNotificationShown));
   // Check that the preferences for this notification are set
-  EXPECT_NE(local_state_.Get()->GetTime(
+  EXPECT_NE(TestingBrowserProcess::GetGlobal()->local_state()->GetTime(
                 prefs::kAdbSideloadingPowerwashPlannedNotificationShownTime),
             base::Time::Min());
   mock_timer_ptr->Fire();
-  EXPECT_TRUE(local_state_.Get()->GetBoolean(
+  EXPECT_TRUE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kAdbSideloadingPowerwashOnNextRebootNotificationShown));
 
   SetDevicePolicyToDisallow();
   base::RunLoop().RunUntilIdle();
 
   // Check that the preference for this notification is set
-  EXPECT_TRUE(local_state_.Get()->GetBoolean(
+  EXPECT_TRUE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kAdbSideloadingDisallowedNotificationShown));
   // Check that the other notification's preferences are reset
-  EXPECT_EQ(local_state_.Get()->GetTime(
+  EXPECT_EQ(TestingBrowserProcess::GetGlobal()->local_state()->GetTime(
                 prefs::kAdbSideloadingPowerwashPlannedNotificationShownTime),
             base::Time::Min());
-  EXPECT_FALSE(local_state_.Get()->GetBoolean(
+  EXPECT_FALSE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kAdbSideloadingPowerwashOnNextRebootNotificationShown));
 
   SetDevicePolicyToAllow();
   base::RunLoop().RunUntilIdle();
 
   // Check that all the preferences are reset again
-  EXPECT_FALSE(local_state_.Get()->GetBoolean(
+  EXPECT_FALSE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kAdbSideloadingDisallowedNotificationShown));
-  EXPECT_EQ(local_state_.Get()->GetTime(
+  EXPECT_EQ(TestingBrowserProcess::GetGlobal()->local_state()->GetTime(
                 prefs::kAdbSideloadingPowerwashPlannedNotificationShownTime),
             base::Time::Min());
-  EXPECT_FALSE(local_state_.Get()->GetBoolean(
+  EXPECT_FALSE(TestingBrowserProcess::GetGlobal()->local_state()->GetBoolean(
       prefs::kAdbSideloadingPowerwashOnNextRebootNotificationShown));
 }
 
diff --git a/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_unittest.cc b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_unittest.cc
index c857ea1..adda6a3 100644
--- a/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_unittest.cc
+++ b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_unittest.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/browser/ash/settings/scoped_testing_cros_settings.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/dbus/shill/shill_service_client.h"
 #include "chromeos/ash/components/dbus/update_engine/fake_update_engine_client.h"
@@ -92,7 +91,6 @@
 
  private:
   bool user_managed_ = true;
-  ScopedTestingLocalState local_state_;
   base::test::ScopedFeatureList feature_list_;
   ash::ScopedTestingCrosSettings scoped_testing_cros_settings_;
   ash::ScopedStubInstallAttributes scoped_stub_install_attributes_;
@@ -103,8 +101,7 @@
   std::unique_ptr<MinimumVersionPolicyHandler> minimum_version_policy_handler_;
 };
 
-MinimumVersionPolicyHandlerTest::MinimumVersionPolicyHandlerTest()
-    : local_state_(TestingBrowserProcess::GetGlobal()) {
+MinimumVersionPolicyHandlerTest::MinimumVersionPolicyHandlerTest() {
   feature_list_.InitAndEnableFeature(ash::features::kMinimumChromeVersion);
 }
 
diff --git a/chrome/browser/ash/policy/handlers/system_proxy_handler_unittest.cc b/chrome/browser/ash/policy/handlers/system_proxy_handler_unittest.cc
index bc27936b..873ba05 100644
--- a/chrome/browser/ash/policy/handlers/system_proxy_handler_unittest.cc
+++ b/chrome/browser/ash/policy/handlers/system_proxy_handler_unittest.cc
@@ -15,13 +15,13 @@
 #include "chrome/browser/ash/net/system_proxy_manager.h"
 #include "chrome/browser/ash/settings/scoped_test_device_settings_service.h"
 #include "chrome/browser/ash/settings/scoped_testing_cros_settings.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/system_proxy/system_proxy_client.h"
 #include "chromeos/ash/components/dbus/system_proxy/system_proxy_service.pb.h"
 #include "chromeos/ash/components/network/network_handler.h"
 #include "chromeos/ash/components/network/network_handler_test_helper.h"
+#include "components/prefs/pref_service.h"
 #include "components/proxy_config/proxy_config_pref_names.h"
 #include "components/proxy_config/proxy_prefs.h"
 #include "content/public/test/browser_task_environment.h"
@@ -43,7 +43,7 @@
 // with RunLoop::Run() with explicit RunLoop::QuitClosure().
 class SystemProxyHandlerTest : public testing::Test {
  public:
-  SystemProxyHandlerTest() : local_state_(TestingBrowserProcess::GetGlobal()) {}
+  SystemProxyHandlerTest() = default;
   ~SystemProxyHandlerTest() override = default;
 
   // testing::Test
@@ -55,15 +55,16 @@
 
     system_proxy_handler_ =
         std::make_unique<SystemProxyHandler>(ash::CrosSettings::Get());
-    system_proxy_manager_ =
-        std::make_unique<ash::SystemProxyManager>(local_state_.Get());
+    system_proxy_manager_ = std::make_unique<ash::SystemProxyManager>(
+        TestingBrowserProcess::GetGlobal()->local_state());
     profile_ = std::make_unique<TestingProfile>();
     system_proxy_manager_->StartObservingPrimaryProfilePrefs(profile_.get());
 
     system_proxy_handler_->SetSystemProxyManagerForTesting(
         system_proxy_manager_.get());
-    ash::NetworkHandler::Get()->InitializePrefServices(profile_->GetPrefs(),
-                                                       local_state_.Get());
+    ash::NetworkHandler::Get()->InitializePrefServices(
+        profile_->GetPrefs(),
+        TestingBrowserProcess::GetGlobal()->local_state());
   }
 
   void TearDown() override {
@@ -102,7 +103,6 @@
 
   content::BrowserTaskEnvironment task_environment_;
   std::unique_ptr<ash::NetworkHandlerTestHelper> network_handler_test_helper_;
-  ScopedTestingLocalState local_state_;
   ash::ScopedTestDeviceSettingsService device_settings_service_;
   ash::ScopedTestingCrosSettings scoped_testing_cros_settings_;
   ash::ScopedStubInstallAttributes test_install_attributes_;
diff --git a/chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler_unittest.cc b/chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler_unittest.cc
index 4776cc6..575ad78 100644
--- a/chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler_unittest.cc
+++ b/chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler_unittest.cc
@@ -19,7 +19,6 @@
 #include "chrome/browser/ash/tpm/tpm_firmware_update.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/dbus/dbus_thread_manager.h"
 #include "chromeos/ash/components/dbus/session_manager/fake_session_manager_client.h"
@@ -44,8 +43,7 @@
 class TPMAutoUpdateModePolicyHandlerTest : public testing::Test {
  public:
   TPMAutoUpdateModePolicyHandlerTest()
-      : local_state_(TestingBrowserProcess::GetGlobal()),
-        user_manager_(new ash::FakeChromeUserManager()),
+      : user_manager_(new ash::FakeChromeUserManager()),
         user_manager_enabler_(base::WrapUnique(user_manager_.get())) {
     ash::SessionManagerClient::InitializeFakeInMemory();
   }
@@ -77,7 +75,6 @@
       ash::TpmAutoUpdateUserNotification::kNone;
 
   content::BrowserTaskEnvironment task_environment_;
-  ScopedTestingLocalState local_state_;
   raw_ptr<ash::FakeChromeUserManager, DanglingUntriaged> user_manager_;
   user_manager::ScopedUserManager user_manager_enabler_;
 
@@ -93,7 +90,8 @@
 // policy option TPMFirmwareUpdateSettings.AutoUpdateMode.
 TEST_F(TPMAutoUpdateModePolicyHandlerTest, PolicyUpdatesTriggered) {
   TPMAutoUpdateModePolicyHandler tpm_update_policy_handler(
-      ash::CrosSettings::Get(), local_state_.Get());
+      ash::CrosSettings::Get(),
+      TestingBrowserProcess::GetGlobal()->local_state());
   tpm_update_policy_handler.SetUpdateCheckerCallbackForTesting(
       base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::CheckForUpdate,
                           weak_factory_.GetWeakPtr()));
@@ -131,7 +129,8 @@
 // state preserving update is not available.
 TEST_F(TPMAutoUpdateModePolicyHandlerTest, NoUpdatesAvailable) {
   TPMAutoUpdateModePolicyHandler tpm_update_policy_handler(
-      ash::CrosSettings::Get(), local_state_.Get());
+      ash::CrosSettings::Get(),
+      TestingBrowserProcess::GetGlobal()->local_state());
   tpm_update_policy_handler.SetUpdateCheckerCallbackForTesting(
       base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::CheckForUpdate,
                           weak_factory_.GetWeakPtr()));
@@ -148,7 +147,8 @@
 // after 24 hours is shown.
 TEST_F(TPMAutoUpdateModePolicyHandlerTest, ShowPlannedUpdateNotification) {
   TPMAutoUpdateModePolicyHandler tpm_update_policy_handler(
-      ash::CrosSettings::Get(), local_state_.Get());
+      ash::CrosSettings::Get(),
+      TestingBrowserProcess::GetGlobal()->local_state());
   tpm_update_policy_handler.SetUpdateCheckerCallbackForTesting(
       base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::CheckForUpdate,
                           weak_factory_.GetWeakPtr()));
@@ -182,7 +182,8 @@
 TEST_F(TPMAutoUpdateModePolicyHandlerTest,
        ShowUpdateOnRebootNotificationNoTimer) {
   TPMAutoUpdateModePolicyHandler tpm_update_policy_handler(
-      ash::CrosSettings::Get(), local_state_.Get());
+      ash::CrosSettings::Get(),
+      TestingBrowserProcess::GetGlobal()->local_state());
   tpm_update_policy_handler.SetUpdateCheckerCallbackForTesting(
       base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::CheckForUpdate,
                           weak_factory_.GetWeakPtr()));
@@ -199,7 +200,7 @@
 
   // First notification was shwed more than 24 hours ago.
   base::Time yesterday = base::Time::Now() - base::Hours(25);
-  local_state_.Get()->SetInt64(
+  TestingBrowserProcess::GetGlobal()->local_state()->SetInt64(
       prefs::kTPMUpdatePlannedNotificationShownTime,
       yesterday.ToDeltaSinceWindowsEpoch().InSeconds());
 
@@ -220,7 +221,8 @@
 TEST_F(TPMAutoUpdateModePolicyHandlerTest,
        ShowUpdateOnRebootNotificationTimer) {
   TPMAutoUpdateModePolicyHandler tpm_update_policy_handler(
-      ash::CrosSettings::Get(), local_state_.Get());
+      ash::CrosSettings::Get(),
+      TestingBrowserProcess::GetGlobal()->local_state());
   tpm_update_policy_handler.SetUpdateCheckerCallbackForTesting(
       base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::CheckForUpdate,
                           weak_factory_.GetWeakPtr()));
@@ -260,7 +262,8 @@
 // TPM update with user acknowlegment triggered.
 TEST_F(TPMAutoUpdateModePolicyHandlerTest, UpdateWithUserAcknowlegment) {
   TPMAutoUpdateModePolicyHandler tpm_update_policy_handler(
-      ash::CrosSettings::Get(), local_state_.Get());
+      ash::CrosSettings::Get(),
+      TestingBrowserProcess::GetGlobal()->local_state());
   tpm_update_policy_handler.SetUpdateCheckerCallbackForTesting(
       base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::CheckForUpdate,
                           weak_factory_.GetWeakPtr()));
@@ -271,8 +274,8 @@
   update_available_ = true;
 
   // Update at next reboot notification already shown.
-  local_state_.Get()->SetBoolean(prefs::kTPMUpdateOnNextRebootNotificationShown,
-                                 true);
+  TestingBrowserProcess::GetGlobal()->local_state()->SetBoolean(
+      prefs::kTPMUpdateOnNextRebootNotificationShown, true);
   SetAutoUpdateMode(AutoUpdateMode::kUserAcknowledgment);
   base::RunLoop().RunUntilIdle();
 
diff --git a/chrome/browser/ash/policy/remote_commands/device_command_wipe_users_job_unittest.cc b/chrome/browser/ash/policy/remote_commands/device_command_wipe_users_job_unittest.cc
index ac863d0..98d0d6c7 100644
--- a/chrome/browser/ash/policy/remote_commands/device_command_wipe_users_job_unittest.cc
+++ b/chrome/browser/ash/policy/remote_commands/device_command_wipe_users_job_unittest.cc
@@ -14,7 +14,6 @@
 #include "base/test/test_future.h"
 #include "base/time/time.h"
 #include "chrome/browser/ash/system/user_removal_manager.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
 #include "components/policy/core/common/cloud/policy_invalidation_scope.h"
@@ -90,14 +89,12 @@
 
   content::BrowserTaskEnvironment task_environment_;
 
-  ScopedTestingLocalState local_state_;
   const std::unique_ptr<MockCloudPolicyClient> client_;
   const std::unique_ptr<TestingRemoteCommandsService> service_;
 };
 
 DeviceCommandWipeUsersJobTest::DeviceCommandWipeUsersJobTest()
-    : local_state_(TestingBrowserProcess::GetGlobal()),
-      client_(std::make_unique<MockCloudPolicyClient>()),
+    : client_(std::make_unique<MockCloudPolicyClient>()),
       service_(std::make_unique<TestingRemoteCommandsService>(client_.get())) {}
 
 DeviceCommandWipeUsersJobTest::~DeviceCommandWipeUsersJobTest() = default;
diff --git a/chrome/browser/ash/policy/reporting/arc_app_install_encrypted_event_reporter_unittest.cc b/chrome/browser/ash/policy/reporting/arc_app_install_encrypted_event_reporter_unittest.cc
index aeb4f7e..f84b9fe 100644
--- a/chrome/browser/ash/policy/reporting/arc_app_install_encrypted_event_reporter_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/arc_app_install_encrypted_event_reporter_unittest.cc
@@ -21,7 +21,6 @@
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/network/network_handler_test_helper.h"
@@ -69,8 +68,6 @@
   }
 
   content::BrowserTaskEnvironment task_environment_;
-  ScopedTestingLocalState scoped_testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
   TestingProfile profile_;
   ash::system::FakeStatisticsProvider statistics_provider_;
 };
diff --git a/chrome/browser/ash/policy/reporting/arc_app_install_event_log_collector_unittest.cc b/chrome/browser/ash/policy/reporting/arc_app_install_event_log_collector_unittest.cc
index 042d1815..40637f9 100644
--- a/chrome/browser/ash/policy/reporting/arc_app_install_event_log_collector_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/arc_app_install_event_log_collector_unittest.cc
@@ -15,7 +15,6 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/shill/shill_service_client.h"
@@ -201,8 +200,6 @@
 
  private:
   content::BrowserTaskEnvironment task_environment_;
-  ScopedTestingLocalState scoped_testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
   std::unique_ptr<ash::NetworkHandlerTestHelper> network_handler_test_helper_;
   std::unique_ptr<TestingProfile> profile_;
   FakeAppInstallEventLogCollectorDelegate delegate_;
diff --git a/chrome/browser/ash/policy/reporting/arc_app_install_event_logger_unittest.cc b/chrome/browser/ash/policy/reporting/arc_app_install_event_logger_unittest.cc
index 514bdc1..01b66eb 100644
--- a/chrome/browser/ash/policy/reporting/arc_app_install_event_logger_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/arc_app_install_event_logger_unittest.cc
@@ -12,7 +12,6 @@
 #include "base/values.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/cros_disks/cros_disks_client.h"
@@ -279,8 +278,6 @@
   }
 
   content::BrowserTaskEnvironment task_environment_;
-  ScopedTestingLocalState scoped_testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
   ash::NetworkHandlerTestHelper network_handler_test_helper_;
   TestingProfile profile_;
 
diff --git a/chrome/browser/ash/policy/reporting/event_based_logs/event_observer_base_unittest.cc b/chrome/browser/ash/policy/reporting/event_based_logs/event_observer_base_unittest.cc
index 8a41bdf..62e8bd3 100644
--- a/chrome/browser/ash/policy/reporting/event_based_logs/event_observer_base_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/event_based_logs/event_observer_base_unittest.cc
@@ -21,7 +21,6 @@
 #include "chrome/browser/policy/messaging_layer/proto/synced/log_upload_event.pb.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/browser/support_tool/data_collection_module.pb.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/testing_pref_service.h"
@@ -66,12 +65,11 @@
 
 class EventObserverBaseTest : public testing::Test {
  public:
-  EventObserverBaseTest()
-      : testing_local_state_(TestingBrowserProcess::GetGlobal()) {}
+  EventObserverBaseTest() = default;
 
   void SetLastUploadTime(const std::string event_name,
                          base::Time last_upload_time) {
-    testing_local_state_.Get()->SetDict(
+    TestingBrowserProcess::GetGlobal()->local_state()->SetDict(
         policy::prefs::kEventBasedLogLastUploadTimes,
         base::Value::Dict().Set(event_name,
                                 base::TimeToValue(last_upload_time)));
@@ -83,7 +81,6 @@
  private:
   base::test::SingleThreadTaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
-  ScopedTestingLocalState testing_local_state_;
 };
 
 }  // namespace
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager_unittest.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager_unittest.cc
index 28389d5..133ba43 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager_unittest.cc
@@ -23,7 +23,6 @@
 #include "chrome/browser/chromeos/reporting/metric_default_utils.h"
 #include "chrome/browser/chromeos/reporting/metric_reporting_prefs.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/session_manager/session_manager_client.h"
@@ -1061,7 +1060,6 @@
   std::unique_ptr<::testing::NiceMock<test::MockDelegate>> mock_delegate_;
 
   ::ash::ScopedTestingCrosSettings cros_settings_;
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
 
   // Placeholder test profile needed for initializing downstream components.
   TestingProfile profile_;
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/network/https_latency_events_unittest.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/network/https_latency_events_unittest.cc
index 27cea4dff..d057464 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/network/https_latency_events_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/network/https_latency_events_unittest.cc
@@ -20,7 +20,6 @@
 #include "chrome/browser/ash/settings/stub_cros_settings_provider.h"
 #include "chrome/browser/chromeos/reporting/metric_default_utils.h"
 #include "chrome/browser/policy/messaging_layer/public/report_client_test_util.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/debug_daemon/debug_daemon_client.h"
@@ -193,7 +192,6 @@
 
   ash::ScopedStubInstallAttributes scoped_stub_install_attributes_;
   ash::ScopedTestingCrosSettings scoped_testing_cros_settings_;
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
 
   std::unique_ptr<TestingProfile> profile_;
   raw_ptr<ash::FakeChromeUserManager, DanglingUntriaged> user_manager_;
diff --git a/chrome/browser/ash/policy/reporting/os_updates/os_updates_reporter_unittest.cc b/chrome/browser/ash/policy/reporting/os_updates/os_updates_reporter_unittest.cc
index fbfdf3d..559a54c 100644
--- a/chrome/browser/ash/policy/reporting/os_updates/os_updates_reporter_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/os_updates/os_updates_reporter_unittest.cc
@@ -12,7 +12,6 @@
 #include "chrome/browser/ash/policy/reporting/user_event_reporter_helper_testing.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/policy/messaging_layer/proto/synced/os_events.pb.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/session_manager/session_manager_client.h"
diff --git a/chrome/browser/ash/policy/reporting/user_session_activity/user_session_activity_reporter_unittest.cc b/chrome/browser/ash/policy/reporting/user_session_activity/user_session_activity_reporter_unittest.cc
index 07a1943..5c31e71 100644
--- a/chrome/browser/ash/policy/reporting/user_session_activity/user_session_activity_reporter_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/user_session_activity/user_session_activity_reporter_unittest.cc
@@ -22,7 +22,6 @@
 #include "chrome/browser/ash/power/ml/idle_event_notifier.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/policy/messaging_layer/proto/synced/user_session_activity.pb.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/policy/device_local_account/device_local_account_type.h"
diff --git a/chrome/browser/ash/policy/skyvault/local_files_migration_manager_unittest.cc b/chrome/browser/ash/policy/skyvault/local_files_migration_manager_unittest.cc
index f638590..8a5aa37 100644
--- a/chrome/browser/ash/policy/skyvault/local_files_migration_manager_unittest.cc
+++ b/chrome/browser/ash/policy/skyvault/local_files_migration_manager_unittest.cc
@@ -27,7 +27,6 @@
 #include "chrome/browser/policy/profile_policy_connector.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/browser_context_helper/annotated_account_id.h"
@@ -36,6 +35,7 @@
 #include "chromeos/ash/components/disks/fake_disk_mount_manager.h"
 #include "chromeos/ash/components/system/fake_statistics_provider.h"
 #include "chromeos/ash/components/system/statistics_provider.h"
+#include "components/prefs/pref_service.h"
 #include "components/user_manager/scoped_user_manager.h"
 #include "content/public/test/browser_task_environment.h"
 #include "google_apis/gaia/gaia_id.h"
@@ -52,8 +52,7 @@
 
 class LocalFilesMigrationManagerTest : public testing::Test {
  public:
-  LocalFilesMigrationManagerTest()
-      : scoped_testing_local_state_(TestingBrowserProcess::GetGlobal()) {}
+  LocalFilesMigrationManagerTest() = default;
 
   LocalFilesMigrationManagerTest(const LocalFilesMigrationManagerTest&) =
       delete;
@@ -165,7 +164,7 @@
       bool local_user_files_allowed = false,
       const std::string& destination = download_dir_util::kLocationOneDrive) {
     SetLocalUserFilesAllowed(local_user_files_allowed);
-    scoped_testing_local_state_.Get()->SetString(
+    TestingBrowserProcess::GetGlobal()->local_state()->SetString(
         prefs::kLocalUserFilesMigrationDestination, destination);
 
     profile()->GetPrefs()->SetInteger(prefs::kSkyVaultMigrationState,
@@ -174,13 +173,13 @@
 
   // Sets the local user files allowed pref value.
   void SetLocalUserFilesAllowed(bool local_user_files_allowed) {
-    scoped_testing_local_state_.Get()->SetBoolean(prefs::kLocalUserFilesAllowed,
-                                                  local_user_files_allowed);
+    TestingBrowserProcess::GetGlobal()->local_state()->SetBoolean(
+        prefs::kLocalUserFilesAllowed, local_user_files_allowed);
   }
 
   // Sets the local user files migration destination pref value.
   void SetMigrationDestination(const std::string& destination) {
-    scoped_testing_local_state_.Get()->SetString(
+    TestingBrowserProcess::GetGlobal()->local_state()->SetString(
         prefs::kLocalUserFilesMigrationDestination, destination);
   }
 
@@ -193,7 +192,6 @@
   testing::NiceMock<ash::MockUserDataAuthClient> userdataauth_;
 
  private:
-  ScopedTestingLocalState scoped_testing_local_state_;
   base::test::ScopedFeatureList scoped_feature_list_;
   content::BrowserTaskEnvironment task_environment_;
   ash::system::FakeStatisticsProvider statistics_provider_;
diff --git a/chrome/browser/ash/policy/status_collector/child_status_collector_unittest.cc b/chrome/browser/ash/policy/status_collector/child_status_collector_unittest.cc
index 8e5a28d..6e5262b 100644
--- a/chrome/browser/ash/policy/status_collector/child_status_collector_unittest.cc
+++ b/chrome/browser/ash/policy/status_collector/child_status_collector_unittest.cc
@@ -45,7 +45,6 @@
 #include "chrome/common/chrome_content_client.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "chromeos/ash/components/dbus/cicerone/cicerone_client.h"
@@ -404,10 +403,6 @@
   content::BrowserTaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
 
-  // scoped_testing_local_state_ should be destructed after TestingProfile.
-  ScopedTestingLocalState scoped_testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
-
   ChromeContentClient content_client_;
   ChromeContentBrowserClient browser_content_client_;
   ash::system::ScopedFakeStatisticsProvider fake_statistics_provider_;
diff --git a/chrome/browser/ash/policy/status_collector/device_status_collector_unittest.cc b/chrome/browser/ash/policy/status_collector/device_status_collector_unittest.cc
index 1398b79..7d4815e 100644
--- a/chrome/browser/ash/policy/status_collector/device_status_collector_unittest.cc
+++ b/chrome/browser/ash/policy/status_collector/device_status_collector_unittest.cc
@@ -74,7 +74,6 @@
 #include "chrome/common/chrome_content_client.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "chromeos/ash/components/audio/cras_audio_handler.h"
@@ -1163,8 +1162,8 @@
 
   void MockAutoLaunchKioskIwa(
       const DeviceLocalAccount& auto_launch_app_account) {
-    kiosk_iwa_manager_ = std::make_unique<ash::KioskIwaManager>(
-        CHECK_DEREF(scoped_local_state_.Get()));
+    kiosk_iwa_manager_ = std::make_unique<ash::KioskIwaManager>(CHECK_DEREF(
+        TestingBrowserProcess::GetGlobal()->GetTestingLocalState()));
     kiosk_iwa_manager_->AddAppForTesting(auto_launch_app_account);
 
     std::vector<DeviceLocalAccount> accounts;
@@ -1198,8 +1197,6 @@
   base::ScopedEnvironmentVariableOverride timezone_override_{"TZ", "UTC"};
 
   content::BrowserTaskEnvironment task_environment_;
-  ScopedTestingLocalState scoped_local_state_{
-      TestingBrowserProcess::GetGlobal()};
 
   ChromeContentClient content_client_;
   ChromeContentBrowserClient browser_content_client_;
@@ -3865,10 +3862,12 @@
   scoped_stub_install_attributes_.Get()->SetDemoMode();
   scoped_feature_list_.InitAndEnableFeature(
       ash::features::kFeatureManagementFeatureAwareDeviceDemoMode);
-  scoped_local_state_.Get()->SetString(ash::prefs::kDemoModeCountry, "CA");
-  scoped_local_state_.Get()->SetString(ash::prefs::kDemoModeRetailerId,
-                                       "retailer");
-  scoped_local_state_.Get()->SetString(ash::prefs::kDemoModeStoreId, "1234");
+  TestingBrowserProcess::GetGlobal()->GetTestingLocalState()->SetString(
+      ash::prefs::kDemoModeCountry, "CA");
+  TestingBrowserProcess::GetGlobal()->GetTestingLocalState()->SetString(
+      ash::prefs::kDemoModeRetailerId, "retailer");
+  TestingBrowserProcess::GetGlobal()->GetTestingLocalState()->SetString(
+      ash::prefs::kDemoModeStoreId, "1234");
 
   expected.set_country("CA");
   expected.set_retailer_name("retailer");
diff --git a/chrome/browser/ash/policy/test_support/embedded_policy_test_server_mixin.cc b/chrome/browser/ash/policy/test_support/embedded_policy_test_server_mixin.cc
index b7fa3470..23394fe8 100644
--- a/chrome/browser/ash/policy/test_support/embedded_policy_test_server_mixin.cc
+++ b/chrome/browser/ash/policy/test_support/embedded_policy_test_server_mixin.cc
@@ -92,7 +92,7 @@
   client_info.device_token = policy::PolicyBuilder::kFakeToken;
   client_info.allowed_policy_types = {
       policy::dm_protocol::kChromeDevicePolicyType,
-      policy::dm_protocol::kChromeUserPolicyType,
+      policy::dm_protocol::GetChromeUserPolicyType(),
       policy::dm_protocol::kChromePublicAccountPolicyType,
       policy::dm_protocol::kChromeExtensionPolicyType,
       policy::dm_protocol::kChromeSigninExtensionPolicyType,
@@ -127,7 +127,7 @@
     const enterprise_management::CloudPolicySettings& policy,
     const std::string& policy_user) {
   policy_test_server_->policy_storage()->set_policy_user(policy_user);
-  UpdatePolicy(policy::dm_protocol::kChromeUserPolicyType,
+  UpdatePolicy(policy::dm_protocol::GetChromeUserPolicyType(),
                policy.SerializeAsString());
 }
 
diff --git a/chrome/browser/ash/policy/uploading/system_log_uploader_unittest.cc b/chrome/browser/ash/policy/uploading/system_log_uploader_unittest.cc
index fb009a22..ecc1b5d0 100644
--- a/chrome/browser/ash/policy/uploading/system_log_uploader_unittest.cc
+++ b/chrome/browser/ash/policy/uploading/system_log_uploader_unittest.cc
@@ -17,7 +17,6 @@
 #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/common/chrome_features.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "components/policy/core/common/remote_commands/remote_command_job.h"
 #include "components/prefs/testing_pref_service.h"
@@ -220,8 +219,6 @@
 
  protected:
   content::BrowserTaskEnvironment task_environment_;
-  ScopedTestingLocalState scoped_testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
   ash::ScopedCrosSettingsTestHelper settings_helper_;
   scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
   base::test::ScopedFeatureList feature_list;
diff --git a/chrome/browser/ash/printing/oauth2/client_ids_database_unittest.cc b/chrome/browser/ash/printing/oauth2/client_ids_database_unittest.cc
index 042c5ed..354fddf 100644
--- a/chrome/browser/ash/printing/oauth2/client_ids_database_unittest.cc
+++ b/chrome/browser/ash/printing/oauth2/client_ids_database_unittest.cc
@@ -12,7 +12,6 @@
 #include "base/test/mock_callback.h"
 #include "base/test/task_environment.h"
 #include "chrome/browser/ash/printing/oauth2/status_code.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -24,8 +23,6 @@
 class PrintingOAuth2ClientIdsDatabaseTest : public testing::Test {
  protected:
   base::test::TaskEnvironment task_environment_;
-  ScopedTestingLocalState pref_ =
-      ScopedTestingLocalState(TestingBrowserProcess::GetGlobal());
   std::unique_ptr<ClientIdsDatabase> client_ids_database_ =
       ClientIdsDatabase::Create();
 };
diff --git a/chrome/browser/ash/printing/server_printers_provider_unittest.cc b/chrome/browser/ash/printing/server_printers_provider_unittest.cc
index f514d41..1830d1da 100644
--- a/chrome/browser/ash/printing/server_printers_provider_unittest.cc
+++ b/chrome/browser/ash/printing/server_printers_provider_unittest.cc
@@ -10,7 +10,6 @@
 
 #include "chrome/browser/ash/printing/enterprise/print_servers_provider_factory.h"
 #include "chrome/browser/ash/printing/print_server.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/policy/proto/chrome_device_policy.pb.h"
 #include "components/user_manager/scoped_user_manager.h"
diff --git a/chrome/browser/ash/report_controller_initializer/report_controller_initializer_unittest.cc b/chrome/browser/ash/report_controller_initializer/report_controller_initializer_unittest.cc
index 6e84e65..e9adc10 100644
--- a/chrome/browser/ash/report_controller_initializer/report_controller_initializer_unittest.cc
+++ b/chrome/browser/ash/report_controller_initializer/report_controller_initializer_unittest.cc
@@ -7,7 +7,6 @@
 #include "base/memory/ptr_util.h"
 #include "chrome/browser/ash/settings/device_settings_service.h"
 #include "chrome/browser/browser_process_platform_part.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/install_attributes/stub_install_attributes.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -54,9 +53,6 @@
   }
 
  private:
-  ScopedTestingLocalState testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
-
   // Needed for `browser_policy_connector_ash()`.
   ScopedStubInstallAttributes scoped_stub_install_attributes_;
 
diff --git a/chrome/browser/ash/settings/cros_settings_unittest.cc b/chrome/browser/ash/settings/cros_settings_unittest.cc
index 7b543b8..8bf4cd9 100644
--- a/chrome/browser/ash/settings/cros_settings_unittest.cc
+++ b/chrome/browser/ash/settings/cros_settings_unittest.cc
@@ -25,7 +25,6 @@
 #include "chrome/browser/ash/settings/device_settings_service.h"
 #include "chrome/browser/ash/settings/scoped_test_device_settings_service.h"
 #include "chrome/browser/net/fake_nss_service.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/browser_context_helper/annotated_account_id.h"
@@ -36,6 +35,7 @@
 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
 #include "components/policy/proto/chrome_device_policy.pb.h"
 #include "components/policy/proto/device_management_backend.pb.h"
+#include "components/prefs/testing_pref_service.h"
 #include "components/user_manager/user_type.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/test/browser_task_environment.h"
@@ -159,11 +159,11 @@
   content::BrowserTaskEnvironment task_environment_{
       content::BrowserTaskEnvironment::IO_MAINLOOP};
 
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
   ScopedStubInstallAttributes scoped_install_attributes_;
   ScopedTestDeviceSettingsService scoped_test_device_settings_;
-  CrosSettingsHolder cros_settings_holder_{ash::DeviceSettingsService::Get(),
-                                           local_state_.Get()};
+  CrosSettingsHolder cros_settings_holder_{
+      ash::DeviceSettingsService::Get(),
+      TestingBrowserProcess::GetGlobal()->GetTestingLocalState()};
 
   FakeSessionManagerClient fake_session_manager_client_;
   scoped_refptr<ownership::MockOwnerKeyUtil> owner_key_util_{
diff --git a/chrome/browser/ash/settings/device_settings_provider_unittest.cc b/chrome/browser/ash/settings/device_settings_provider_unittest.cc
index 4a340ec..24440849 100644
--- a/chrome/browser/ash/settings/device_settings_provider_unittest.cc
+++ b/chrome/browser/ash/settings/device_settings_provider_unittest.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/ash/policy/core/device_local_account.h"
 #include "chrome/browser/ash/settings/device_settings_test_helper.h"
 #include "chrome/common/chrome_paths.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/install_attributes/stub_install_attributes.h"
@@ -27,6 +26,7 @@
 #include "components/policy/core/common/cloud/test/policy_builder.h"
 #include "components/policy/proto/chrome_device_policy.pb.h"
 #include "components/policy/proto/device_management_backend.pb.h"
+#include "components/prefs/testing_pref_service.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -58,8 +58,7 @@
 
  protected:
   DeviceSettingsProviderTest()
-      : local_state_(TestingBrowserProcess::GetGlobal()),
-        user_data_dir_override_(chrome::DIR_USER_DATA) {}
+      : user_data_dir_override_(chrome::DIR_USER_DATA) {}
 
   void SetUp() override {
     DeviceSettingsTestBase::SetUp();
@@ -73,7 +72,8 @@
     provider_ = std::make_unique<DeviceSettingsProvider>(
         base::BindRepeating(&DeviceSettingsProviderTest::SettingChanged,
                             base::Unretained(this)),
-        device_settings_service_.get(), local_state_.Get());
+        device_settings_service_.get(),
+        TestingBrowserProcess::GetGlobal()->local_state());
     Mock::VerifyAndClearExpectations(this);
   }
 
@@ -445,8 +445,6 @@
 
   base::test::ScopedFeatureList feature_list_;
 
-  ScopedTestingLocalState local_state_;
-
   std::unique_ptr<DeviceSettingsProvider> provider_;
 
   base::ScopedPathOverride user_data_dir_override_;
diff --git a/chrome/browser/ash/settings/stats_reporting_controller_unittest.cc b/chrome/browser/ash/settings/stats_reporting_controller_unittest.cc
index 5116db2..70ba9d7 100644
--- a/chrome/browser/ash/settings/stats_reporting_controller_unittest.cc
+++ b/chrome/browser/ash/settings/stats_reporting_controller_unittest.cc
@@ -17,7 +17,6 @@
 #include "chrome/browser/ash/settings/scoped_test_device_settings_service.h"
 #include "chrome/browser/net/fake_nss_service.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/policy/device_policy/device_policy_builder.h"
diff --git a/chrome/browser/ash/smb_client/smb_kerberos_credentials_updater_unittest.cc b/chrome/browser/ash/smb_client/smb_kerberos_credentials_updater_unittest.cc
index e42bf395..1de9d0b8 100644
--- a/chrome/browser/ash/smb_client/smb_kerberos_credentials_updater_unittest.cc
+++ b/chrome/browser/ash/smb_client/smb_kerberos_credentials_updater_unittest.cc
@@ -14,10 +14,10 @@
 #include "chrome/browser/ash/kerberos/kerberos_credentials_manager.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/kerberos/kerberos_client.h"
+#include "components/prefs/testing_pref_service.h"
 #include "components/user_manager/scoped_user_manager.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/test/browser_task_environment.h"
@@ -40,8 +40,7 @@
 
 class SmbKerberosCredentialsUpdaterTest : public testing::Test {
  public:
-  SmbKerberosCredentialsUpdaterTest()
-      : local_state_(TestingBrowserProcess::GetGlobal()) {
+  SmbKerberosCredentialsUpdaterTest() {
     // Enable Kerberos via policy.
     SetPref(prefs::kKerberosEnabled, base::Value(true));
 
@@ -53,7 +52,7 @@
     profile_builder.SetProfileName(kProfileEmail);
     profile_ = profile_builder.Build();
     credentials_manager_ = std::make_unique<KerberosCredentialsManager>(
-        local_state_.Get(), profile_.get());
+        TestingBrowserProcess::GetGlobal()->local_state(), profile_.get());
   }
 
   ~SmbKerberosCredentialsUpdaterTest() override {
@@ -75,7 +74,7 @@
   }
 
   void SetPref(const char* name, base::Value value) {
-    local_state_.Get()->SetManagedPref(
+    TestingBrowserProcess::GetGlobal()->GetTestingLocalState()->SetManagedPref(
         name, std::make_unique<base::Value>(std::move(value)));
   }
 
@@ -86,7 +85,6 @@
   }
 
   content::BrowserTaskEnvironment task_environment_;
-  ScopedTestingLocalState local_state_;
   user_manager::TypedScopedUserManager<FakeChromeUserManager> user_manager_{
       std::make_unique<FakeChromeUserManager>()};
   std::unique_ptr<TestingProfile> profile_;
diff --git a/chrome/browser/ash/system/automatic_reboot_manager_unittest.cc b/chrome/browser/ash/system/automatic_reboot_manager_unittest.cc
index dd6cf43..469eb1f8 100644
--- a/chrome/browser/ash/system/automatic_reboot_manager_unittest.cc
+++ b/chrome/browser/ash/system/automatic_reboot_manager_unittest.cc
@@ -30,7 +30,6 @@
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/ash/system/automatic_reboot_manager_observer.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/dbus/update_engine/fake_update_engine_client.h"
 #include "chromeos/dbus/power/fake_power_manager_client.h"
@@ -225,8 +224,6 @@
   base::SingleThreadTaskRunner::CurrentHandleOverrideForTesting
       single_thread_task_runner_current_default_handle_override_;
 
-  ScopedTestingLocalState scoped_testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
   user_manager::TypedScopedUserManager<ash::FakeChromeUserManager>
       user_manager_;
   session_manager::SessionManager session_manager_;
@@ -376,7 +373,7 @@
     bool reboot_after_update,
     bool expect_reboot) {
   reboot_after_update_ = reboot_after_update;
-  scoped_testing_local_state_.Get()->SetManagedPref(
+  TestingBrowserProcess::GetGlobal()->GetTestingLocalState()->SetManagedPref(
       prefs::kRebootAfterUpdate,
       std::make_unique<base::Value>(reboot_after_update));
   task_runner_->RunUntilIdle();
@@ -390,9 +387,11 @@
     bool expect_reboot) {
   uptime_limit_ = limit;
   if (limit.is_zero()) {
-    scoped_testing_local_state_.Get()->RemoveManagedPref(prefs::kUptimeLimit);
+    TestingBrowserProcess::GetGlobal()
+        ->GetTestingLocalState()
+        ->RemoveManagedPref(prefs::kUptimeLimit);
   } else {
-    scoped_testing_local_state_.Get()->SetManagedPref(
+    TestingBrowserProcess::GetGlobal()->GetTestingLocalState()->SetManagedPref(
         prefs::kUptimeLimit,
         std::make_unique<base::Value>(static_cast<int>(limit.InSeconds())));
   }
diff --git a/chrome/browser/ash/system/device_disabling_manager_unittest.cc b/chrome/browser/ash/system/device_disabling_manager_unittest.cc
index 229c6dcf..f44a4f1 100644
--- a/chrome/browser/ash/system/device_disabling_manager_unittest.cc
+++ b/chrome/browser/ash/system/device_disabling_manager_unittest.cc
@@ -19,7 +19,6 @@
 #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/browser/browser_process_platform_part.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/dbus/session_manager/fake_session_manager_client.h"
 #include "chromeos/ash/components/policy/device_policy/device_policy_builder.h"
@@ -147,8 +146,6 @@
  private:
   void OnDeviceDisabledChecked(bool device_disabled);
 
-  ScopedTestingLocalState scoped_testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
   FakeStatisticsProvider statistics_provider_;
 
   base::RunLoop run_loop_;
@@ -177,7 +174,7 @@
 }
 
 void DeviceDisablingManagerOOBETest::SetDeviceDisabled(bool disabled) {
-  ScopedDictPrefUpdate dict(scoped_testing_local_state_.Get(),
+  ScopedDictPrefUpdate dict(TestingBrowserProcess::GetGlobal()->local_state(),
                             prefs::kServerBackedDeviceState);
   if (disabled) {
     dict->Set(policy::kDeviceStateMode, policy::kDeviceStateModeDisabled);
diff --git a/chrome/browser/ash/system/user_removal_manager_unittest.cc b/chrome/browser/ash/system/user_removal_manager_unittest.cc
index 49501aa..f9907f8 100644
--- a/chrome/browser/ash/system/user_removal_manager_unittest.cc
+++ b/chrome/browser/ash/system/user_removal_manager_unittest.cc
@@ -13,10 +13,11 @@
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/ash/settings/scoped_testing_cros_settings.h"
 #include "chrome/common/pref_names.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/install_attributes/stub_install_attributes.h"
 #include "components/account_id/account_id.h"
+#include "components/prefs/pref_service.h"
+#include "components/prefs/testing_pref_service.h"
 #include "components/user_manager/fake_user_manager_delegate.h"
 #include "components/user_manager/scoped_user_manager.h"
 #include "components/user_manager/test_helper.h"
diff --git a/chrome/browser/ash/system_web_apps/apps/help_app/help_app_notification_controller_unittest.cc b/chrome/browser/ash/system_web_apps/apps/help_app/help_app_notification_controller_unittest.cc
index 53e122b..e0ab18fd 100644
--- a/chrome/browser/ash/system_web_apps/apps/help_app/help_app_notification_controller_unittest.cc
+++ b/chrome/browser/ash/system_web_apps/apps/help_app/help_app_notification_controller_unittest.cc
@@ -43,7 +43,7 @@
 
   TestingProfile* CreateRegularProfile() {
     constexpr char kEmail[] = "user@gmail.com";
-    const GaiaId kFakeGaia("fakegaia");
+    const GaiaId kFakeGaia("fakegaia123");
     LogIn(kEmail, kFakeGaia);
     auto* profile = CreateProfile(kEmail);
     // Set profile creation version, otherwise it defaults to 1.0.0.0.
diff --git a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_user_provider_impl_unittest.cc b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_user_provider_impl_unittest.cc
index 129e1670..0819457 100644
--- a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_user_provider_impl_unittest.cc
+++ b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_user_provider_impl_unittest.cc
@@ -29,7 +29,6 @@
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_utils.h"
 #include "chrome/common/chrome_paths.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
@@ -312,7 +311,6 @@
   }
 
  private:
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
   base::test::ScopedFeatureList scoped_feature_list_;
   content::BrowserTaskEnvironment task_environment_;
   FakeVideoCaptureService fake_video_capture_service_;
diff --git a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc
index abfaaf593..652677c 100644
--- a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc
+++ b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_wallpaper_provider_impl_unittest.cc
@@ -51,7 +51,6 @@
 #include "chrome/browser/profiles/profile_attributes_storage.h"
 #include "chrome/browser/ui/ash/wallpaper/test_wallpaper_controller.h"
 #include "chrome/browser/ui/ash/wallpaper/wallpaper_controller_client_impl.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
diff --git a/chrome/browser/ash/system_web_apps/system_web_app_manager_unittest.cc b/chrome/browser/ash/system_web_apps/system_web_app_manager_unittest.cc
index fbe7c01..9c5c5bf8 100644
--- a/chrome/browser/ash/system_web_apps/system_web_app_manager_unittest.cc
+++ b/chrome/browser/ash/system_web_apps/system_web_app_manager_unittest.cc
@@ -38,7 +38,6 @@
 #include "chrome/browser/web_applications/web_app_registry_update.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/ash/components/browser_context_helper/annotated_account_id.h"
 #include "chromeos/ash/experiences/system_web_apps/types/system_web_app_delegate_map.h"
@@ -1427,8 +1426,8 @@
   void SetUp() override {
     // Kiosk user session needs to be set up before profile creation done in
     // ChromeRenderViewHostTestHarness::SetUp().
-    user_manager_.Reset(
-        std::make_unique<user_manager::FakeUserManager>(local_state_.Get()));
+    user_manager_.Reset(std::make_unique<user_manager::FakeUserManager>(
+        TestingBrowserProcess::GetGlobal()->local_state()));
     ash::ProfileHelper::Get();  // Instantiate BrowserContextHelper.
     chromeos::SetUpFakeKioskSession();
     ChromeRenderViewHostTestHarness::SetUp();
@@ -1463,7 +1462,6 @@
   }
 
  private:
-  ScopedTestingLocalState local_state_{TestingBrowserProcess::GetGlobal()};
   user_manager::ScopedUserManager user_manager_;
 };
 
diff --git a/chrome/browser/ash/tether/tether_service_unittest.cc b/chrome/browser/ash/tether/tether_service_unittest.cc
index a2565eca..786e672 100644
--- a/chrome/browser/ash/tether/tether_service_unittest.cc
+++ b/chrome/browser/ash/tether/tether_service_unittest.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/browser/ui/ash/network/tether_notification_presenter.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/dbus/shill/shill_device_client.h"
@@ -543,9 +542,6 @@
   bool is_adapter_powered_;
   bool shutdown_reason_verified_;
 
-  ScopedTestingLocalState scoped_testing_local_state_{
-      TestingBrowserProcess::GetGlobal()};
-
   std::unique_ptr<TestTetherService> tether_service_;
   std::unique_ptr<TestingProfile> profile_;
 
diff --git a/chrome/browser/ash/wallpaper_handlers/google_photos_wallpaper_handlers_unittest.cc b/chrome/browser/ash/wallpaper_handlers/google_photos_wallpaper_handlers_unittest.cc
index d77ddb8..527f212 100644
--- a/chrome/browser/ash/wallpaper_handlers/google_photos_wallpaper_handlers_unittest.cc
+++ b/chrome/browser/ash/wallpaper_handlers/google_photos_wallpaper_handlers_unittest.cc
@@ -16,7 +16,6 @@
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h"
 #include "chrome/browser/ash/wallpaper_handlers/wallpaper_fetcher_delegate.h"
-#include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
diff --git a/chrome/browser/browser_features.cc b/chrome/browser/browser_features.cc
index 6195114..e181af9 100644
--- a/chrome/browser/browser_features.cc
+++ b/chrome/browser/browser_features.cc
@@ -40,6 +40,11 @@
              "BookmarkTriggerForPrerender2",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
+// This flag is used for enabling BookmarkBar triggered preconnect.
+BASE_FEATURE(kBookmarkTriggerForPreconnect,
+             "BookmarkTriggerForPreconnect",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 // Enables Certificate Transparency on Desktop and Android Browser (CT is
 // disabled in Android Webview, see aw_browser_context.cc).
 // Enabling CT enforcement requires maintaining a log policy, and the ability to
diff --git a/chrome/browser/browser_features.h b/chrome/browser/browser_features.h
index d7ce506c..e5003ab 100644
--- a/chrome/browser/browser_features.h
+++ b/chrome/browser/browser_features.h
@@ -34,6 +34,7 @@
 BASE_DECLARE_FEATURE(kAutocompleteActionPredictorConfidenceCutoff);
 BASE_DECLARE_FEATURE(kBookmarksTreeView);
 BASE_DECLARE_FEATURE(kBookmarkTriggerForPrerender2);
+BASE_DECLARE_FEATURE(kBookmarkTriggerForPreconnect);
 BASE_DECLARE_FEATURE(kCertificateTransparencyAskBeforeEnabling);
 BASE_DECLARE_FEATURE(kCertVerificationNetworkTime);
 BASE_DECLARE_FEATURE(kClearUserDataUponProfileDestruction);
diff --git a/chrome/browser/chromeos/extensions/login_screen/login/login_apitest.cc b/chrome/browser/chromeos/extensions/login_screen/login/login_apitest.cc
index dddbbac5..ffa0d77 100644
--- a/chrome/browser/chromeos/extensions/login_screen/login/login_apitest.cc
+++ b/chrome/browser/chromeos/extensions/login_screen/login/login_apitest.cc
@@ -449,7 +449,7 @@
     SetUpSessionExtensionUserPolicyBuilder();
     enterprise_management::PolicyData& policy_data =
         user_policy_builder_->policy_data();
-    policy_data.set_policy_type(policy::dm_protocol::kChromeUserPolicyType);
+    policy_data.set_policy_type(policy::dm_protocol::GetChromeUserPolicyType());
     policy_data.set_username(account_id.GetUserEmail());
     policy_data.set_gaia_id(account_id.GetGaiaId().ToString());
     user_policy_builder_->Build();
diff --git a/chrome/browser/component_updater/pki_metadata_component_installer_browsertest.cc b/chrome/browser/component_updater/pki_metadata_component_installer_browsertest.cc
index 11c29c0..88e10157 100644
--- a/chrome/browser/component_updater/pki_metadata_component_installer_browsertest.cc
+++ b/chrome/browser/component_updater/pki_metadata_component_installer_browsertest.cc
@@ -65,6 +65,7 @@
 #include "chrome/browser/ssl/ssl_browsertest_util.h"
 #include "net/base/features.h"
 #include "net/cert/internal/trust_store_chrome.h"
+#include "net/cert/root_store_proto_lite/root_store.pb.h"
 #include "net/cert/x509_util.h"
 #include "net/test/cert_builder.h"
 #include "third_party/boringssl/src/include/openssl/ssl.h"
diff --git a/chrome/browser/contextual_cueing/zero_state_suggestions_request.cc b/chrome/browser/contextual_cueing/zero_state_suggestions_request.cc
index 04e43cf..d427896 100644
--- a/chrome/browser/contextual_cueing/zero_state_suggestions_request.cc
+++ b/chrome/browser/contextual_cueing/zero_state_suggestions_request.cc
@@ -115,18 +115,11 @@
     CHECK_EQ(filtered_page_contexts.size(), 1u);
     *pending_base_request_.mutable_page_context() =
         filtered_page_contexts.front().page_context();
-  } else if (pending_base_request_.has_page_context_list() &&
-             filtered_page_contexts.size() > 1) {
+  } else if (pending_base_request_.has_page_context_list()) {
     pending_base_request_.mutable_page_context()->Clear();
     *pending_base_request_.mutable_page_context_list()
          ->mutable_page_contexts() = {filtered_page_contexts.begin(),
                                       filtered_page_contexts.end()};
-  } else if (pending_base_request_.has_page_context_list() &&
-             filtered_page_contexts.size() == 1) {
-    // If it's a pinned tabs request with a single tab, pass up context as if it
-    // were for a focused tab request.
-    *pending_base_request_.mutable_page_context() =
-        filtered_page_contexts.front().page_context();
   }
 
   // Initiate model execution fetch.
diff --git a/chrome/browser/devtools/protocol/pwa_handler.h b/chrome/browser/devtools/protocol/pwa_handler.h
index 70881db..b28ae68 100644
--- a/chrome/browser/devtools/protocol/pwa_handler.h
+++ b/chrome/browser/devtools/protocol/pwa_handler.h
@@ -10,8 +10,7 @@
 
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/devtools/protocol/pwa.h"
-#include "chrome/browser/web_applications/isolated_web_apps/commands/install_isolated_web_app_command.h"
-#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader.h"
+#include "url/gurl.h"
 
 class Profile;
 
diff --git a/chrome/browser/download/android/download_message_bridge.cc b/chrome/browser/download/android/download_message_bridge.cc
index 506fecf..1a58b26f 100644
--- a/chrome/browser/download/android/download_message_bridge.cc
+++ b/chrome/browser/download/android/download_message_bridge.cc
@@ -4,52 +4,24 @@
 
 #include "chrome/browser/download/android/download_message_bridge.h"
 
-#include <string>
-
 #include "base/android/jni_android.h"
-#include "base/android/jni_string.h"
-#include "base/android/path_utils.h"
-#include "base/files/file_path.h"
-#include "base/memory/singleton.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/android/android_theme_resources.h"
-#include "chrome/browser/download/android/download_dialog_utils.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/grit/generated_resources.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/download_item_utils.h"
+#include "base/android/jni_callback.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/android/window_android.h"
-#include "ui/base/l10n/l10n_util.h"
 
 // Must come after all headers that specialize FromJniType() / ToJniType().
 #include "chrome/android/chrome_jni_headers/DownloadMessageBridge_jni.h"
 
-using base::android::JavaParamRef;
-
-DownloadMessageBridge::DownloadMessageBridge() {
-  JNIEnv* env = base::android::AttachCurrentThread();
-  java_object_.Reset(
-      Java_DownloadMessageBridge_create(env, reinterpret_cast<intptr_t>(this)));
-}
-
-DownloadMessageBridge::~DownloadMessageBridge() {
-  Java_DownloadMessageBridge_destroy(base::android::AttachCurrentThread(),
-                                     java_object_);
-}
+DownloadMessageBridge::DownloadMessageBridge() = default;
+DownloadMessageBridge::~DownloadMessageBridge() = default;
 
 void DownloadMessageBridge::ShowIncognitoDownloadMessage(
     DownloadMessageRequestCallback callback) {
   JNIEnv* env = base::android::AttachCurrentThread();
-
-  // Copy |callback| on the heap to pass the pointer through JNI. This callback
-  // will be deleted when it's run.
   CHECK(!callback.is_null());
-  jlong callback_id = reinterpret_cast<jlong>(
-      new DownloadMessageRequestCallback(std::move(callback)));
-  validator_.AddJavaCallback(callback_id);
-  Java_DownloadMessageBridge_showIncognitoDownloadMessage(env, java_object_,
-                                                          callback_id);
+  // Convert the C++ callback to a JNI callback using ToJniCallback.
+  Java_DownloadMessageBridge_showIncognitoDownloadMessage(
+      env, base::android::ToJniCallback(env, std::move(callback)));
 }
 
 void DownloadMessageBridge::ShowUnsupportedDownloadMessage(
@@ -63,16 +35,5 @@
   }
 
   Java_DownloadMessageBridge_showUnsupportedDownloadMessage(
-      env, java_object_, window_android->GetJavaObject());
-}
-
-void DownloadMessageBridge::OnConfirmed(JNIEnv* env,
-                                        jlong callback_id,
-                                        jboolean accepted) {
-  if (!validator_.ValidateAndClearJavaCallback(callback_id))
-    return;
-  // Convert java long long int to c++ pointer, take ownership.
-  std::unique_ptr<DownloadMessageRequestCallback> cb(
-      reinterpret_cast<DownloadMessageRequestCallback*>(callback_id));
-  std::move(*cb).Run(accepted);
+      env, window_android->GetJavaObject());
 }
diff --git a/chrome/browser/download/android/download_message_bridge.h b/chrome/browser/download/android/download_message_bridge.h
index 6cd59af..4e78b4bf 100644
--- a/chrome/browser/download/android/download_message_bridge.h
+++ b/chrome/browser/download/android/download_message_bridge.h
@@ -5,10 +5,7 @@
 #ifndef CHROME_BROWSER_DOWNLOAD_ANDROID_DOWNLOAD_MESSAGE_BRIDGE_H_
 #define CHROME_BROWSER_DOWNLOAD_ANDROID_DOWNLOAD_MESSAGE_BRIDGE_H_
 
-#include "base/android/jni_android.h"
-#include "base/android/scoped_java_ref.h"
-#include "chrome/browser/download/android/download_callback_validator.h"
-#include "chrome/browser/download/download_target_determiner_delegate.h"
+#include "base/functional/callback.h"
 #include "components/download/public/common/download_item.h"
 
 namespace content {
@@ -30,15 +27,6 @@
   void ShowIncognitoDownloadMessage(DownloadMessageRequestCallback callback);
   virtual void ShowUnsupportedDownloadMessage(
       content::WebContents* web_contents);
-
-  // Called from Java via JNI.
-  void OnConfirmed(JNIEnv* env, jlong callback_id, jboolean accepted);
-
- private:
-  // Validator for all JNI callbacks.
-  DownloadCallbackValidator validator_;
-  // The corresponding java object.
-  base::android::ScopedJavaGlobalRef<jobject> java_object_;
 };
 
 #endif  // CHROME_BROWSER_DOWNLOAD_ANDROID_DOWNLOAD_MESSAGE_BRIDGE_H_
diff --git a/chrome/browser/extensions/api/autofill_private/autofill_util.cc b/chrome/browser/extensions/api/autofill_private/autofill_util.cc
index 76265713..492ec4d2 100644
--- a/chrome/browser/extensions/api/autofill_private/autofill_util.cc
+++ b/chrome/browser/extensions/api/autofill_private/autofill_util.cc
@@ -330,21 +330,8 @@
 
 PayOverTimeIssuerEntryList GeneratePayOverTimeIssuerList(
     const autofill::PaymentsDataManager& paydm) {
-  std::vector<autofill::BnplIssuer> linked_issuers =
-      base::ToVector(paydm.GetLinkedBnplIssuers());
-
-  // Remove the issuer entry if a BNPL issuer is linked externally, due to
-  // missing terms of services acceptance.
-  linked_issuers.erase(
-      std::remove_if(
-          linked_issuers.begin(), linked_issuers.end(),
-          [](autofill::BnplIssuer& issuer) {
-            return issuer.payment_instrument()->action_required().contains(
-                autofill::PaymentInstrument::ActionRequired::kAcceptTos);
-          }),
-      linked_issuers.end());
-
-  return base::ToVector(linked_issuers, &BnplIssuerToPayOverTimeIssuerEntry);
+  return base::ToVector(paydm.GetLinkedBnplIssuers(),
+                        &BnplIssuerToPayOverTimeIssuerEntry);
 }
 
 std::optional<api::autofill_private::AccountInfo> GetAccountInfo(
diff --git a/chrome/browser/extensions/api/autofill_private/autofill_util_unittest.cc b/chrome/browser/extensions/api/autofill_private/autofill_util_unittest.cc
index a1a44cd..1c1ff52d 100644
--- a/chrome/browser/extensions/api/autofill_private/autofill_util_unittest.cc
+++ b/chrome/browser/extensions/api/autofill_private/autofill_util_unittest.cc
@@ -8,13 +8,11 @@
 
 #include "base/functional/callback_forward.h"
 #include "base/test/mock_callback.h"
-#include "base/test/scoped_feature_list.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/autofill/core/browser/data_manager/payments/test_payments_data_manager.h"
 #include "components/autofill/core/browser/data_manager/test_personal_data_manager.h"
 #include "components/autofill/core/browser/test_utils/autofill_test_utils.h"
 #include "components/autofill/core/common/autofill_test_utils.h"
-#include "components/autofill/core/common/dense_set.h"
 #include "components/device_reauth/mock_device_authenticator.h"
 #include "content/public/test/browser_task_environment.h"
 #include "content/public/test/browser_test.h"
@@ -34,11 +32,6 @@
   return arg.metadata->is_local == is_local;
 }
 
-MATCHER_P(MatchesBnplIssuer, bnpl_issuer, "") {
-  return arg.issuer_id ==
-         autofill::ConvertToBnplIssuerIdString(bnpl_issuer.issuer_id());
-}
-
 class AutofillUtilTest : public InProcessBrowserTest {
  public:
   AutofillUtilTest() = default;
@@ -57,24 +50,6 @@
       mock_device_authenticator_;
 };
 
-class AutofillUtilTestForBnpl : public AutofillUtilTest {
- public:
-  AutofillUtilTestForBnpl() {
-    scoped_feature_list_.InitWithFeatures(
-        /*enabled_features=*/
-        {autofill::features::kAutofillEnableBuyNowPayLater,
-         autofill::features::kAutofillEnableBuyNowPayLaterSyncing,
-         autofill::features::kAutofillEnableBuyNowPayLaterForKlarna},
-        /*disabled_features=*/{});
-  }
-
-  AutofillUtilTestForBnpl(const AutofillUtilTestForBnpl&) = delete;
-  AutofillUtilTestForBnpl& operator=(const AutofillUtilTestForBnpl&) = delete;
-
- private:
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
 IN_PROC_BROWSER_TEST_F(AutofillUtilTest, GenerateIbanList) {
   autofill::TestPaymentsDataManager paydm;
   paydm.SetAutofillWalletImportEnabled(true);
@@ -127,47 +102,6 @@
 #endif
 }
 
-IN_PROC_BROWSER_TEST_F(AutofillUtilTestForBnpl,
-                       GeneratePayOverTimeIssuerList_IssuerLinkedExternally) {
-  autofill::TestPaymentsDataManager paydm;
-  paydm.SetAutofillWalletImportEnabled(true);
-  paydm.SetAutofillPaymentMethodsEnabled(true);
-  paydm.SetIsAutofillBnplPrefEnabled(true);
-  autofill::BnplIssuer issuer_affirm = autofill::test::GetTestLinkedBnplIssuer(
-      autofill::BnplIssuer::IssuerId::kBnplAffirm);
-  autofill::BnplIssuer issuer_klarna = autofill::test::GetTestLinkedBnplIssuer(
-      autofill::BnplIssuer::IssuerId::kBnplKlarna,
-      /*action_required=*/autofill::DenseSet(
-          {autofill::PaymentInstrument::ActionRequired::kAcceptTos}));
-  paydm.AddBnplIssuer(issuer_affirm);
-  paydm.AddBnplIssuer(issuer_klarna);
-
-  PayOverTimeIssuerEntryList bnpl_issuer_list =
-      GeneratePayOverTimeIssuerList(paydm);
-  EXPECT_THAT(bnpl_issuer_list,
-              UnorderedElementsAre(MatchesBnplIssuer(issuer_affirm)));
-}
-
-IN_PROC_BROWSER_TEST_F(AutofillUtilTestForBnpl,
-                       GeneratePayOverTimeIssuerList_IssuerTosAccepted) {
-  autofill::TestPaymentsDataManager paydm;
-  paydm.SetAutofillWalletImportEnabled(true);
-  paydm.SetAutofillPaymentMethodsEnabled(true);
-  paydm.SetIsAutofillBnplPrefEnabled(true);
-  autofill::BnplIssuer issuer_affirm = autofill::test::GetTestLinkedBnplIssuer(
-      autofill::BnplIssuer::IssuerId::kBnplAffirm);
-  autofill::BnplIssuer issuer_klarna = autofill::test::GetTestLinkedBnplIssuer(
-      autofill::BnplIssuer::IssuerId::kBnplKlarna);
-  paydm.AddBnplIssuer(issuer_affirm);
-  paydm.AddBnplIssuer(issuer_klarna);
-
-  PayOverTimeIssuerEntryList bnpl_issuer_list =
-      GeneratePayOverTimeIssuerList(paydm);
-  EXPECT_THAT(bnpl_issuer_list,
-              UnorderedElementsAre(MatchesBnplIssuer(issuer_affirm),
-                                   MatchesBnplIssuer(issuer_klarna)));
-}
-
 }  // namespace
 
 }  // namespace extensions::autofill_util
diff --git a/chrome/browser/extensions/api/experimental_actor/experimental_actor_api.cc b/chrome/browser/extensions/api/experimental_actor/experimental_actor_api.cc
index dd721d98..5666a2a4 100644
--- a/chrome/browser/extensions/api/experimental_actor/experimental_actor_api.cc
+++ b/chrome/browser/extensions/api/experimental_actor/experimental_actor_api.cc
@@ -265,7 +265,8 @@
       actor::ActorKeyedServiceFactory::GetActorKeyedService(browser_context());
 
   actor_service->GetJournal().Log(
-      GURL(), actor::TaskId(action.task_id()), "ExperimentalActorExecutAction",
+      GURL(), actor::TaskId(action.task_id()),
+      actor::mojom::JournalTrack::kActor, "ExperimentalActorExecutAction",
       absl::StrFormat("Proto: %s", actor::ToBase64(action)));
 
   // BuildToolRequest looks for tab_ids on the individual action structs since
@@ -399,7 +400,8 @@
 
   auto* actor_service = actor::ActorKeyedService::Get(browser_context());
   actor_service->GetJournal().Log(
-      GURL(), actor::TaskId(actions.task_id()), "ExperimentalActorExecutAction",
+      GURL(), actor::TaskId(actions.task_id()),
+      actor::mojom::JournalTrack::kActor, "ExperimentalActorExecutAction",
       absl::StrFormat("Proto: %s", actor::ToBase64(actions)));
 
   actor::TaskId task_id(actions.task_id());
diff --git a/chrome/browser/extensions/policy_handlers.cc b/chrome/browser/extensions/policy_handlers.cc
index 193f718..71775ecd 100644
--- a/chrome/browser/extensions/policy_handlers.cc
+++ b/chrome/browser/extensions/policy_handlers.cc
@@ -155,7 +155,7 @@
     size_t pos = entry_string.find(';');
     if (pos == std::string::npos) {
       extension_id = entry_string;
-      update_url = extension_urls::GetWebstoreUpdateUrl().spec();
+      update_url = extension_urls::kChromeWebstoreUpdateURL;
     } else {
       extension_id = entry_string.substr(0, pos);
       update_url = entry_string.substr(pos + 1);
diff --git a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsMediator.java b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsMediator.java
index c96509d..a96d976 100644
--- a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsMediator.java
+++ b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsMediator.java
@@ -184,13 +184,12 @@
                 screenItems.add(new ListItem(PAYMENT_APP, model));
             }
         }
-
-        screenItems.add(buildEwalletAdditionalInfo(ewallets));
+        screenItems.add(buildPaymentLinkAdditionalInfo(ewallets, apps));
 
         maybeShowContinueButton(screenItems, EWALLET);
 
-        screenItems.add(0, buildEwalletHeader(mContext, ewallets));
-        screenItems.add(buildEwalletFooter(ewallets));
+        screenItems.add(0, buildPaymentLinkHeader(mContext, ewallets, apps));
+        screenItems.add(buildPaymentLinkFooter(ewallets, apps));
 
         mModel.set(SURVIVES_NAVIGATION, false);
         mModel.set(VISIBLE_STATE, SHOWN);
@@ -275,7 +274,8 @@
     }
 
     @VisibleForTesting
-    ListItem buildEwalletHeader(Context context, List<Ewallet> ewallets) {
+    ListItem buildPaymentLinkHeader(
+            Context context, List<Ewallet> ewallets, List<ResolveInfo> apps) {
         // This will contain the shared ewallet name if all eWallets have the same name;
         // otherwise, it will contain `null`.
         Optional<String> sharedEwalletName = Optional.of(ewallets.get(0).getEwalletName());
@@ -337,7 +337,7 @@
                         .build());
     }
 
-    private ListItem buildEwalletFooter(List<Ewallet> ewallets) {
+    private ListItem buildPaymentLinkFooter(List<Ewallet> ewallets, List<ResolveInfo> apps) {
         return new ListItem(
                 FacilitatedPaymentsPaymentMethodsProperties.ItemType.FOOTER,
                 new PropertyModel.Builder(FooterProperties.ALL_KEYS)
@@ -345,7 +345,8 @@
                                 FooterProperties.SHOW_PAYMENT_METHOD_SETTINGS_CALLBACK,
                                 () ->
                                         this.onManagePaymentMethodsOptionSelected(
-                                                getEwalletFopSelectorUserActionHistogram(ewallets)))
+                                                getNonCardPaymentMethodsFopSelectorUserActionHistogram(
+                                                        ewallets, apps)))
                         .build());
     }
 
@@ -368,7 +369,8 @@
     }
 
     @VisibleForTesting
-    ListItem buildEwalletAdditionalInfo(List<Ewallet> ewallets) {
+    ListItem buildPaymentLinkAdditionalInfo(List<Ewallet> ewallets, List<ResolveInfo> apps) {
+
         return new ListItem(
                 FacilitatedPaymentsPaymentMethodsProperties.ItemType.ADDITIONAL_INFO,
                 new PropertyModel.Builder(AdditionalInfoProperties.ALL_KEYS)
@@ -386,7 +388,8 @@
                                         startSettings(FINANCIAL_ACCOUNTS);
                                     }
                                     recordHistogramOnTurnOffPaymentPromptLinkClicked(
-                                            getEwalletFopSelectorUserActionHistogram(ewallets));
+                                            getNonCardPaymentMethodsFopSelectorUserActionHistogram(
+                                                    ewallets, apps));
                                 })
                         .build());
     }
@@ -484,7 +487,9 @@
                 FopSelectorAction.MAX_VALUE);
     }
 
-    private String getEwalletFopSelectorUserActionHistogram(List<Ewallet> ewallets) {
+    // TODO(crbug.com/433617327): unusedApps will be used in a later patch to update the histogram.
+    private String getNonCardPaymentMethodsFopSelectorUserActionHistogram(
+            List<Ewallet> ewallets, List<ResolveInfo> unusedApps) {
         if (ewallets.size() == 1) {
             if (ewallets.get(0).getIsFidoEnrolled()) {
                 return EWALLET_FOP_SELECTOR_USER_ACTION_HISTOGRAM + "SingleBoundEwallet";
diff --git a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsViewTest.java b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsViewTest.java
index 07f1bd7..e3a53e0 100644
--- a/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsViewTest.java
+++ b/chrome/browser/facilitated_payments/ui/android/internal/java/src/org/chromium/chrome/browser/facilitated_payments/FacilitatedPaymentsPaymentMethodsViewTest.java
@@ -397,8 +397,10 @@
                     mModel.get(SCREEN_VIEW_MODEL)
                             .get(SCREEN_ITEMS)
                             .add(
-                                    mMediator.buildEwalletHeader(
-                                            mActivityTestRule.getActivity(), List.of(EWALLET_1)));
+                                    mMediator.buildPaymentLinkHeader(
+                                            mActivityTestRule.getActivity(),
+                                            List.of(EWALLET_1),
+                                            List.of()));
                     mModel.set(VISIBLE_STATE, SHOWN);
                 });
 
@@ -419,8 +421,10 @@
                     mModel.get(SCREEN_VIEW_MODEL)
                             .get(SCREEN_ITEMS)
                             .add(
-                                    mMediator.buildEwalletHeader(
-                                            mActivityTestRule.getActivity(), List.of(EWALLET_3)));
+                                    mMediator.buildPaymentLinkHeader(
+                                            mActivityTestRule.getActivity(),
+                                            List.of(EWALLET_3),
+                                            List.of()));
                     mModel.set(VISIBLE_STATE, SHOWN);
                 });
 
@@ -443,9 +447,10 @@
                     mModel.get(SCREEN_VIEW_MODEL)
                             .get(SCREEN_ITEMS)
                             .add(
-                                    mMediator.buildEwalletHeader(
+                                    mMediator.buildPaymentLinkHeader(
                                             mActivityTestRule.getActivity(),
-                                            List.of(EWALLET_3, EWALLET_4)));
+                                            List.of(EWALLET_3, EWALLET_4),
+                                            List.of()));
                     mModel.set(VISIBLE_STATE, SHOWN);
                 });
 
@@ -485,7 +490,9 @@
                     mModel.set(SCREEN, FOP_SELECTOR);
                     mModel.get(SCREEN_VIEW_MODEL)
                             .get(SCREEN_ITEMS)
-                            .add(mMediator.buildEwalletAdditionalInfo(List.of(EWALLET_1)));
+                            .add(
+                                    mMediator.buildPaymentLinkAdditionalInfo(
+                                            List.of(EWALLET_1), List.of()));
                     mModel.set(VISIBLE_STATE, SHOWN);
                 });
         BottomSheetTestSupport.waitForOpen(mBottomSheetController);
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index c3ed28f..9716185 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -10313,6 +10313,11 @@
     "expiry_milestone": 145
   },
   {
+    "name": "webium",
+    "owners": [ "robliao@chromium.org", "kerenzhu@chromium.org" ],
+    "expiry_milestone": 146
+  },
+  {
     "name": "webnn-coreml",
     "owners": [ "reillyg@chromium.org", "phillis@chromium.org" ],
     "expiry_milestone": 146
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 79838a6..ec68a520 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -4325,6 +4325,11 @@
     "persistent storage of device permissions and Web Bluetooth features such "
     "as BluetoothDevice.watchAdvertisements() and Bluetooth.getDevices()";
 
+#if !BUILDFLAG(IS_ANDROID)
+const char kWebiumName[] = "Webium";
+const char kWebiumDescription[] = "Webium Prototype Browser.";
+#endif  // !BUILDFLAG(IS_ANDROID)
+
 const char kWebOtpBackendName[] = "Web OTP";
 const char kWebOtpBackendDescription[] =
     "Enables Web OTP API that uses the specified backend.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index b36aa1c..36b281f9 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -2493,6 +2493,11 @@
 extern const char kWebBluetoothNewPermissionsBackendName[];
 extern const char kWebBluetoothNewPermissionsBackendDescription[];
 
+#if !BUILDFLAG(IS_ANDROID)
+extern const char kWebiumName[];
+extern const char kWebiumDescription[];
+#endif  // !BUILDFLAG(IS_ANDROID)
+
 extern const char kWebOtpBackendName[];
 extern const char kWebOtpBackendDescription[];
 extern const char kWebOtpBackendSmsVerification[];
diff --git a/chrome/browser/glic/glic_keyed_service.cc b/chrome/browser/glic/glic_keyed_service.cc
index 36a14941..dd79ea6 100644
--- a/chrome/browser/glic/glic_keyed_service.cc
+++ b/chrome/browser/glic/glic_keyed_service.cc
@@ -387,7 +387,8 @@
 
   auto* actor_service = actor::ActorKeyedService::Get(profile_);
   actor_service->GetJournal().Log(
-      GURL(), actor::TaskId(actions.task_id()), "GlicPerformActions",
+      GURL(), actor::TaskId(actions.task_id()),
+      actor::mojom::JournalTrack::kActor, "GlicPerformActions",
       absl::StrFormat("Proto: %s", actor::ToBase64(actions)));
 
   if (!actions.has_task_id()) {
@@ -401,7 +402,8 @@
   actor::BuildToolRequestResult requests = actor::BuildToolRequest(actions);
   if (!requests.has_value()) {
     actor_service->GetJournal().Log(
-        GURL::EmptyGURL(), task_id, "Act Failed",
+        GURL::EmptyGURL(), task_id, actor::mojom::JournalTrack::kActor,
+        "Act Failed",
         absl::StrFormat("Failed to convert proto::Actions[%d] to ToolRequest",
                         requests.error()));
     optimization_guide::proto::ActionsResult response =
@@ -462,33 +464,6 @@
   actor_controller_->ResumeTask(task_id, context_options, std::move(callback));
 }
 
-void GlicKeyedService::OnUserInputSubmitted(glic::mojom::WebClientMode mode) {
-  metrics_->OnUserInputSubmitted(mode);
-  if (actor_controller_) {
-    actor_controller_->OnUserInputSubmitted();
-  }
-}
-
-void GlicKeyedService::OnRequestStarted() {
-  if (actor_controller_) {
-    actor_controller_->OnRequestStarted();
-  }
-}
-
-void GlicKeyedService::OnResponseStarted() {
-  metrics_->OnResponseStarted();
-  if (actor_controller_) {
-    actor_controller_->OnResponseStarted();
-  }
-}
-
-void GlicKeyedService::OnResponseStopped() {
-  metrics_->OnResponseStopped();
-  if (actor_controller_) {
-    actor_controller_->OnResponseStopped();
-  }
-}
-
 void GlicKeyedService::CaptureScreenshot(
     mojom::WebClientHandler::CaptureScreenshotCallback callback) {
   screenshot_capturer_->CaptureScreenshot(
diff --git a/chrome/browser/glic/glic_keyed_service.h b/chrome/browser/glic/glic_keyed_service.h
index 9a2828c..246b833 100644
--- a/chrome/browser/glic/glic_keyed_service.h
+++ b/chrome/browser/glic/glic_keyed_service.h
@@ -172,11 +172,6 @@
       const mojom::GetTabContextOptions& context_options,
       glic::mojom::WebClientHandler::ResumeActorTaskCallback callback);
 
-  void OnUserInputSubmitted(glic::mojom::WebClientMode mode);
-  void OnRequestStarted();
-  void OnResponseStarted();
-  void OnResponseStopped();
-
   void CaptureScreenshot(
       glic::mojom::WebClientHandler::CaptureScreenshotCallback callback);
 
diff --git a/chrome/browser/glic/glic_net_log_browsertest.cc b/chrome/browser/glic/glic_net_log_browsertest.cc
index ff39edd..d9a5262 100644
--- a/chrome/browser/glic/glic_net_log_browsertest.cc
+++ b/chrome/browser/glic/glic_net_log_browsertest.cc
@@ -79,11 +79,11 @@
                COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("glic_fre_web_ui");
   });
 
-  EXPECT_NE(it, entries.end())
+  ASSERT_NE(it, entries.end())
       << "NetLog did not contain URL_REQUEST_START_JOB for Glic FRE WeUI";
   EXPECT_EQ(true, it->params.FindBool("dummy_request"));
   const std::string* url = it->params.FindString("url");
-  EXPECT_NE(nullptr, url);
+  ASSERT_TRUE(url);
   EXPECT_THAT(*url, testing::StartsWith(kTestGlicFreURL));
 }
 
@@ -115,11 +115,11 @@
                COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH("glic_web_ui");
   });
 
-  EXPECT_NE(it, entries.end())
+  ASSERT_NE(it, entries.end())
       << "NetLog did not contain URL_REQUEST_START_JOB for Glic WebUI";
   EXPECT_EQ(true, it->params.FindBool("dummy_request"));
   const std::string* url = it->params.FindString("url");
-  EXPECT_NE(nullptr, url);
+  ASSERT_TRUE(url);
   EXPECT_THAT(*url, testing::StartsWith(kTestGlicURL));
 }
 
diff --git a/chrome/browser/glic/host/glic.mojom b/chrome/browser/glic/host/glic.mojom
index 3a8c21f..3d5e4aa 100644
--- a/chrome/browser/glic/host/glic.mojom
+++ b/chrome/browser/glic/host/glic.mojom
@@ -699,9 +699,6 @@
   // Called when the user submits input.
   OnUserInputSubmitted(WebClientMode mode);
 
-  // Called when the web client starts a request.
-  OnRequestStarted();
-
   // Called when the web client starts to respond.
   OnResponseStarted();
 
diff --git a/chrome/browser/glic/host/glic_actor_controller.cc b/chrome/browser/glic/host/glic_actor_controller.cc
index fcab1bb9..225c1f3d 100644
--- a/chrome/browser/glic/host/glic_actor_controller.cc
+++ b/chrome/browser/glic/host/glic_actor_controller.cc
@@ -118,13 +118,6 @@
 
 }  // namespace
 
-// A wrapper class around actor::AggregatedJournal::PendingAsyncEntry for
-// dependency purposes.
-class GlicActorController::OngoingRequest {
- public:
-  std::unique_ptr<actor::AggregatedJournal::PendingAsyncEntry> journal_entry_;
-};
-
 GlicActorController::GlicActorController(Profile* profile) : profile_(profile) {
   CHECK(profile_);
   actor::ExecutionEngine::RegisterWithProfile(profile_);
@@ -140,7 +133,8 @@
   CHECK(actor_service);
 
   actor_service->GetJournal().Log(
-      GURL(), TaskId(action.task_id()), "GlicActInFocusedTab",
+      GURL(), TaskId(action.task_id()), actor::mojom::JournalTrack::kActor,
+      "GlicActInFocusedTab",
       absl::StrFormat("Proto: %s", actor::ToBase64(action)));
 
   actor::BuildToolRequestResult result =
@@ -148,7 +142,8 @@
 
   if (!result.has_value()) {
     actor::ActorKeyedService::Get(profile_)->GetJournal().Log(
-        /*url=*/GURL(), actor::TaskId(), "ActImpl",
+        /*url=*/GURL(), actor::TaskId(), actor::mojom::JournalTrack::kActor,
+        "ActImpl",
         absl::StrFormat("Invalid BrowserAction proto[%d]", result.error()));
     PostTaskForActCallback(
         std::move(callback),
@@ -179,7 +174,8 @@
 
     if (!will_observe_tab) {
       actor_service->GetJournal().Log(
-          /*url=*/GURL(), task->id(), "[Warning] No observable tab",
+          /*url=*/GURL(), task->id(), actor::mojom::JournalTrack::kActor,
+          "[Warning] No observable tab",
           "Action will end without an observable tab, adding active tab.");
 
       // Get the most recently active browser for this profile.
@@ -246,38 +242,6 @@
                          std::move(callback));
 }
 
-void GlicActorController::OnUserInputSubmitted() {
-  current_request_ = std::make_unique<OngoingRequest>();
-  current_request_->journal_entry_ =
-      actor::ActorKeyedService::Get(profile_.get())
-          ->GetJournal()
-          .CreatePendingAsyncEntry(/*url=*/GURL::EmptyGURL(), actor::TaskId(),
-                                   "Request", /*details=*/"User Input");
-}
-
-void GlicActorController::OnRequestStarted() {
-  auto& journal = actor::ActorKeyedService::Get(profile_.get())->GetJournal();
-
-  if (!current_request_) {
-    current_request_ = std::make_unique<OngoingRequest>();
-    current_request_->journal_entry_ = journal.CreatePendingAsyncEntry(
-        /*url=*/GURL::EmptyGURL(), actor::TaskId(), "Request",
-        /*details=*/"Multi-turn");
-  } else {
-    journal.Log(/*url=*/GURL(), actor::TaskId(), "Request", "Request Started");
-  }
-}
-
-void GlicActorController::OnResponseStarted() {
-  actor::ActorKeyedService::Get(profile_.get())
-      ->GetJournal()
-      .Log(/*url=*/GURL(), actor::TaskId(), "Request", "Response Started");
-}
-
-void GlicActorController::OnResponseStopped() {
-  current_request_.reset();
-}
-
 void GlicActorController::OnActionFinished(
     actor::TaskId task_id,
     const mojom::GetTabContextOptions& options,
@@ -298,7 +262,7 @@
   actor::AggregatedJournal& journal =
       actor::ActorKeyedService::Get(profile_)->GetJournal();
   if (task->GetTabs().size() != 1) {
-    journal.Log(GURL::EmptyGURL(), task_id,
+    journal.Log(GURL::EmptyGURL(), task_id, actor::mojom::JournalTrack::kActor,
                 "[Warning] Unexpected number of tabs",
                 absl::StrFormat("Expect 1 observable tab but have [%d]",
                                 task->GetTabs().size()));
@@ -314,7 +278,7 @@
   if (tab) {
     const GURL& url = tab->GetContents()->GetLastCommittedURL();
     auto journal_entry = journal.CreatePendingAsyncEntry(
-        url, task_id, "FetchPageContext",
+        url, task_id, actor::mojom::JournalTrack::kActor, "FetchPageContext",
         "TabHandle:" + base::ToString(tab->GetHandle()));
 
     FetchPageContext(tab, *ActionableOptions(options),
@@ -323,7 +287,8 @@
                                     std::move(callback),
                                     task->GetExecutionEngine()->GetWeakPtr()));
   } else {
-    journal.Log(GURL::EmptyGURL(), task_id, "FetchPageContext", "Tab is gone");
+    journal.Log(GURL::EmptyGURL(), task_id, actor::mojom::JournalTrack::kActor,
+                "FetchPageContext", "Tab is gone");
     PostTaskForActCallback(std::move(callback),
                            mojom::ActInFocusedTabErrorReason::kTargetNotFound);
   }
diff --git a/chrome/browser/glic/host/glic_actor_controller.h b/chrome/browser/glic/host/glic_actor_controller.h
index 23ab45b..11a9d4e 100644
--- a/chrome/browser/glic/host/glic_actor_controller.h
+++ b/chrome/browser/glic/host/glic_actor_controller.h
@@ -47,13 +47,6 @@
       const mojom::GetTabContextOptions& context_options,
       glic::mojom::WebClientHandler::ResumeActorTaskCallback callback);
 
-  // These may not be necessarily generate actor tasks, but they are
-  // useful for recording in the ActorJournal.
-  void OnUserInputSubmitted();
-  void OnRequestStarted();
-  void OnResponseStarted();
-  void OnResponseStopped();
-
   // TODO(crbug.com/418280472): This temporarily gates providing observations
   // after action failure, to avoid confusing the client before it's updated.
   static bool ProvideObservationOnActionFailureEnabled();
@@ -72,10 +65,7 @@
   base::WeakPtr<const GlicActorController> GetWeakPtr() const;
   base::WeakPtr<GlicActorController> GetWeakPtr();
 
-  class OngoingRequest;
-
   raw_ptr<Profile> profile_;
-  std::unique_ptr<OngoingRequest> current_request_;
   base::WeakPtrFactory<GlicActorController> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/browser/glic/host/glic_page_handler.cc b/chrome/browser/glic/host/glic_page_handler.cc
index e59794c..ce27c67e 100644
--- a/chrome/browser/glic/host/glic_page_handler.cc
+++ b/chrome/browser/glic/host/glic_page_handler.cc
@@ -326,7 +326,8 @@
 
     active_journal_events_[event_async_id] =
         actor_keyed_service_->GetJournal().CreatePendingAsyncEntry(
-            /*url=*/GURL::EmptyGURL(), actor::TaskId(task_id), event, details);
+            /*url=*/GURL::EmptyGURL(), actor::TaskId(task_id),
+            actor::mojom::JournalTrack::kFrontEnd, event, details);
   }
 
   void LogEndAsyncEvent(uint64_t event_async_id, const std::string& details) {
@@ -341,7 +342,8 @@
                        const std::string& event,
                        const std::string& details) {
     actor_keyed_service_->GetJournal().Log(
-        /*url=*/GURL::EmptyGURL(), actor::TaskId(task_id), event, details);
+        /*url=*/GURL::EmptyGURL(), actor::TaskId(task_id),
+        actor::mojom::JournalTrack::kFrontEnd, event, details);
   }
 
   void Clear() {
@@ -1065,14 +1067,16 @@
   }
 
   void OnUserInputSubmitted(glic::mojom::WebClientMode mode) override {
-    glic_service_->OnUserInputSubmitted(mode);
+    glic_service_->metrics()->OnUserInputSubmitted(mode);
   }
 
-  void OnRequestStarted() override { glic_service_->OnRequestStarted(); }
+  void OnResponseStarted() override {
+    glic_service_->metrics()->OnResponseStarted();
+  }
 
-  void OnResponseStarted() override { glic_service_->OnResponseStarted(); }
-
-  void OnResponseStopped() override { glic_service_->OnResponseStopped(); }
+  void OnResponseStopped() override {
+    glic_service_->metrics()->OnResponseStopped();
+  }
 
   void OnSessionTerminated() override {
     glic_service_->metrics()->OnSessionTerminated();
diff --git a/chrome/browser/keyboard_accessory/android/accessory_sheet_enums.h b/chrome/browser/keyboard_accessory/android/accessory_sheet_enums.h
index 5b0e6e87..9715657 100644
--- a/chrome/browser/keyboard_accessory/android/accessory_sheet_enums.h
+++ b/chrome/browser/keyboard_accessory/android/accessory_sheet_enums.h
@@ -93,6 +93,7 @@
   MANAGE_PLUS_ADDRESS_FROM_PASSWORD_SHEET = 15,
   MANAGE_LOYALTY_CARDS = 16,
   RETRIEVE_TRUSTED_VAULT_KEY = 17,
+  AUTOFILL_SUGGESTION_FROM_ACCESSORY_SHEET = 18,
   COUNT,
 };
 // LINT.ThenChange(/tools/metrics/histograms/metadata/password/enums.xml)
diff --git a/chrome/browser/keyboard_accessory/android/manual_filling_controller_impl.cc b/chrome/browser/keyboard_accessory/android/manual_filling_controller_impl.cc
index 1cf9730..83e9bdb3 100644
--- a/chrome/browser/keyboard_accessory/android/manual_filling_controller_impl.cc
+++ b/chrome/browser/keyboard_accessory/android/manual_filling_controller_impl.cc
@@ -460,6 +460,7 @@
     case AccessoryAction::MANAGE_LOYALTY_CARDS:
       return payment_method_controller_.get();
     case AccessoryAction::AUTOFILL_SUGGESTION:
+    case AccessoryAction::AUTOFILL_SUGGESTION_FROM_ACCESSORY_SHEET:
     case AccessoryAction::COUNT:
       NOTREACHED() << "Controller not defined for action: "
                    << static_cast<int>(action);
diff --git a/chrome/browser/loader/keep_alive_category_request_browsertest.cc b/chrome/browser/loader/keep_alive_category_request_browsertest.cc
index 52e43e11..d7579b5 100644
--- a/chrome/browser/loader/keep_alive_category_request_browsertest.cc
+++ b/chrome/browser/loader/keep_alive_category_request_browsertest.cc
@@ -163,6 +163,7 @@
       content::KeepAliveRequestTracker::RequestType::kFetch,
       /*category_id=*/1,
       /*num_redirects=*/0,
+      /*num_retries=*/0,
       /*is_context_detached=*/false,
       content::KeepAliveRequestTracker::RequestStageType::kLoaderCompleted,
       content::KeepAliveRequestTracker::RequestStageType::kResponseReceived,
@@ -196,6 +197,7 @@
       content::KeepAliveRequestTracker::RequestType::kFetch,
       /*category_id=*/1,
       /*num_redirects=*/0,
+      /*num_retries=*/0,
       /*is_context_detached=*/true,
       content::KeepAliveRequestTracker::RequestStageType::kResponseReceived,
       content::KeepAliveRequestTracker::RequestStageType::
@@ -243,6 +245,7 @@
       content::KeepAliveRequestTracker::RequestType::kFetch,
       /*category_id=*/1,
       /*num_redirects=*/0,
+      /*num_retries=*/0,
       /*is_context_detached=*/false,
       content::KeepAliveRequestTracker::RequestStageType::kLoaderCompleted,
       content::KeepAliveRequestTracker::RequestStageType::kResponseReceived,
@@ -291,6 +294,7 @@
       content::KeepAliveRequestTracker::RequestType::kFetch,
       /*category_id=*/1,
       /*num_redirects=*/1,
+      /*num_retries=*/0,
       /*is_context_detached=*/true,
       content::KeepAliveRequestTracker::RequestStageType::kResponseReceived,
       content::KeepAliveRequestTracker::RequestStageType::
@@ -360,6 +364,7 @@
       content::KeepAliveRequestTracker::RequestType::kFetch,
       /*category_id=*/1,
       /*num_redirects=*/0,
+      /*num_retries=*/0,
       /*is_context_detached=*/false,
       content::KeepAliveRequestTracker::RequestStageType::kLoaderCompleted,
       content::KeepAliveRequestTracker::RequestStageType::kResponseReceived,
@@ -402,6 +407,7 @@
       content::KeepAliveRequestTracker::RequestType::kFetch,
       /*category_id=*/1,
       /*num_redirects=*/0,
+      /*num_retries=*/0,
       /*is_context_detached=*/false,
       content::KeepAliveRequestTracker::RequestStageType::kLoaderCompleted,
       content::KeepAliveRequestTracker::RequestStageType::kResponseReceived,
@@ -453,6 +459,7 @@
       {{content::KeepAliveRequestTracker::RequestType::kFetch,
         /*category_id=*/1,
         /*num_redirects=*/0,
+        /*num_retries=*/0,
         /*is_context_detached=*/false,
         content::KeepAliveRequestTracker::RequestStageType::kLoaderCompleted,
         content::KeepAliveRequestTracker::RequestStageType::kResponseReceived,
@@ -464,6 +471,7 @@
        {content::KeepAliveRequestTracker::RequestType::kFetch,
         /*category_id=*/2,
         /*num_redirects=*/0,
+        /*num_retries=*/0,
         /*is_context_detached=*/false,
         content::KeepAliveRequestTracker::RequestStageType::kLoaderCompleted,
         content::KeepAliveRequestTracker::RequestStageType::kResponseReceived,
@@ -511,6 +519,7 @@
       {{content::KeepAliveRequestTracker::RequestType::kFetch,
         /*category_id=*/1,
         /*num_redirects=*/0,
+        /*num_retries=*/0,
         /*is_context_detached=*/false,
         content::KeepAliveRequestTracker::RequestStageType::kLoaderCompleted,
         content::KeepAliveRequestTracker::RequestStageType::kResponseReceived,
@@ -522,6 +531,7 @@
        {content::KeepAliveRequestTracker::RequestType::kFetch,
         /*category_id=*/1,
         /*num_redirects=*/0,
+        /*num_retries=*/0,
         /*is_context_detached=*/false,
         content::KeepAliveRequestTracker::RequestStageType::kLoaderCompleted,
         content::KeepAliveRequestTracker::RequestStageType::kResponseReceived,
@@ -562,6 +572,7 @@
       content::KeepAliveRequestTracker::RequestType::kFetch,
       /*category_id=*/1,
       /*num_redirects=*/0,
+      /*num_retries=*/0,
       /*is_context_detached=*/false,
       content::KeepAliveRequestTracker::RequestStageType::kLoaderCompleted,
       content::KeepAliveRequestTracker::RequestStageType::kResponseReceived,
@@ -608,6 +619,7 @@
       content::KeepAliveRequestTracker::RequestType::kFetch,
       /*category_id=*/2,
       /*num_redirects=*/0,
+      /*num_retries=*/0,
       /*is_context_detached=*/false,
       content::KeepAliveRequestTracker::RequestStageType::kLoaderCompleted,
       content::KeepAliveRequestTracker::RequestStageType::kResponseReceived,
@@ -663,6 +675,7 @@
       {{content::KeepAliveRequestTracker::RequestType::kFetch,
         /*category_id=*/1,
         /*num_redirects=*/0,
+        /*num_retries=*/0,
         /*is_context_detached=*/false,
         content::KeepAliveRequestTracker::RequestStageType::kLoaderCompleted,
         content::KeepAliveRequestTracker::RequestStageType::kResponseReceived,
@@ -674,6 +687,7 @@
        {content::KeepAliveRequestTracker::RequestType::kFetch,
         /*category_id=*/2,
         /*num_redirects=*/0,
+        /*num_retries=*/0,
         /*is_context_detached=*/false,
         content::KeepAliveRequestTracker::RequestStageType::kLoaderCompleted,
         content::KeepAliveRequestTracker::RequestStageType::kResponseReceived,
@@ -715,6 +729,7 @@
       content::KeepAliveRequestTracker::RequestType::kFetch,
       /*category_id=*/1,
       /*num_redirects=*/0,
+      /*num_retries=*/0,
       /*is_context_detached=*/false,
       content::KeepAliveRequestTracker::RequestStageType::kLoaderCompleted,
       content::KeepAliveRequestTracker::RequestStageType::kResponseReceived,
diff --git a/chrome/browser/loader/keep_alive_request_tracker.cc b/chrome/browser/loader/keep_alive_request_tracker.cc
index 90ddf4d6..12fbb19 100644
--- a/chrome/browser/loader/keep_alive_request_tracker.cc
+++ b/chrome/browser/loader/keep_alive_request_tracker.cc
@@ -28,6 +28,8 @@
 // This is unlikely to reach as the maximum is 20 per spec
 // https://fetch.spec.whatwg.org/#http-redirect-fetch
 constexpr size_t kMaxNonBucketedNumRedirects = 20;
+// See also `kMaxRetryCount` in content/browser/loader/keep_alive_url_loader.cc.
+constexpr size_t kMaxNonBucketedNumRetries = 10;
 
 ChromeKeepAliveRequestTracker::RequestType ComputeRequestType(
     const network::ResourceRequest& request) {
@@ -176,6 +178,15 @@
       ukm_builder_.SetLoaderCompleted_ExtendedErrorCode(
           stage.status->extended_error_code);
       break;
+
+    case RequestStageType::kRequestRetried:
+      IncreaseNumRetries();
+      ukm_builder_.SetTimeDelta_RequestRetried(
+          relative_to_created_time.InMilliseconds());
+      ukm_builder_.SetRequestRetried_ErrorCode(stage.status->error_code);
+      ukm_builder_.SetRequestRetried_ExtendedErrorCode(
+          stage.status->extended_error_code);
+      break;
   }
 }
 
@@ -189,6 +200,11 @@
       num_redirects <= kMaxNonBucketedNumRedirects
           ? num_redirects
           : ukm::GetExponentialBucketMinForCounts1000(num_redirects));
+  uint32_t num_retries = GetNumRetries();
+  ukm_builder_.SetNumRetries(
+      num_retries <= kMaxNonBucketedNumRetries
+          ? num_retries
+          : ukm::GetExponentialBucketMinForCounts1000(num_retries));
   ukm_builder_.SetIsContextDetached(is_context_detached_callback_.Run());
   ukm_builder_.SetTimeDelta_EventLogged(
       (base::TimeTicks::Now() - created_time_).InMilliseconds());
diff --git a/chrome/browser/loader/keep_alive_request_tracker_unittest.cc b/chrome/browser/loader/keep_alive_request_tracker_unittest.cc
index d3ebd1c..e760e6e 100644
--- a/chrome/browser/loader/keep_alive_request_tracker_unittest.cc
+++ b/chrome/browser/loader/keep_alive_request_tracker_unittest.cc
@@ -233,6 +233,7 @@
   ExpectCommonUkm(GetParam().request_type,
                   /*category_id=*/10,
                   /*num_redirects=*/0,
+                  /*num_retries=*/0,
                   /*is_context_detached=*/false,
                   RequestStageType::kLoaderCreated,
                   /*previous_stage=*/std::nullopt, *request.keepalive_token);
@@ -252,6 +253,7 @@
   ExpectCommonUkm(GetParam().request_type,
                   /*category_id=*/20,
                   /*num_redirects=*/0,
+                  /*num_retries=*/0,
                   /*is_context_detached=*/false,
                   RequestStageType::kRequestStarted,
                   RequestStageType::kLoaderCreated, *request.keepalive_token);
@@ -274,6 +276,7 @@
   ExpectCommonUkm(GetParam().request_type,
                   /*category_id=*/30,
                   /*num_redirects=*/1,
+                  /*num_retries=*/0,
                   /*is_context_detached=*/false,
                   RequestStageType::kFirstRedirectReceived,
                   RequestStageType::kRequestStarted, *request.keepalive_token);
@@ -300,6 +303,7 @@
       GetParam().request_type,
       /*category_id=*/40,
       /*num_redirects=*/2,
+      /*num_retries=*/0,
       /*is_context_detached=*/false, RequestStageType::kSecondRedirectReceived,
       RequestStageType::kFirstRedirectReceived, *request.keepalive_token);
   ExpectTimeSortedTimeDeltaUkm(
@@ -327,6 +331,7 @@
   ExpectCommonUkm(GetParam().request_type,
                   /*category_id=*/50,
                   /*num_redirects=*/3,
+                  /*num_retries=*/0,
                   /*is_context_detached=*/false,
                   RequestStageType::kThirdOrLaterRedirectReceived,
                   RequestStageType::kSecondRedirectReceived,
@@ -352,6 +357,7 @@
   ExpectCommonUkm(GetParam().request_type,
                   /*category_id=*/60,
                   /*num_redirects=*/0,
+                  /*num_retries=*/0,
                   /*is_context_detached=*/false,
                   RequestStageType::kResponseReceived,
                   RequestStageType::kRequestStarted, *request.keepalive_token);
@@ -380,6 +386,7 @@
       GetParam().request_type,
       /*category_id=*/70,
       /*num_redirects=*/2,
+      /*num_retries=*/0,
       /*is_context_detached=*/false, RequestStageType::kResponseReceived,
       RequestStageType::kSecondRedirectReceived, *request.keepalive_token);
   ExpectTimeSortedTimeDeltaUkm(
@@ -407,6 +414,7 @@
   ExpectCommonUkm(GetParam().request_type,
                   /*category_id=*/80,
                   /*num_redirects=*/0,
+                  /*num_retries=*/0,
                   /*is_context_detached=*/false,
                   RequestStageType::kRequestFailed,
                   RequestStageType::kRequestStarted, *request.keepalive_token,
@@ -435,6 +443,7 @@
   ExpectCommonUkm(GetParam().request_type,
                   /*category_id=*/90,
                   /*num_redirects=*/0,
+                  /*num_retries=*/0,
                   /*is_context_detached=*/false,
                   RequestStageType::kLoaderCompleted,
                   RequestStageType::kResponseReceived, *request.keepalive_token,
@@ -465,6 +474,7 @@
   ExpectCommonUkm(GetParam().request_type,
                   /*category_id=*/100,
                   /*num_redirects=*/0,
+                  /*num_retries=*/0,
                   /*is_context_detached=*/false,
                   RequestStageType::kLoaderCompleted,
                   RequestStageType::kRequestStarted, *request.keepalive_token,
@@ -477,4 +487,86 @@
        "TimeDelta.EventLogged"});
 }
 
+TEST_P(ChromeKeepAliveRequestTrackerTest, RequestRetriedAfterRequestFailed) {
+  auto request = CreateRequest(GetUrlWithCategory("test-prefix110"));
+  auto failed_status = CreateCompletionStatus(/*error_code=*/net::ERR_TIMED_OUT,
+                                              /*extended_error_code=*/1);
+  auto retried_status =
+      CreateCompletionStatus(/*error_code=*/net::ERR_TIMED_OUT,
+                             /*extended_error_code=*/1);
+
+  {
+    auto tracker = CreateTracker(request);
+    ASSERT_THAT(tracker, NotNull());
+    FastForwardBy(one_time_step());
+    tracker->AdvanceToNextStage(RequestStageType::kRequestStarted);
+    FastForwardBy(one_time_step());
+    tracker->AdvanceToNextStage(RequestStageType::kRequestFailed,
+                                failed_status);
+    FastForwardBy(one_time_step());
+    tracker->AdvanceToNextStage(RequestStageType::kRequestRetried,
+                                retried_status);
+  }
+
+  ExpectCommonUkm(
+      GetParam().request_type,
+      /*category_id=*/110,
+      /*num_redirects=*/0,
+      /*num_retries=*/1,
+      /*is_context_detached=*/false, RequestStageType::kRequestRetried,
+      RequestStageType::kRequestFailed, *request.keepalive_token,
+      /*failed_error_code=*/failed_status.error_code,
+      /*failed_extended_error_code=*/failed_status.extended_error_code,
+      /*completed_error_code=*/std::nullopt,
+      /*completed_extended_error_code=*/std::nullopt,
+      /*retried_error_code=*/retried_status.error_code,
+      /*retried_extended_error_code=*/retried_status.extended_error_code);
+  ExpectTimeSortedTimeDeltaUkm(
+      {"TimeDelta.RequestStarted", "TimeDelta.RequestFailed",
+       "TimeDelta.RequestRetried", "TimeDelta.EventLogged"});
+}
+
+TEST_P(ChromeKeepAliveRequestTrackerTest, RequestRetriedAfterTwoRedirects) {
+  auto request = CreateRequest(GetUrlWithCategory("test-prefix120"));
+  auto failed_status = CreateCompletionStatus(/*error_code=*/net::ERR_FAILED,
+                                              /*extended_error_code=*/2);
+  auto retried_status = CreateCompletionStatus(/*error_code=*/net::ERR_FAILED,
+                                               /*extended_error_code=*/2);
+
+  {
+    auto tracker = CreateTracker(request);
+    ASSERT_THAT(tracker, NotNull());
+    FastForwardBy(one_time_step());
+    tracker->AdvanceToNextStage(RequestStageType::kRequestStarted);
+    FastForwardBy(one_time_step());
+    tracker->AdvanceToNextStage(RequestStageType::kFirstRedirectReceived);
+    FastForwardBy(one_time_step());
+    tracker->AdvanceToNextStage(RequestStageType::kSecondRedirectReceived);
+    FastForwardBy(one_time_step());
+    tracker->AdvanceToNextStage(RequestStageType::kRequestFailed,
+                                failed_status);
+    FastForwardBy(one_time_step());
+    tracker->AdvanceToNextStage(RequestStageType::kRequestRetried,
+                                retried_status);
+  }
+
+  ExpectCommonUkm(
+      GetParam().request_type,
+      /*category_id=*/120,
+      /*num_redirects=*/2,
+      /*num_retries=*/1,
+      /*is_context_detached=*/false, RequestStageType::kRequestRetried,
+      RequestStageType::kRequestFailed, *request.keepalive_token,
+      /*failed_error_code=*/failed_status.error_code,
+      /*failed_extended_error_code=*/failed_status.extended_error_code,
+      /*completed_error_code=*/std::nullopt,
+      /*completed_extended_error_code=*/std::nullopt,
+      /*retried_error_code=*/retried_status.error_code,
+      /*retried_extended_error_code=*/retried_status.extended_error_code);
+  ExpectTimeSortedTimeDeltaUkm(
+      {"TimeDelta.RequestStarted", "TimeDelta.FirstRedirectReceived",
+       "TimeDelta.SecondRedirectReceived", "TimeDelta.RequestFailed",
+       "TimeDelta.RequestRetried", "TimeDelta.EventLogged"});
+}
+
 }  // namespace
diff --git a/chrome/browser/net/cert_verifier_service_browsertest.cc b/chrome/browser/net/cert_verifier_service_browsertest.cc
index 396846a9..8620930 100644
--- a/chrome/browser/net/cert_verifier_service_browsertest.cc
+++ b/chrome/browser/net/cert_verifier_service_browsertest.cc
@@ -23,6 +23,7 @@
 #include "net/base/features.h"
 #include "net/base/ip_address.h"
 #include "net/cert/internal/trust_store_chrome.h"
+#include "net/cert/root_store_proto_lite/root_store.pb.h"
 #include "net/cert/test_root_certs.h"
 #include "net/cert/x509_util.h"
 #include "net/dns/mock_host_resolver.h"
diff --git a/chrome/browser/net/profile_network_context_service.cc b/chrome/browser/net/profile_network_context_service.cc
index 2cdab916..a4d22cf 100644
--- a/chrome/browser/net/profile_network_context_service.cc
+++ b/chrome/browser/net/profile_network_context_service.cc
@@ -23,6 +23,7 @@
 #include "base/metrics/field_trial_params.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/notreached.h"
+#include "base/strings/strcat.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/string_view_util.h"
@@ -85,6 +86,7 @@
 #include "net/base/features.h"
 #include "net/cert/asn1_util.h"
 #include "net/disk_cache/backend_experiment.h"
+#include "net/disk_cache/buildflags.h"
 #include "net/http/http_auth_preferences.h"
 #include "net/http/http_util.h"
 #include "net/net_buildflags.h"
@@ -407,6 +409,85 @@
                            !net::features::kIpPrivacyOnlyInIncognito.Get());
 }
 
+constexpr std::string_view kDiskCacheExperimentNameSeparator = " ";
+constexpr std::string_view kDiskCacheExperimentNameNone = "None";
+// The date and prefix for the disk cache backend experiment.
+#define DISK_CACHE_EXPERIMENT_DATE_PREFIX "20250725-DiskCache-"
+constexpr std::string_view kDiskCacheExperimentNameDefault =
+    DISK_CACHE_EXPERIMENT_DATE_PREFIX "Default";
+constexpr std::string_view kDiskCacheExperimentNameSimple =
+    DISK_CACHE_EXPERIMENT_DATE_PREFIX "Simple";
+constexpr std::string_view kDiskCacheExperimentNameBlockfile =
+    DISK_CACHE_EXPERIMENT_DATE_PREFIX "Blockfile";
+#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
+constexpr std::string_view kDiskCacheExperimentNameSql =
+    DISK_CACHE_EXPERIMENT_DATE_PREFIX "Sql";
+#endif  // ENABLE_DISK_CACHE_SQL_BACKEND
+
+std::string_view GetDiskCacheBackendExperimentString() {
+  if (!disk_cache::InBackendExperiment()) {
+    return "";
+  }
+  switch (net::features::kDiskCacheBackendParam.Get()) {
+    case net::features::DiskCacheBackend::kDefault:
+      return kDiskCacheExperimentNameDefault;
+    case net::features::DiskCacheBackend::kSimple:
+      return kDiskCacheExperimentNameSimple;
+    case net::features::DiskCacheBackend::kBlockfile:
+      return kDiskCacheExperimentNameBlockfile;
+#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
+    case net::features::DiskCacheBackend::kSql:
+      return kDiskCacheExperimentNameSql;
+#endif  // ENABLE_DISK_CACHE_SQL_BACKEND
+  }
+  NOTREACHED();
+}
+
+bool GetHttpCacheBackendResetParam(PrefService* local_state) {
+  // Get the field trial groups.  If the server cannot be reached, then
+  // this corresponds to "None" for each experiment.
+  base::FieldTrial* isolation_key_field_trial =
+      base::FeatureList::GetFieldTrial(
+          net::features::kSplitCacheByNetworkIsolationKey);
+  base::FieldTrial* credentials_field_trial = base::FeatureList::GetFieldTrial(
+      net::features::kSplitCacheByIncludeCredentials);
+
+  std::vector<std::string_view> experiment_parts;
+  // SplitCacheByNetworkIsolationKey experiment:
+  experiment_parts.push_back(isolation_key_field_trial
+                                 ? isolation_key_field_trial->group_name()
+                                 : kDiskCacheExperimentNameNone);
+  // This used to be used for keying on main frame only vs main frame +
+  // innermost frame, but the feature was removed, and now it's always
+  // keyed on both.
+  experiment_parts.push_back(kDiskCacheExperimentNameNone);
+  // This used to be for keying on scheme + eTLD+1 vs origin, but the trial
+  // was removed, and now it's always keyed on eTLD+1. Still keeping a
+  // third "None" to avoid resetting the disk cache.
+  experiment_parts.push_back(kDiskCacheExperimentNameNone);
+  // SplitCacheByIncludeCredentials experiment:
+  experiment_parts.push_back(credentials_field_trial
+                                 ? credentials_field_trial->group_name()
+                                 : kDiskCacheExperimentNameNone);
+
+  // Add the disk cache backend experiment group if active.
+  std::string_view backend_experiment = GetDiskCacheBackendExperimentString();
+  if (!backend_experiment.empty()) {
+    experiment_parts.push_back(backend_experiment);
+  }
+
+  const std::string current_field_trial_status =
+      base::JoinString(experiment_parts, kDiskCacheExperimentNameSeparator);
+
+  const std::string previous_field_trial_status =
+      local_state->GetString(kHttpCacheFinchExperimentGroups);
+  local_state->SetString(kHttpCacheFinchExperimentGroups,
+                         current_field_trial_status);
+
+  return !previous_field_trial_status.empty() &&
+         current_field_trial_status != previous_field_trial_status;
+}
+
 }  // namespace
 
 ProfileNetworkContextService::ProfileNetworkContextService(Profile* profile)
@@ -1229,44 +1310,6 @@
 #endif
 }
 
-bool GetHttpCacheBackendResetParam(PrefService* local_state) {
-  // Get the field trial groups.  If the server cannot be reached, then
-  // this corresponds to "None" for each experiment.
-  base::FieldTrial* field_trial = base::FeatureList::GetFieldTrial(
-      net::features::kSplitCacheByNetworkIsolationKey);
-  std::string current_field_trial_status =
-      (field_trial ? field_trial->group_name() : "None");
-  // This used to be used for keying on main frame only vs main frame +
-  // innermost frame, but the feature was removed, and now it's always keyed on
-  // both.
-  current_field_trial_status += " None";
-  // This used to be for keying on scheme + eTLD+1 vs origin, but the trial was
-  // removed, and now it's always keyed on eTLD+1. Still keeping a third "None"
-  // to avoid resetting the disk cache.
-  current_field_trial_status += " None ";
-
-  field_trial = base::FeatureList::GetFieldTrial(
-      net::features::kSplitCacheByIncludeCredentials);
-  current_field_trial_status +=
-      (field_trial ? field_trial->group_name() : "None");
-
-  if (disk_cache::InBackendExperiment()) {
-    if (disk_cache::InSimpleBackendExperimentGroup()) {
-      current_field_trial_status += " 20241007-DiskCache-Simple";
-    } else {
-      current_field_trial_status += " 20241007-DiskCache-Blockfile";
-    }
-  }
-
-  std::string previous_field_trial_status =
-      local_state->GetString(kHttpCacheFinchExperimentGroups);
-  local_state->SetString(kHttpCacheFinchExperimentGroups,
-                         current_field_trial_status);
-
-  return !previous_field_trial_status.empty() &&
-         current_field_trial_status != previous_field_trial_status;
-}
-
 void ProfileNetworkContextService::ConfigureNetworkContextParamsInternal(
     bool in_memory,
     const base::FilePath& relative_partition_path,
diff --git a/chrome/browser/net/profile_network_context_service_browsertest.cc b/chrome/browser/net/profile_network_context_service_browsertest.cc
index 5d43164..7c29b319 100644
--- a/chrome/browser/net/profile_network_context_service_browsertest.cc
+++ b/chrome/browser/net/profile_network_context_service_browsertest.cc
@@ -69,6 +69,7 @@
 #include "mojo/public/cpp/system/data_pipe_utils.h"
 #include "net/base/features.h"
 #include "net/base/load_flags.h"
+#include "net/disk_cache/buildflags.h"
 #include "net/disk_cache/cache_util.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/http/http_auth_preferences.h"
@@ -417,19 +418,33 @@
 
   const char* GetBackendParamValue() {
     switch (GetParam()) {
+      case net::features::DiskCacheBackend::kDefault:
+        return "default";
       case net::features::DiskCacheBackend::kSimple:
         return "simple";
       case net::features::DiskCacheBackend::kBlockfile:
         return "blockfile";
+#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
+      case net::features::DiskCacheBackend::kSql:
+        return "sql";
+#endif  // ENABLE_DISK_CACHE_SQL_BACKEND
     }
   }
 
   const char* GetExperimentString() {
+// The date and prefix for the disk cache backend experiment.
+#define DISK_CACHE_EXPERIMENT_DATE_PREFIX "20250725-DiskCache-"
     switch (GetParam()) {
+      case net::features::DiskCacheBackend::kDefault:
+        return DISK_CACHE_EXPERIMENT_DATE_PREFIX "Default";
       case net::features::DiskCacheBackend::kSimple:
-        return "20241007-DiskCache-Simple";
+        return DISK_CACHE_EXPERIMENT_DATE_PREFIX "Simple";
       case net::features::DiskCacheBackend::kBlockfile:
-        return "20241007-DiskCache-Blockfile";
+        return DISK_CACHE_EXPERIMENT_DATE_PREFIX "Blockfile";
+#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
+      case net::features::DiskCacheBackend::kSql:
+        return DISK_CACHE_EXPERIMENT_DATE_PREFIX "Sql";
+#endif  // ENABLE_DISK_CACHE_SQL_BACKEND
     }
   }
 
@@ -478,7 +493,12 @@
     All,
     ProfileNetworkContextServiceDiskCacheBackendExperimentBrowserTest,
     testing::ValuesIn({net::features::DiskCacheBackend::kSimple,
-                       net::features::DiskCacheBackend::kBlockfile}));
+                       net::features::DiskCacheBackend::kBlockfile
+#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
+                       ,
+                       net::features::DiskCacheBackend::kSql
+#endif  // ENABLE_DISK_CACHE_SQL_BACKEND
+    }));
 
 class AmbientAuthenticationTestWithPolicy : public policy::PolicyTest {
  public:
diff --git a/chrome/browser/net/qwac_web_contents_observer_browsertest.cc b/chrome/browser/net/qwac_web_contents_observer_browsertest.cc
index 9803174..8373a61 100644
--- a/chrome/browser/net/qwac_web_contents_observer_browsertest.cc
+++ b/chrome/browser/net/qwac_web_contents_observer_browsertest.cc
@@ -22,6 +22,7 @@
 #include "mojo/public/cpp/base/proto_wrapper.h"
 #include "net/base/features.h"
 #include "net/cert/internal/trust_store_chrome.h"
+#include "net/cert/root_store_proto_lite/root_store.pb.h"
 #include "net/cert/x509_certificate.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/http/http_status_code.h"
diff --git a/chrome/browser/page_image_service/android/BUILD.gn b/chrome/browser/page_image_service/android/BUILD.gn
index d9d7ee2..f42593f6 100644
--- a/chrome/browser/page_image_service/android/BUILD.gn
+++ b/chrome/browser/page_image_service/android/BUILD.gn
@@ -46,7 +46,7 @@
     "//components/page_image_service/mojom:mojo_bindings_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//url:gurl_junit_test_support",
     "//url:url_java",
diff --git a/chrome/browser/page_info/BUILD.gn b/chrome/browser/page_info/BUILD.gn
index 3709e0a..6bef4be 100644
--- a/chrome/browser/page_info/BUILD.gn
+++ b/chrome/browser/page_info/BUILD.gn
@@ -14,7 +14,7 @@
   public = [ "page_info_features.h" ]
 
   public_deps = [
-    "//base:base",
+    "//base",
     "//chrome/browser:browser_process",
   ]
 }
diff --git a/chrome/browser/partnerbookmarks/BUILD.gn b/chrome/browser/partnerbookmarks/BUILD.gn
index d41e3da..9234a5e2 100644
--- a/chrome/browser/partnerbookmarks/BUILD.gn
+++ b/chrome/browser/partnerbookmarks/BUILD.gn
@@ -35,10 +35,10 @@
     ":java_enums",
     ":jni_headers",
     "//chrome/browser:browser_process",
-    "//chrome/browser/favicon:favicon",
+    "//chrome/browser/favicon",
     "//chrome/browser/profiles:profile",
-    "//components/favicon/core:core",
-    "//components/pref_registry:pref_registry",
+    "//components/favicon/core",
+    "//components/pref_registry",
   ]
 }
 
@@ -96,7 +96,7 @@
     "//base:base_junit_test_support",
     "//chrome/browser/partnercustomizations:java",
     "//chrome/browser/profiles/android:java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
   ]
 }
diff --git a/chrome/browser/partnercustomizations/BUILD.gn b/chrome/browser/partnercustomizations/BUILD.gn
index 679a73e..e7075be 100644
--- a/chrome/browser/partnercustomizations/BUILD.gn
+++ b/chrome/browser/partnercustomizations/BUILD.gn
@@ -76,7 +76,7 @@
     "//content/public/test/android:content_java_test_support",
     "//third_party/androidx:androidx_test_core_java",
     "//third_party/androidx:androidx_test_monitor_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
   ]
 }
 
@@ -99,7 +99,7 @@
     "//components/url_formatter/android:url_formatter_java",
     "//content/public/test/android:content_java_test_support",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//url:gurl_java",
   ]
 }
@@ -126,7 +126,7 @@
     "//chrome/test/android:chrome_java_unit_test_support",
     "//components/embedder_support/android:util_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//url:gurl_java",
     "//url:gurl_junit_test_support",
diff --git a/chrome/browser/password_check/android/BUILD.gn b/chrome/browser/password_check/android/BUILD.gn
index 97f2f089..4ad4580b 100644
--- a/chrome/browser/password_check/android/BUILD.gn
+++ b/chrome/browser/password_check/android/BUILD.gn
@@ -23,7 +23,7 @@
     ":password_check_enums_srcjar",
     "//base/test:test_support",
     "//chrome/browser",
-    "//chrome/browser/password_manager/factories:factories",
+    "//chrome/browser/password_manager/factories",
     "//chrome/browser/sync",
     "//chrome/test:test_support",
     "//components/password_manager/core/browser",
diff --git a/chrome/browser/password_edit_dialog/android/BUILD.gn b/chrome/browser/password_edit_dialog/android/BUILD.gn
index d26fb9aad..3eeefde1 100644
--- a/chrome/browser/password_edit_dialog/android/BUILD.gn
+++ b/chrome/browser/password_edit_dialog/android/BUILD.gn
@@ -17,7 +17,7 @@
     "//base",
     "//chrome/app:generated_resources",
     "//content/public/browser",
-    "//ui/android:android",
+    "//ui/android",
   ]
 }
 
diff --git a/chrome/browser/password_manager/BUILD.gn b/chrome/browser/password_manager/BUILD.gn
index 10d87f3..4fff1ea4 100644
--- a/chrome/browser/password_manager/BUILD.gn
+++ b/chrome/browser/password_manager/BUILD.gn
@@ -4,7 +4,7 @@
 
 group("password_manager") {
   public_deps = [
+    "//chrome/browser/password_manager/factories",
     "//chrome/browser/password_manager/factories:backend_factory",
-    "//chrome/browser/password_manager/factories:factories",
   ]
 }
diff --git a/chrome/browser/password_manager/android/BUILD.gn b/chrome/browser/password_manager/android/BUILD.gn
index 9f71549..ba75d46 100644
--- a/chrome/browser/password_manager/android/BUILD.gn
+++ b/chrome/browser/password_manager/android/BUILD.gn
@@ -189,18 +189,10 @@
     "java/src/org/chromium/chrome/browser/password_manager/PasswordStoreBridge.java",
     "java/src/org/chromium/chrome/browser/password_manager/PasswordStoreCredential.java",
     "java/src/org/chromium/chrome/browser/password_manager/PasswordSyncControllerDelegateBridgeImpl.java",
-    "java/src/org/chromium/chrome/browser/password_manager/settings/ExportFlow.java",
-    "java/src/org/chromium/chrome/browser/password_manager/settings/ExportFlowInterface.java",
     "java/src/org/chromium/chrome/browser/password_manager/settings/PasswordAccessReauthenticationHelper.java",
-    "java/src/org/chromium/chrome/browser/password_manager/settings/PasswordListObserver.java",
-    "java/src/org/chromium/chrome/browser/password_manager/settings/PasswordManagerHandler.java",
-    "java/src/org/chromium/chrome/browser/password_manager/settings/PasswordManagerHandlerProvider.java",
     "java/src/org/chromium/chrome/browser/password_manager/settings/PasswordReauthenticationFragment.java",
-    "java/src/org/chromium/chrome/browser/password_manager/settings/PasswordUiView.java",
     "java/src/org/chromium/chrome/browser/password_manager/settings/PasswordsPreference.java",
-    "java/src/org/chromium/chrome/browser/password_manager/settings/ProgressBarDialogFragment.java",
     "java/src/org/chromium/chrome/browser/password_manager/settings/ReauthenticationManager.java",
-    "java/src/org/chromium/chrome/browser/password_manager/settings/SavedPasswordEntry.java",
   ]
 
   resources_package = "org.chromium.chrome.browser.password_manager"
@@ -223,7 +215,6 @@
     "java/src/org/chromium/chrome/browser/password_manager/PasswordStoreBridge.java",
     "java/src/org/chromium/chrome/browser/password_manager/PasswordStoreCredential.java",
     "java/src/org/chromium/chrome/browser/password_manager/PasswordSyncControllerDelegateBridgeImpl.java",
-    "java/src/org/chromium/chrome/browser/password_manager/settings/PasswordUiView.java",
   ]
 }
 
@@ -234,12 +225,6 @@
     "java/src/org/chromium/chrome/browser/password_manager/HelpUrlLauncher.java",
     "java/src/org/chromium/chrome/browser/password_manager/LoginDbDeprecationUtilBridge.java",
     "java/src/org/chromium/chrome/browser/password_manager/PasswordExportLauncher.java",
-    "java/src/org/chromium/chrome/browser/password_manager/settings/CallbackDelayer.java",
-    "java/src/org/chromium/chrome/browser/password_manager/settings/DialogManager.java",
-    "java/src/org/chromium/chrome/browser/password_manager/settings/ExportErrorDialogFragment.java",
-    "java/src/org/chromium/chrome/browser/password_manager/settings/NonCancelableProgressBar.java",
-    "java/src/org/chromium/chrome/browser/password_manager/settings/SingleThreadBarrierClosure.java",
-    "java/src/org/chromium/chrome/browser/password_manager/settings/TimedCallbackDelayer.java",
   ]
 
   srcjar_deps = [ ":utils_jni_headers" ]
@@ -471,7 +456,6 @@
     "test_support/java/src/org/chromium/chrome/browser/password_manager/FakePasswordCheckupClientHelper.java",
     "test_support/java/src/org/chromium/chrome/browser/password_manager/FakePasswordCheckupClientHelperFactoryImpl.java",
     "test_support/java/src/org/chromium/chrome/browser/password_manager/FakePasswordManagerBackendSupportHelper.java",
-    "test_support/java/src/org/chromium/chrome/browser/password_manager/FakePasswordManagerHandler.java",
     "test_support/java/src/org/chromium/chrome/browser/password_manager/FakePasswordSettingsAccessor.java",
     "test_support/java/src/org/chromium/chrome/browser/password_manager/FakePasswordSettingsAccessorFactoryImpl.java",
     "test_support/java/src/org/chromium/chrome/browser/password_manager/FakePasswordStoreAndroidBackend.java",
diff --git a/chrome/browser/password_manager/android/account_storage_notice/BUILD.gn b/chrome/browser/password_manager/android/account_storage_notice/BUILD.gn
index 0c8dc90..edaba04d 100644
--- a/chrome/browser/password_manager/android/account_storage_notice/BUILD.gn
+++ b/chrome/browser/password_manager/android/account_storage_notice/BUILD.gn
@@ -88,7 +88,7 @@
     "//components/browser_ui/settings/android:java",
     "//components/prefs/android:java",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java",
   ]
diff --git a/chrome/browser/password_manager/android/add_username_dialog/BUILD.gn b/chrome/browser/password_manager/android/add_username_dialog/BUILD.gn
index 673d8ef..03c417d1 100644
--- a/chrome/browser/password_manager/android/add_username_dialog/BUILD.gn
+++ b/chrome/browser/password_manager/android/add_username_dialog/BUILD.gn
@@ -15,7 +15,7 @@
     ":jni_headers",
     "//base",
     "//content/public/browser",
-    "//ui/android:android",
+    "//ui/android",
   ]
 }
 
diff --git a/chrome/browser/password_manager/android/bottom_sheet/BUILD.gn b/chrome/browser/password_manager/android/bottom_sheet/BUILD.gn
index 481272f..ba04dc2 100644
--- a/chrome/browser/password_manager/android/bottom_sheet/BUILD.gn
+++ b/chrome/browser/password_manager/android/bottom_sheet/BUILD.gn
@@ -42,7 +42,7 @@
     "//third_party/androidx:androidx_test_ext_junit_java",
     "//third_party/hamcrest:hamcrest_core_java",
     "//third_party/hamcrest:hamcrest_library_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
     "//ui/android:ui_no_recycler_view_java",
@@ -70,7 +70,7 @@
     "//components/browser_ui/bottomsheet/android:manager_java",
     "//components/browser_ui/bottomsheet/android/test:java",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
     "//ui/android:ui_no_recycler_view_java",
diff --git a/chrome/browser/password_manager/android/grouped_affiliations/BUILD.gn b/chrome/browser/password_manager/android/grouped_affiliations/BUILD.gn
index 1e5d077..081f0bc4 100644
--- a/chrome/browser/password_manager/android/grouped_affiliations/BUILD.gn
+++ b/chrome/browser/password_manager/android/grouped_affiliations/BUILD.gn
@@ -16,9 +16,9 @@
   deps = [
     ":jni_headers",
     "//base",
-    "//components/password_manager/core/browser:browser",
+    "//components/password_manager/core/browser",
     "//content/public/browser",
-    "//ui/android:android",
+    "//ui/android",
   ]
 }
 
@@ -74,7 +74,7 @@
   deps = [
     ":public",
     "//base/test:test_support",
-    "//ui/android:android",
+    "//ui/android",
   ]
 }
 
@@ -84,7 +84,7 @@
   deps = [
     ":public",
     "//base/test:test_support",
-    "//ui/android:android",
+    "//ui/android",
   ]
 }
 
@@ -106,7 +106,7 @@
     "//components/browser_ui/bottomsheet/android:manager_java",
     "//components/browser_ui/theme/android:java_resources",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_no_recycler_view_java",
   ]
@@ -132,7 +132,7 @@
     "//components/browser_ui/bottomsheet/android:manager_java",
     "//components/browser_ui/bottomsheet/android/test:java",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
     "//ui/android:ui_no_recycler_view_java",
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/ExportFlow.java b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/ExportFlow.java
deleted file mode 100644
index 62bdc5e..0000000
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/ExportFlow.java
+++ /dev/null
@@ -1,606 +0,0 @@
-// Copyright 2018 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.password_manager.settings;
-
-import static org.chromium.build.NullUtil.assumeNonNull;
-import static org.chromium.chrome.browser.password_manager.PasswordMetricsUtil.logPasswordsExportResult;
-
-import android.content.ActivityNotFoundException;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.VisibleForTesting;
-import androidx.appcompat.app.AlertDialog;
-
-import org.chromium.base.CallbackUtils;
-import org.chromium.base.ContextUtils;
-import org.chromium.base.FileProviderUtils;
-import org.chromium.base.FileUtils;
-import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.base.task.AsyncTask;
-import org.chromium.build.annotations.Initializer;
-import org.chromium.build.annotations.NullMarked;
-import org.chromium.build.annotations.Nullable;
-import org.chromium.chrome.browser.password_manager.PasswordMetricsUtil;
-import org.chromium.chrome.browser.password_manager.PasswordMetricsUtil.HistogramExportResult;
-import org.chromium.chrome.browser.password_manager.R;
-import org.chromium.ui.widget.Toast;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * This class allows to trigger and complete the UX flow for exporting passwords. A {@link Fragment}
- * can use it to display the flow UI over the fragment.
- *
- * <pre>
- * Internally, the flow is represented by the following calls:
- * (1)  {@link #startExporting}, which triggers both preparing of stored passwords in the background
- *      and reauthentication of the user.
- * (2a) {@link #shareSerializedPasswords}, which is the final part of the preparation of passwords
- *      which otherwise runs in the native code.
- * (2b) {@link #exportAfterReauth} is the user-visible next step after reauthentication.
- * (3)  {@link #tryExporting} merges the flow of the in-parallel-running (2a) and (2b). In the rare
- *      case when (2b) finishes before (2a), it also displays a progress bar.
- * (4)  {@link #sendExportIntent} creates an intent chooser for sharing the exported passwords with
- *      an app of user's choice.
- * </pre>
- */
-@NullMarked
-public class ExportFlow implements ExportFlowInterface {
-    @IntDef({ExportState.INACTIVE, ExportState.REQUESTED, ExportState.CONFIRMED})
-    @Retention(RetentionPolicy.SOURCE)
-    private @interface ExportState {
-        /**
-         * INACTIVE: there is no currently running export. Either the user did not request
-         * one, or the last one completed (i.e., a share intent picker or an error message were
-         * displayed or the user cancelled it).
-         */
-        int INACTIVE = 0;
-
-        /**
-         * REQUESTED: the user requested the export in the menu but did not authenticate
-         * and confirm it yet.
-         */
-        int REQUESTED = 1;
-
-        /**
-         * CONFIRMED: the user confirmed the export and Chrome is still busy preparing the
-         * data for the share intent.
-         */
-        int CONFIRMED = 2;
-    }
-
-    /** Describes at which state the password export flow is. */
-    @ExportState private int mExportState;
-
-    /** Name of the subdirectory in cache which stores the exported passwords file. */
-    private static final String PASSWORDS_CACHE_DIR = "/passwords";
-
-    /** The key for saving {@link #mExportState} to instance bundle. */
-    private static final String SAVED_STATE_EXPORT_STATE = "saved-state-export-state";
-
-    /** The key for saving {@link #mEntriesCount}|to instance bundle. */
-    private static final String SAVED_STATE_ENTRIES_COUNT = "saved-state-entries-count";
-
-    /** The key for saving {@link #mExportFileUri} to instance bundle. */
-    private static final String SAVED_STATE_EXPORT_FILE_URI = "saved-state-export-file-uri";
-
-    /** The delay after which the progress bar will be displayed. */
-    private static final int PROGRESS_BAR_DELAY_MS = 500;
-
-    // Values of the histogram recording password export related events.
-    @IntDef({
-        PasswordExportEvent.EXPORT_OPTION_SELECTED,
-        PasswordExportEvent.EXPORT_DISMISSED,
-        PasswordExportEvent.EXPORT_CONFIRMED,
-        PasswordExportEvent.COUNT
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface PasswordExportEvent {
-        int EXPORT_OPTION_SELECTED = 0;
-        int EXPORT_DISMISSED = 1;
-        int EXPORT_CONFIRMED = 2;
-        int COUNT = 3;
-    }
-
-    /**
-     * When the user requests that passwords are exported and once the passwords are sent over from
-     * native code and stored in a cache file, this variable contains the content:// URI for that
-     * cache file, or an empty URI if there was a problem with storing to that file. During all
-     * other times, this variable is null. In particular, after the export is requested, the
-     * variable being null means that the passwords have not arrived from the native code yet.
-     */
-    private @Nullable Uri mExportFileUri;
-
-    /**
-     * The number of password entries contained in the most recent serialized data for password
-     * export. The null value indicates that serialization has not completed since the last request
-     * (or there was no request at all).
-     */
-    private @Nullable Integer mEntriesCount;
-
-    // Histogram values for "PasswordManager.Android.ExportPasswordsProgressBarUsage". Never remove
-    // or reuse them, only add new ones if needed to keep past and future UMA reports compatible.
-    @VisibleForTesting public static final int PROGRESS_NOT_SHOWN = 0;
-    @VisibleForTesting public static final int PROGRESS_HIDDEN_DIRECTLY = 1;
-    @VisibleForTesting public static final int PROGRESS_HIDDEN_DELAYED = 2;
-
-    // Takes care of displaying and hiding the progress bar for exporting, while avoiding
-    // flickering.
-    private final DialogManager mProgressBarManager = new DialogManager(null);
-
-    /**
-     * If an error dialog should be shown, this contains the arguments for it, such as the error
-     * message. If no error dialog should be shown, this is null.
-     */
-    private ExportErrorDialogFragment.@Nullable ErrorDialogParams mErrorDialogParams;
-
-    public DialogManager getDialogManagerForTesting() {
-        return mProgressBarManager;
-    }
-
-    /** The concrete delegate instance. It is (re)set in {@link #onCreate}. */
-    private Delegate mDelegate;
-
-    /** Histogram names for metrics logging. */
-    private String mCallerMetricsId;
-
-    private boolean mPasswordSerializationStarted;
-
-    public ExportFlow() {}
-
-    public String getExportEventHistogramName() {
-        return mCallerMetricsId + ".Event";
-    }
-
-    public String getExportResultHistogramName2ForTesting() {
-        return mCallerMetricsId + PasswordMetricsUtil.EXPORT_RESULT_HISTOGRAM_SUFFIX;
-    }
-
-    @Initializer
-    @Override
-    public void onCreate(
-            @Nullable Bundle savedInstanceState, Delegate delegate, String callerMetricsId) {
-        mDelegate = delegate;
-        mCallerMetricsId = callerMetricsId;
-
-        if (savedInstanceState == null) return;
-
-        if (savedInstanceState.containsKey(SAVED_STATE_EXPORT_STATE)) {
-            mExportState = savedInstanceState.getInt(SAVED_STATE_EXPORT_STATE);
-            if (mExportState == ExportState.CONFIRMED) {
-                // If export is underway, ensure that the UI is updated.
-                tryExporting();
-            }
-        }
-        if (savedInstanceState.containsKey(SAVED_STATE_EXPORT_FILE_URI)) {
-            String uriString = savedInstanceState.getString(SAVED_STATE_EXPORT_FILE_URI);
-            assumeNonNull(uriString);
-            if (uriString.isEmpty()) {
-                mExportFileUri = Uri.EMPTY;
-            } else {
-                mExportFileUri = Uri.parse(uriString);
-            }
-        }
-        if (savedInstanceState.containsKey(SAVED_STATE_ENTRIES_COUNT)) {
-            mEntriesCount = savedInstanceState.getInt(SAVED_STATE_ENTRIES_COUNT);
-        }
-    }
-
-    /**
-     * Returns true if the export flow is in progress, i.e., when the user interacts with some of
-     * its UI.
-     * @return True if in progress, false otherwise.
-     */
-    public boolean isActive() {
-        return mExportState != ExportState.INACTIVE;
-    }
-
-    /**
-     * A helper method which processes the signal that serialized passwords have been stored in the
-     * temporary file. It produces a sharing URI for that file, registers that file for deletion at
-     * the shutdown of the Java VM, logs some metrics and continues the flow.
-     * @param pathToPasswordsFile The filesystem path to the file containing the serialized
-     *                            passwords.
-     */
-    private void shareSerializedPasswords(String pathToPasswordsFile) {
-        // Don't display any UI if the user cancelled the export in the meantime.
-        if (mExportState == ExportState.INACTIVE) return;
-
-        File passwordsFile = new File(pathToPasswordsFile);
-        passwordsFile.deleteOnExit();
-
-        try {
-            mExportFileUri = FileProviderUtils.getContentUriFromFile(passwordsFile);
-        } catch (IllegalArgumentException e) {
-            showExportErrorAndAbort(
-                    R.string.password_settings_export_tips,
-                    e.getMessage(),
-                    getPositiveButtonLabelId(),
-                    HistogramExportResult.WRITE_FAILED);
-            return;
-        }
-
-        tryExporting();
-    }
-
-    /**
-     * Returns the path to the directory where serialized passwords are stored.
-     *
-     * @return A subdirectory of the cache, where serialized passwords are stored.
-     */
-    @VisibleForTesting
-    public static String getTargetDirectory() {
-        return ContextUtils.getApplicationContext().getCacheDir() + PASSWORDS_CACHE_DIR;
-    }
-
-    @Override
-    public void startExporting() {
-        assert mExportState == ExportState.INACTIVE;
-        mPasswordSerializationStarted = false;
-        // Disable re-triggering exporting until the current exporting finishes.
-        mExportState = ExportState.REQUESTED;
-
-        // Start fetching the serialized passwords now to use the time the user spends
-        // reauthenticating and reading the warning message. If the user cancels the export or
-        // fails the reauthentication, the serialized passwords will simply get ignored when
-        // they arrive.
-        mEntriesCount = null;
-        PasswordManagerHandler handler =
-                PasswordManagerHandlerProvider.getForProfile(mDelegate.getProfile())
-                        .getPasswordManagerHandler();
-        assumeNonNull(handler);
-        if (!handler.isWaitingForPasswordStore()) {
-            serializePasswords();
-        }
-        if (!ReauthenticationManager.isScreenLockSetUp(
-                mDelegate.getActivity().getApplicationContext())) {
-            Toast.makeText(
-                            mDelegate.getActivity().getApplicationContext(),
-                            R.string.password_export_set_lock_screen,
-                            Toast.LENGTH_LONG)
-                    .show();
-            // Re-enable exporting, the current one was cancelled by Chrome.
-            mExportState = ExportState.INACTIVE;
-        } else {
-            // Always trigger reauthentication at the start of the exporting flow, even if the last
-            // one succeeded recently.
-            ReauthenticationManager.displayReauthenticationFragment(
-                    R.string.lockscreen_description_export,
-                    mDelegate.getViewId(),
-                    mDelegate.getFragmentManager(),
-                    ReauthenticationManager.ReauthScope.BULK);
-        }
-    }
-
-    /** Starts fetching the serialized passwords. */
-    void serializePasswords() {
-        if (mPasswordSerializationStarted) return;
-        mPasswordSerializationStarted = true;
-        PasswordManagerHandler handler =
-                PasswordManagerHandlerProvider.getForProfile(mDelegate.getProfile())
-                        .getPasswordManagerHandler();
-        assumeNonNull(handler);
-        handler.serializePasswords(
-                getTargetDirectory(),
-                (int entriesCount, String pathToPasswordsFile) -> {
-                    mEntriesCount = entriesCount;
-                    shareSerializedPasswords(pathToPasswordsFile);
-                },
-                (String errorMessage) -> {
-                    showExportErrorAndAbort(
-                            R.string.password_settings_export_tips,
-                            errorMessage,
-                            getPositiveButtonLabelId(),
-                            HistogramExportResult.WRITE_FAILED);
-                });
-    }
-
-    @Override
-    public void passwordsAvailable() {
-        if (mExportState == ExportState.REQUESTED) {
-            serializePasswords();
-        }
-    }
-
-    /**
-     * Continues with the password export flow after the user successfully reauthenticated. Current
-     * state of export flow: the user tapped the menu item for export and passed reauthentication.
-     * The next steps are: confirming the export, waiting for exported data (if needed) and choosing
-     * a consumer app for the data.
-     */
-    private void exportAfterReauth() {
-        RecordHistogram.recordEnumeratedHistogram(
-                getExportEventHistogramName(),
-                PasswordExportEvent.EXPORT_CONFIRMED,
-                PasswordExportEvent.COUNT);
-        mExportState = ExportState.CONFIRMED;
-        // If the error dialog has been waiting (e. g. because password serialization failed while
-        // the user was authenticating), display it now, otherwise continue the export flow.
-        if (mErrorDialogParams != null) {
-            showExportErrorDialogFragment();
-        } else {
-            tryExporting();
-        }
-    }
-
-    /**
-     * Starts the exporting intent if both blocking events are completed: serializing and the
-     * confirmation flow. At this point, the user has tapped the menu item for export and passed
-     * reauthentication. Upon calling this method, the user has either also confirmed the export, or
-     * the exported data have been prepared. The method is called twice, once for each of those
-     * events. The next step after both the export is confirmed and the data is ready is to create
-     * document intent.
-     */
-    private void tryExporting() {
-        if (mExportState != ExportState.CONFIRMED) return;
-        if (mEntriesCount == null) {
-            // The serialization has not finished. Until this finishes, a progress bar is
-            // displayed with an option to cancel the export.
-            ProgressBarDialogFragment progressBarDialogFragment = new ProgressBarDialogFragment();
-            progressBarDialogFragment.setCancelProgressHandler(
-                    (unusedDialogInterface, button) -> {
-                        if (button == AlertDialog.BUTTON_NEGATIVE) {
-                            mExportState = ExportState.INACTIVE;
-                        }
-                    });
-            mProgressBarManager.show(progressBarDialogFragment, mDelegate.getFragmentManager());
-        } else {
-            // Note: if the serialization is quicker than the user interacting with the
-            // confirmation dialog, then there is no progress bar shown, in which case hide() is
-            // just calling the callback synchronously.
-            mProgressBarManager.hide(this::sendExportIntent);
-        }
-    }
-
-    /**
-     * Call this to abort the export UI flow and display an error description to the user.
-     *
-     * @param descriptionId The resource ID of a string with a brief explanation of the error.
-     * @param detailedDescription An optional string with more technical details about the error.
-     * @param positiveButtonLabelId The resource ID of the label of the positive button in the error
-     *     dialog.
-     */
-    @VisibleForTesting
-    void showExportErrorAndAbort(
-            int descriptionId,
-            @Nullable String detailedDescription,
-            int positiveButtonLabelId,
-            @HistogramExportResult int histogramExportResult) {
-        assert mErrorDialogParams == null;
-        mDelegate.onExportFlowFailed();
-        mProgressBarManager.hide(
-                () -> {
-                    showExportErrorAndAbortImmediately(
-                            descriptionId,
-                            detailedDescription,
-                            positiveButtonLabelId,
-                            histogramExportResult);
-                });
-    }
-
-    public void showExportErrorAndAbortImmediately(
-            int descriptionId,
-            @Nullable String detailedDescription,
-            int positiveButtonLabelId,
-            @HistogramExportResult int histogramExportResult) {
-        mErrorDialogParams = new ExportErrorDialogFragment.ErrorDialogParams();
-        mErrorDialogParams.positiveButtonLabelId = positiveButtonLabelId;
-        mErrorDialogParams.description =
-                mDelegate.getActivity().getResources().getString(descriptionId);
-
-        if (detailedDescription != null) {
-            mErrorDialogParams.detailedDescription =
-                    mDelegate
-                            .getActivity()
-                            .getResources()
-                            .getString(
-                                    R.string.password_settings_export_error_details,
-                                    detailedDescription);
-        }
-
-        showExportErrorDialogFragment();
-    }
-
-    /**
-     * This is a helper method to {@link #showExportErrorAndAbort}, responsible for showing the
-     * actual UI.
-     */
-    private void showExportErrorDialogFragment() {
-        assert mErrorDialogParams != null;
-
-        ExportErrorDialogFragment exportErrorDialogFragment = new ExportErrorDialogFragment();
-        int positiveButtonLabelId = mErrorDialogParams.positiveButtonLabelId;
-        exportErrorDialogFragment.initialize(mErrorDialogParams);
-        mErrorDialogParams = null;
-
-        exportErrorDialogFragment.setExportErrorHandler(
-                new DialogInterface.OnClickListener() {
-                    @Override
-                    public void onClick(DialogInterface dialog, int which) {
-                        if (which == AlertDialog.BUTTON_POSITIVE) {
-                            if (positiveButtonLabelId
-                                    == R.string.password_settings_export_learn_google_drive) {
-                                // Link to the help article about how to use Google Drive.
-                                Intent intent =
-                                        new Intent(
-                                                Intent.ACTION_VIEW,
-                                                Uri.parse(
-                                                        "https://support.google.com/drive/answer/2424384"));
-                                intent.setPackage(mDelegate.getActivity().getPackageName());
-                                mDelegate.getActivity().startActivity(intent);
-                            } else if (positiveButtonLabelId == R.string.try_again) {
-                                mExportState = ExportState.REQUESTED;
-                                // If `mExportFileUri` is null, it means that serialization has
-                                // failed. Need to restart it too.
-                                if (mExportFileUri == null) {
-                                    mPasswordSerializationStarted = false;
-                                    serializePasswords();
-                                }
-                                exportAfterReauth();
-                            }
-                        } else if (which == AlertDialog.BUTTON_NEGATIVE) {
-                            // Re-enable exporting, the current one was just cancelled.
-                            mDelegate.onExportFlowCanceled();
-                            mProgressBarManager.hide(CallbackUtils.emptyRunnable());
-                            mExportState = ExportState.INACTIVE;
-                            mExportFileUri = null;
-                        }
-                    }
-                });
-        exportErrorDialogFragment.show(mDelegate.getFragmentManager(), null);
-    }
-
-    /**
-     * If the URI of the file with exported passwords is not null, passes it into an implicit
-     * intent, so that the user can use a storage app to save the exported passwords.
-     */
-    private void sendExportIntent() {
-        assert mExportState == ExportState.CONFIRMED;
-        mExportState = ExportState.INACTIVE;
-
-        if (mExportFileUri != null && mExportFileUri.equals(Uri.EMPTY)) return;
-
-        runCreateFileOnDiskIntent();
-    }
-
-    private void runCreateFileOnDiskIntent() {
-        Intent saveToDownloads = new Intent(Intent.ACTION_CREATE_DOCUMENT);
-        saveToDownloads.setType("text/csv");
-        saveToDownloads.addCategory(Intent.CATEGORY_OPENABLE);
-        saveToDownloads.putExtra(
-                Intent.EXTRA_TITLE,
-                mDelegate
-                        .getActivity()
-                        .getResources()
-                        .getString(R.string.password_manager_default_export_filename));
-        try {
-            mDelegate.runCreateFileOnDiskIntent(saveToDownloads);
-        } catch (ActivityNotFoundException e) {
-            showExportErrorAndAbort(
-                    R.string.password_settings_export_no_app,
-                    e.getMessage(),
-                    getPositiveButtonLabelId(),
-                    HistogramExportResult.NO_CONSUMER);
-        }
-    }
-
-    @Override
-    public void savePasswordsToDownloads(Uri passwordsFile) {
-        if (passwordsFile == null) {
-            showExportErrorAndAbort(
-                    R.string.password_settings_export_tips,
-                    "Could not create file.",
-                    getPositiveButtonLabelId(),
-                    HistogramExportResult.WRITE_FAILED);
-            return;
-        }
-        new AsyncTask<@Nullable String>() {
-            @Override
-            protected @Nullable String doInBackground() {
-                assumeNonNull(mExportFileUri);
-                try {
-                    writeToInternalStorage(mExportFileUri, passwordsFile);
-                } catch (IOException e) {
-                    return e.getMessage();
-                }
-                return null;
-            }
-
-            @Override
-            protected void onPostExecute(@Nullable String exceptionMessage) {
-                mProgressBarManager.hide(
-                        () -> {
-                            if (exceptionMessage != null) {
-                                showExportErrorAndAbort(
-                                        R.string.password_settings_export_tips,
-                                        exceptionMessage,
-                                        getPositiveButtonLabelId(),
-                                        HistogramExportResult.WRITE_FAILED);
-                            } else {
-                                mDelegate.onExportFlowSucceeded();
-                                mExportFileUri = null;
-                                logPasswordsExportResult(
-                                        mCallerMetricsId, HistogramExportResult.SUCCESS);
-                            }
-                        });
-            }
-        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-        mProgressBarManager.showWithDelay(
-                new NonCancelableProgressBar(R.string.passwords_export_in_progress_title),
-                mDelegate.getFragmentManager(),
-                PROGRESS_BAR_DELAY_MS);
-    }
-
-    private static void writeToInternalStorage(Uri exportedPasswordsUri, Uri savedPasswordsFileUri)
-            throws IOException {
-        try (InputStream fileInputStream =
-                ContextUtils.getApplicationContext()
-                        .getContentResolver()
-                        .openInputStream(exportedPasswordsUri)) {
-            try (OutputStream fileOutputStream =
-                    ContextUtils.getApplicationContext()
-                            .getContentResolver()
-                            .openOutputStream(savedPasswordsFileUri)) {
-                assumeNonNull(fileInputStream);
-                assumeNonNull(fileOutputStream);
-                FileUtils.copyStream(fileInputStream, fileOutputStream);
-            }
-        }
-    }
-
-    @Override
-    public void onResume() {
-        if (mExportState == ExportState.REQUESTED) {
-            if (ReauthenticationManager.authenticationStillValid(
-                    ReauthenticationManager.ReauthScope.BULK)) {
-                exportAfterReauth();
-            } else {
-                mExportState = ExportState.INACTIVE;
-            }
-        }
-    }
-
-    /**
-     * A hook to be used in a {@link Fragment}'s onSaveInstanceState method. I saves the state of
-     * the flow.
-     */
-    public void onSaveInstanceState(Bundle outState) {
-        outState.putInt(SAVED_STATE_EXPORT_STATE, mExportState);
-        if (mEntriesCount != null) {
-            outState.putInt(SAVED_STATE_ENTRIES_COUNT, mEntriesCount);
-        }
-        if (mExportFileUri != null) {
-            outState.putString(SAVED_STATE_EXPORT_FILE_URI, mExportFileUri.toString());
-        }
-    }
-
-    /**
-     * Returns whether the password export feature is ready to use.
-     * @return Returns true if the Reauthentication Api is available.
-     */
-    public static boolean providesPasswordExport() {
-        return ReauthenticationManager.isReauthenticationApiAvailable();
-    }
-
-    private int getPositiveButtonLabelId() {
-        // Don't allow to try restarting the export flow. The reason: it won't be able to create the
-        // file for saving passwords on disk because the dialog, which owns the export flow would be
-        // dismissed. There is a workaround: clicking on Google Password Manager will propose to
-        // restart the export flow.
-        // TODO (crbug.com/364530583): returning 0 here means there should be only one "Close"
-        // button in the dialog. Make error dialog configurable instead of passing a 0 resource into
-        // it.
-        return 0;
-    }
-}
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/ExportFlowInterface.java b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/ExportFlowInterface.java
deleted file mode 100644
index b586b4fc..0000000
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/ExportFlowInterface.java
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.password_manager.settings;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentManager;
-
-import org.chromium.build.annotations.NullMarked;
-import org.chromium.build.annotations.Nullable;
-import org.chromium.chrome.browser.profiles.Profile;
-
-/** An interface for the implementations of {@link ExportFlow}. */
-@NullMarked
-public interface ExportFlowInterface {
-    /** The delegate to provide ExportFlow with essential information from the owning fragment. */
-    public interface Delegate {
-        /**
-         * @return The activity associated with the owning fragment.
-         */
-        Activity getActivity();
-
-        /**
-         * @return The fragment manager associated with the owning fragment.
-         */
-        FragmentManager getFragmentManager();
-
-        /**
-         * @return The ID of the root view of the owning fragment.
-         */
-        int getViewId();
-
-        /**
-         * Runs the activity on the fragment owning the export flow.
-         *
-         * @param intent The intent to start an activity.
-         */
-        void runCreateFileOnDiskIntent(Intent intent);
-
-        /**
-         * Performs the actions that should happen after the export flow has successfully finished.
-         */
-        default void onExportFlowSucceeded() {}
-
-        /** Performs the actions that should happen after the export flow has failed. */
-        default void onExportFlowFailed() {}
-
-        /** Notifies about that export flow has been canceled. */
-        default void onExportFlowCanceled() {}
-
-        /** Return the {@link Profile} associated with the passwords. */
-        Profile getProfile();
-    }
-
-    /**
-     * A hook to be used in the onCreate method of the owning {@link Fragment}. I restores the state
-     * of the flow.
-     *
-     * @param savedInstanceState The {@link Bundle} passed from the fragment's onCreate method.
-     * @param delegate The {@link Delegate} for this ExportFlow.
-     * @param callerMetricsId The unique string, which identifies the caller. This will be used as
-     *     the prefix for metrics histograms names.
-     */
-    public void onCreate(
-            @Nullable Bundle savedInstanceState, Delegate delegate, String callerMetricsId);
-
-    /** Starts the password export flow. */
-    public void startExporting();
-
-    /**
-     * A hook to be used in a {@link Fragment}'s onResume method. I processes the result of the
-     * reauthentication.
-     */
-    public void onResume();
-
-    /** Continues the export flow when password list is available. */
-    public void passwordsAvailable();
-
-    /**
-     * Saves the passwords into the file (in the form of Uri) passed in.
-     *
-     * @param passwordsFile The file into which the passwords will be written (expected to be a file
-     *         Uri).
-     */
-    void savePasswordsToDownloads(Uri passwordsFile);
-}
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordListObserver.java b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordListObserver.java
deleted file mode 100644
index 773d1f1..0000000
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordListObserver.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.password_manager.settings;
-
-import org.chromium.build.annotations.NullMarked;
-
-/**
- * An interface which a client can use to listen to changes to password and password exception
- * lists.
- */
-@NullMarked
-public interface PasswordListObserver {
-    /**
-     * Called when passwords list is updated.
-     *
-     * @param count Number of entries in the password list.
-     */
-    void passwordListAvailable(int count);
-
-    /**
-     * Called when password exceptions list is updated.
-     *
-     * @param count Number of entries in the password exception list.
-     */
-    void passwordExceptionListAvailable(int count);
-}
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordManagerHandler.java b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordManagerHandler.java
deleted file mode 100644
index 49f2ac8..0000000
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordManagerHandler.java
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2017 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.password_manager.settings;
-
-import android.content.Context;
-
-import org.chromium.base.Callback;
-import org.chromium.base.IntStringCallback;
-import org.chromium.build.annotations.NullMarked;
-
-/**
- * Interface for retrieving passwords and password exceptions (websites for which Chrome should not
- * save password) from native code.
- */
-@NullMarked
-public interface PasswordManagerHandler {
-    /** Called to insert a password entry into the password store. */
-    public void insertPasswordEntryForTesting(String origin, String username, String password);
-
-    /** Called to start fetching password and exception lists. */
-    void updatePasswordLists();
-
-    /**
-     * Get the saved password entry at index.
-     *
-     * @param index Index of Password.
-     * @return SavedPasswordEntry at index.
-     */
-    SavedPasswordEntry getSavedPasswordEntry(int index);
-
-    /**
-     * Get saved password exception at index.
-     *
-     * @param index of exception
-     * @return Origin of password exception.
-     */
-    String getSavedPasswordException(int index);
-
-    /**
-     * Remove saved password entry at index.
-     *
-     * @param index of password entry to remove.
-     */
-    void removeSavedPasswordEntry(int index);
-
-    /**
-     * Remove saved exception entry at index.
-     *
-     * @param index of exception entry.
-     */
-    void removeSavedPasswordException(int index);
-
-    /**
-     * Trigger serializing the saved passwords in the background.
-     *
-     * @param targetPath is the file to which the serialized passwords should be written.
-     * @param successCallback is called on successful completion, with the count of the serialized
-     * passwords and the path to the file containing them as argument.
-     * @param errorCallback is called on failure, with the error message as argument.
-     */
-    void serializePasswords(
-            String targetPath, IntStringCallback successCallback, Callback<String> errorCallback);
-
-    /**
-     * Show the UI that allows to edit saved credentials.
-     *
-     * @param context the current Activity to launch the edit view from, or an application context
-     *     if no Activity is available.
-     * @param index the index of the password entry to edit
-     * @param isBlockedCredential whether this credential is blocked for saving
-     */
-    void showPasswordEntryEditingView(Context context, int index, boolean isBlockedCredential);
-
-    /**
-     * Calls C++ to check whether the PasswordManagerHandler is still waiting for the passwords to
-     * be fetched from the password store.
-     *
-     * @return Returns true if the request to fetch the passwords is still pending.
-     */
-    boolean isWaitingForPasswordStore();
-}
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordManagerHandlerProvider.java b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordManagerHandlerProvider.java
deleted file mode 100644
index 1b5da0ff5..0000000
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordManagerHandlerProvider.java
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2017 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.password_manager.settings;
-
-import static org.chromium.build.NullUtil.assumeNonNull;
-
-import org.chromium.base.ObserverList;
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.lifetime.Destroyable;
-import org.chromium.build.annotations.NullMarked;
-import org.chromium.build.annotations.Nullable;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.profiles.ProfileKeyedMap;
-
-/**
- * A provider for PasswordManagerHandler implementations, handling the choice of the proper one
- * (production vs. testing), its lifetime and multiple observers.
- *
- * <p>This class is used by the code responsible for Chrome's passwords settings. There can only be
- * one instance of Chrome's passwords settings opened at a time (although more clients of
- * PasswordManagerHandler can live as nested settings pages).
- */
-@NullMarked
-public class PasswordManagerHandlerProvider implements PasswordListObserver, Destroyable {
-    private static @Nullable ProfileKeyedMap<PasswordManagerHandlerProvider> sProfileMap;
-
-    /** Return the {@link PasswordManagerHandlerProvider} for the given {@link Profile}. */
-    public static PasswordManagerHandlerProvider getForProfile(Profile profile) {
-        if (sProfileMap == null) {
-            sProfileMap =
-                    ProfileKeyedMap.createMapOfDestroyables(
-                            ProfileKeyedMap.ProfileSelection.REDIRECTED_TO_ORIGINAL);
-        }
-        return sProfileMap.getForProfile(profile, PasswordManagerHandlerProvider::new);
-    }
-
-    private final Profile mProfile;
-
-    // The production implementation of PasswordManagerHandler is |sPasswordUiView|, instantiated on
-    // demand. Tests might want to override that by providing a fake implementation through
-    // setPasswordManagerHandlerForTest, which is then kept in |mTestPasswordManagerHandler|.
-    private @Nullable PasswordUiView mPasswordUiView;
-    private @Nullable PasswordManagerHandler mTestPasswordManagerHandler;
-
-    // This class is itself a PasswordListObserver, listening directly to a PasswordManagerHandler
-    // implementation. But it also keeps a list of other observers, to which it forwards the events.
-    private final ObserverList<PasswordListObserver> mObservers = new ObserverList<>();
-
-    private PasswordManagerHandlerProvider(Profile profile) {
-        mProfile = profile;
-    }
-
-    /**
-     * Sets a testing implementation of PasswordManagerHandler to be used. It overrides the
-     * production one even if it exists. The caller needs to ensure that |this| becomes an observer
-     * of |passwordManagerHandler|. Also, this must not be called when there are already some
-     * observers in |mObservers|, because of special handling of the production implementation of
-     * PasswordManagerHandler on removing the last observer.
-     */
-    public void setPasswordManagerHandlerForTest(PasswordManagerHandler passwordManagerHandler) {
-        ThreadUtils.assertOnUiThread();
-        assert mObservers.isEmpty();
-        mTestPasswordManagerHandler = passwordManagerHandler;
-    }
-
-    /**
-     * Resets the testing implementation of PasswordManagerHandler, clears all observers and ensures
-     * that the view is cleaned up properly.
-     */
-    public void resetPasswordManagerHandlerForTest() {
-        ThreadUtils.assertOnUiThread();
-        mObservers.clear();
-        mTestPasswordManagerHandler = null;
-        if (mPasswordUiView != null) {
-            mPasswordUiView.destroy();
-            mPasswordUiView = null;
-        }
-    }
-
-    @Override
-    public void destroy() {
-        if (mPasswordUiView != null) {
-            mPasswordUiView.destroy();
-            mPasswordUiView = null;
-        }
-    }
-
-    /**
-     * A convenience function to choose between the production and test PasswordManagerHandler
-     * implementation.
-     */
-    public @Nullable PasswordManagerHandler getPasswordManagerHandler() {
-        ThreadUtils.assertOnUiThread();
-        if (mTestPasswordManagerHandler != null) return mTestPasswordManagerHandler;
-        return mPasswordUiView;
-    }
-
-    /**
-     * This method creates the production implementation of PasswordManagerHandler and saves it into
-     * mPasswordUiView.
-     */
-    private void createPasswordManagerHandler() {
-        ThreadUtils.assertOnUiThread();
-        assert mPasswordUiView == null;
-        mPasswordUiView = new PasswordUiView(this, mProfile);
-    }
-
-    /** Starts forwarding events from the PasswordManagerHandler implementation to |observer|. */
-    public void addObserver(PasswordListObserver observer) {
-        ThreadUtils.assertOnUiThread();
-        if (getPasswordManagerHandler() == null) createPasswordManagerHandler();
-        mObservers.addObserver(observer);
-    }
-
-    public void removeObserver(PasswordListObserver observer) {
-        ThreadUtils.assertOnUiThread();
-        mObservers.removeObserver(observer);
-        // If this was the last observer of the production implementation of PasswordManagerHandler,
-        // call destroy on it to close the connection to the native C++ code.
-        if (mObservers.isEmpty() && mTestPasswordManagerHandler == null) {
-            assumeNonNull(mPasswordUiView);
-            mPasswordUiView.destroy();
-            mPasswordUiView = null;
-        }
-    }
-
-    @Override
-    public void passwordListAvailable(int count) {
-        ThreadUtils.assertOnUiThread();
-        for (PasswordListObserver observer : mObservers) {
-            observer.passwordListAvailable(count);
-        }
-    }
-
-    @Override
-    public void passwordExceptionListAvailable(int count) {
-        ThreadUtils.assertOnUiThread();
-        for (PasswordListObserver observer : mObservers) {
-            observer.passwordExceptionListAvailable(count);
-        }
-    }
-}
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordUiView.java b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordUiView.java
deleted file mode 100644
index 3ecf4fca..0000000
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordUiView.java
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright 2013 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.password_manager.settings;
-
-import android.content.Context;
-
-import org.jni_zero.CalledByNative;
-import org.jni_zero.JniType;
-import org.jni_zero.NativeMethods;
-
-import org.chromium.base.Callback;
-import org.chromium.base.IntStringCallback;
-import org.chromium.build.annotations.NullMarked;
-import org.chromium.chrome.browser.profiles.Profile;
-
-/**
- * Production implementation of PasswordManagerHandler, making calls to native C++ code to retrieve
- * the data.
- */
-@NullMarked
-public final class PasswordUiView implements PasswordManagerHandler {
-    @CalledByNative
-    private static SavedPasswordEntry createSavedPasswordEntry(
-            @JniType("std::string") String url,
-            @JniType("std::u16string") String name,
-            @JniType("std::u16string") String password) {
-        return new SavedPasswordEntry(url, name, password);
-    }
-
-    // Pointer to native implementation, set to 0 in destroy().
-    private long mNativePasswordUiViewAndroid;
-
-    // This class has exactly one observer, set on construction and expected to last at least as
-    // long as this object (a good candidate is the owner of this object).
-    private final PasswordListObserver mObserver;
-
-    /**
-     * Constructor creates the native object as well. Callers should call destroy() after usage.
-     *
-     * @param observer The only observer.
-     * @param profile The {@link Profile} associated with these passwords.
-     */
-    public PasswordUiView(PasswordListObserver observer, Profile profile) {
-        mNativePasswordUiViewAndroid = PasswordUiViewJni.get().init(this, profile);
-        mObserver = observer;
-    }
-
-    @CalledByNative
-    private void passwordListAvailable(int count) {
-        mObserver.passwordListAvailable(count);
-    }
-
-    @CalledByNative
-    private void passwordExceptionListAvailable(int count) {
-        mObserver.passwordExceptionListAvailable(count);
-    }
-
-    @Override
-    public void insertPasswordEntryForTesting(String origin, String username, String password) {
-        PasswordUiViewJni.get()
-                .insertPasswordEntryForTesting(
-                        mNativePasswordUiViewAndroid, origin, username, password);
-    }
-
-    // Calls native to refresh password and exception lists. The native code calls back into
-    // passwordListAvailable and passwordExceptionListAvailable.
-    @Override
-    public void updatePasswordLists() {
-        PasswordUiViewJni.get().updatePasswordLists(mNativePasswordUiViewAndroid);
-    }
-
-    @Override
-    public SavedPasswordEntry getSavedPasswordEntry(int index) {
-        return PasswordUiViewJni.get().getSavedPasswordEntry(mNativePasswordUiViewAndroid, index);
-    }
-
-    @Override
-    public String getSavedPasswordException(int index) {
-        return PasswordUiViewJni.get()
-                .getSavedPasswordException(mNativePasswordUiViewAndroid, index);
-    }
-
-    @Override
-    public void removeSavedPasswordEntry(int index) {
-        PasswordUiViewJni.get().handleRemoveSavedPasswordEntry(mNativePasswordUiViewAndroid, index);
-    }
-
-    @Override
-    public void removeSavedPasswordException(int index) {
-        PasswordUiViewJni.get()
-                .handleRemoveSavedPasswordException(mNativePasswordUiViewAndroid, index);
-    }
-
-    @Override
-    public void serializePasswords(
-            String targetPath, IntStringCallback successCallback, Callback<String> errorCallback) {
-        PasswordUiViewJni.get()
-                .handleSerializePasswords(
-                        mNativePasswordUiViewAndroid, targetPath, successCallback, errorCallback);
-    }
-
-    @Override
-    public void showPasswordEntryEditingView(
-            Context context, int index, boolean isBlockedCredential) {
-        if (isBlockedCredential) {
-            PasswordUiViewJni.get()
-                    .handleShowBlockedCredentialView(mNativePasswordUiViewAndroid, context, index);
-            return;
-        }
-        PasswordUiViewJni.get()
-                .handleShowPasswordEntryEditingView(mNativePasswordUiViewAndroid, context, index);
-    }
-
-    /**
-     * Returns the URL for the website for managing one's passwords without the need to use Chrome
-     * with the user's profile signed in.
-     *
-     * @return The string with the URL.
-     */
-    public static String getAccountDashboardURL() {
-        return PasswordUiViewJni.get().getAccountDashboardURL();
-    }
-
-    /**
-     * Returns the URL of the help center article about trusted vault encryption.
-     *
-     * @return The string with the URL.
-     */
-    public static String getTrustedVaultLearnMoreURL() {
-        return PasswordUiViewJni.get().getTrustedVaultLearnMoreURL();
-    }
-
-    @Override
-    public boolean isWaitingForPasswordStore() {
-        return PasswordUiViewJni.get().isWaitingForPasswordStore(mNativePasswordUiViewAndroid);
-    }
-
-    /** Destroy the native object. */
-    public void destroy() {
-        if (mNativePasswordUiViewAndroid != 0) {
-            PasswordUiViewJni.get().destroy(mNativePasswordUiViewAndroid);
-            mNativePasswordUiViewAndroid = 0;
-        }
-    }
-
-    @NativeMethods
-    interface Natives {
-        long init(PasswordUiView self, @JniType("Profile*") Profile profile);
-
-        void insertPasswordEntryForTesting(
-                long nativePasswordUiViewAndroid,
-                @JniType("std::u16string") String origin,
-                @JniType("std::u16string") String username,
-                @JniType("std::u16string") String password);
-
-        void updatePasswordLists(long nativePasswordUiViewAndroid);
-
-        SavedPasswordEntry getSavedPasswordEntry(long nativePasswordUiViewAndroid, int index);
-
-        @JniType("std::string")
-        String getSavedPasswordException(long nativePasswordUiViewAndroid, int index);
-
-        void handleRemoveSavedPasswordEntry(long nativePasswordUiViewAndroid, int index);
-
-        void handleRemoveSavedPasswordException(long nativePasswordUiViewAndroid, int index);
-
-        @JniType("std::string")
-        String getAccountDashboardURL();
-
-        @JniType("std::string")
-        String getTrustedVaultLearnMoreURL();
-
-        boolean isWaitingForPasswordStore(long nativePasswordUiViewAndroid);
-
-        void destroy(long nativePasswordUiViewAndroid);
-
-        void handleSerializePasswords(
-                long nativePasswordUiViewAndroid,
-                @JniType("std::string") String targetPath,
-                IntStringCallback successCallback,
-                Callback<String> errorCallback);
-
-        void handleShowPasswordEntryEditingView(
-                long nativePasswordUiViewAndroid, Context context, int index);
-
-        void handleShowBlockedCredentialView(
-                long nativePasswordUiViewAndroid, Context context, int index);
-    }
-}
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/ProgressBarDialogFragment.java b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/ProgressBarDialogFragment.java
deleted file mode 100644
index a4312640..0000000
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/ProgressBarDialogFragment.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2018 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.password_manager.settings;
-import org.chromium.build.annotations.Initializer;
-import org.chromium.build.annotations.NullMarked;
-
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.view.View;
-
-import androidx.appcompat.app.AlertDialog;
-import androidx.fragment.app.DialogFragment;
-
-//import org.chromium.chrome.R;
-import org.chromium.chrome.browser.password_manager.R;
-import org.chromium.components.browser_ui.widget.MaterialProgressBar;
-import org.chromium.build.annotations.Nullable;
-
-/**
- * Shows the dialog that informs the user about the progress of preparing passwords for export and
- * allows the user to cancel that operation.
- */
-@NullMarked
-public class ProgressBarDialogFragment extends DialogFragment {
-    // This handler is used to perform the user-triggered cancellation of the password preparation.
-    private DialogInterface.OnClickListener mHandler;
-
-    @Initializer
-    public void setCancelProgressHandler(DialogInterface.OnClickListener handler) {
-        mHandler = handler;
-    }
-
-    /**
-     * Opens the dialog with the progress bar, hooks up the cancel button handler and sets the
-     * progress indicator to being indeterminate, because the background operation does not easily
-     * allow to signal its own progress.
-     */
-    @Override
-    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
-        View dialog =
-                getActivity().getLayoutInflater().inflate(R.layout.passwords_progress_dialog, null);
-        MaterialProgressBar bar = dialog.findViewById(R.id.passwords_progress_bar);
-        bar.setIndeterminate(true);
-        return new AlertDialog.Builder(
-                        getActivity(), R.style.ThemeOverlay_BrowserUI_AlertDialog_NoActionBar)
-                .setView(dialog)
-                .setNegativeButton(R.string.cancel, mHandler)
-                .setTitle(
-                        getActivity()
-                                .getResources()
-                                .getString(R.string.settings_passwords_preparing_export))
-                .create();
-    }
-
-    @Override
-    public void onCreate(@Nullable Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        // If there is a |savedInstanceState|, then the dialog is being recreated
-        // by Android and will lack the necessary click handler. Dismiss
-        // immediately, the settings page will recreate it with the appropriate
-        // click handler.
-        if (savedInstanceState != null) {
-            dismiss();
-            return;
-        }
-    }
-}
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/SavedPasswordEntry.java b/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/SavedPasswordEntry.java
deleted file mode 100644
index 7a42dad..0000000
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/SavedPasswordEntry.java
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2017 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.password_manager.settings;
-
-import org.chromium.build.annotations.NullMarked;
-
-/**
- * A class representing information about a saved password entry in Chrome's settngs.
- *
- * <p>Note: This could be a nested class in the PasswordManagerHandler interface, but that would
- * mean that PasswordUiView, which implements that interface and references SavedPasswordEntry in
- * some of its JNI-registered methods, would need an explicit import of PasswordManagerHandler. That
- * again would violate our presubmit checks, and https://crbug.com/424792 indicates that the
- * preferred solution is to move the nested class to top-level.
- */
-@NullMarked
-public final class SavedPasswordEntry {
-    private final String mUrl;
-    private final String mName;
-    private final String mPassword;
-
-    public SavedPasswordEntry(String url, String name, String password) {
-        mUrl = url;
-        mName = name;
-        mPassword = password;
-    }
-
-    public String getUrl() {
-        return mUrl;
-    }
-
-    public String getUserName() {
-        return mName;
-    }
-
-    public String getPassword() {
-        return mPassword;
-    }
-}
diff --git a/chrome/browser/password_manager/android/junit/src/org/chromium/chrome/browser/password_manager/settings/ReauthenticationManagerTest.java b/chrome/browser/password_manager/android/junit/src/org/chromium/chrome/browser/password_manager/settings/ReauthenticationManagerTest.java
index 6295521..88ec374 100644
--- a/chrome/browser/password_manager/android/junit/src/org/chromium/chrome/browser/password_manager/settings/ReauthenticationManagerTest.java
+++ b/chrome/browser/password_manager/android/junit/src/org/chromium/chrome/browser/password_manager/settings/ReauthenticationManagerTest.java
@@ -151,7 +151,7 @@
                         ReauthenticationManager.ReauthScope.BULK));
 
         ReauthenticationManager.displayReauthenticationFragment(
-                R.string.lockscreen_description_export,
+                R.string.lockscreen_description_view,
                 View.NO_ID,
                 mFragmentManager,
                 ReauthenticationManager.ReauthScope.BULK);
diff --git a/chrome/browser/password_manager/android/one_time_passwords/BUILD.gn b/chrome/browser/password_manager/android/one_time_passwords/BUILD.gn
index be9827a..5dbdbc1 100644
--- a/chrome/browser/password_manager/android/one_time_passwords/BUILD.gn
+++ b/chrome/browser/password_manager/android/one_time_passwords/BUILD.gn
@@ -23,7 +23,7 @@
     "//base",
     "//chrome/browser/profiles:profile",
     "//components/keyed_service/core",
-    "//components/password_manager/core/browser:browser",
+    "//components/password_manager/core/browser",
     "//content/public/browser",
   ]
 }
diff --git a/chrome/browser/password_manager/android/password_ui_view_android.cc b/chrome/browser/password_manager/android/password_ui_view_android.cc
deleted file mode 100644
index b56304b..0000000
--- a/chrome/browser/password_manager/android/password_ui_view_android.cc
+++ /dev/null
@@ -1,365 +0,0 @@
-// Copyright 2013 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/password_manager/android/password_ui_view_android.h"
-
-#include <algorithm>
-#include <memory>
-#include <vector>
-
-#include "base/android/callback_android.h"
-#include "base/android/int_string_callback.h"
-#include "base/android/jni_string.h"
-#include "base/android/jni_weak_ref.h"
-#include "base/android/scoped_java_ref.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_helpers.h"
-#include "base/logging.h"
-#include "base/metrics/field_trial.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/user_metrics.h"
-#include "base/metrics/user_metrics_action.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/task/thread_pool.h"
-#include "base/threading/scoped_blocking_call.h"
-#include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/common/url_constants.h"
-#include "chrome/grit/generated_resources.h"
-#include "components/password_manager/core/browser/export/password_csv_writer.h"
-#include "components/password_manager/core/browser/form_parsing/form_data_parser.h"
-#include "components/password_manager/core/browser/leak_detection/leak_detection_check_impl.h"
-#include "components/password_manager/core/browser/password_form.h"
-#include "components/password_manager/core/browser/password_ui_utils.h"
-#include "components/password_manager/core/browser/ui/credential_provider_interface.h"
-#include "components/password_manager/core/browser/ui/credential_ui_entry.h"
-#include "content/public/browser/browser_thread.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "url/gurl.h"
-
-// Must come after other includes, because FromJniType() uses Profile.
-#include "chrome/browser/password_manager/android/jni_headers/PasswordUiView_jni.h"
-
-namespace {
-
-using base::android::JavaParamRef;
-using base::android::JavaRef;
-using base::android::ScopedJavaLocalRef;
-using IsInsecureCredential = CredentialEditBridge::IsInsecureCredential;
-
-PasswordUiViewAndroid::SerializationResult SerializePasswords(
-    const base::FilePath& target_directory,
-    std::vector<password_manager::CredentialUIEntry> credentials) {
-  // The UI should not trigger serialization if there are no passwords.
-  base::UmaHistogramBoolean(
-      "PasswordManager.ExportAndroid.MoreThanZeroPasswords",
-      credentials.size() > 0);
-
-  // Creating a file will block the execution on I/O.
-  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
-                                                base::BlockingType::WILL_BLOCK);
-
-  // Ensure that the target directory exists.
-  base::File::Error error = base::File::FILE_OK;
-  if (!base::CreateDirectoryAndGetError(target_directory, &error)) {
-    base::UmaHistogramExactLinear(
-        "PasswordManager.ExportAndroid.CreateDirectoryError", -error,
-        -base::File::Error::FILE_ERROR_MAX);
-    return {0, std::string(), base::File::ErrorToString(error)};
-  }
-
-  // Create a temporary file in the target directory to hold the serialized
-  // passwords.
-  base::FilePath export_file;
-  if (!base::CreateTemporaryFileInDir(target_directory, &export_file)) {
-    logging::SystemErrorCode error_code = logging::GetLastSystemErrorCode();
-    base::UmaHistogramExactLinear(
-        "PasswordManager.ExportAndroid.CreateTempFileError",
-        -base::File::OSErrorToFileError(error_code),
-        -base::File::Error::FILE_ERROR_MAX);
-    return {0, std::string(), logging::SystemErrorCodeToString(error_code)};
-  }
-
-  // Write the serialized data in CSV.
-  std::string data =
-      password_manager::PasswordCSVWriter::SerializePasswords(credentials);
-  if (!base::WriteFile(export_file, data)) {
-    logging::SystemErrorCode error_code = logging::GetLastSystemErrorCode();
-    base::UmaHistogramExactLinear(
-        "PasswordManager.ExportAndroid.WriteToTempFileError",
-        -base::File::OSErrorToFileError(error_code),
-        -base::File::Error::FILE_ERROR_MAX);
-    return {0, std::string(), logging::SystemErrorCodeToString(error_code)};
-  }
-
-  return {static_cast<int>(credentials.size()), export_file.value(),
-          std::string()};
-}
-
-}  // namespace
-
-PasswordUiViewAndroid::PasswordUiViewAndroid(
-    JNIEnv* env,
-    const jni_zero::JavaRef<jobject>& obj,
-    Profile* profile)
-    : profile_(profile),
-      profile_store_(ProfilePasswordStoreFactory::GetForProfile(
-          profile,
-          ServiceAccessType::EXPLICIT_ACCESS)),
-      saved_passwords_presenter_(
-          AffiliationServiceFactory::GetForProfile(profile),
-          profile_store_,
-          AccountPasswordStoreFactory::GetForProfile(
-              profile,
-              ServiceAccessType::EXPLICIT_ACCESS)),
-      weak_java_ui_controller_(env, obj) {
-  saved_passwords_presenter_.AddObserver(this);
-  saved_passwords_presenter_.Init();
-}
-
-PasswordUiViewAndroid::~PasswordUiViewAndroid() {
-  saved_passwords_presenter_.RemoveObserver(this);
-}
-
-void PasswordUiViewAndroid::Destroy(JNIEnv* env) {
-  switch (state_) {
-    case State::ALIVE:
-      delete this;
-      break;
-    case State::ALIVE_SERIALIZATION_PENDING:
-      // Postpone the deletion until the pending tasks are completed, so that
-      // the tasks do not attempt a use after free while reading data from
-      // |this|.
-      state_ = State::DELETION_PENDING;
-      break;
-    case State::DELETION_PENDING:
-      NOTREACHED();
-  }
-}
-
-void PasswordUiViewAndroid::InsertPasswordEntryForTesting(
-    JNIEnv* env,
-    const std::u16string& origin,
-    const std::u16string& username,
-    const std::u16string& password) {
-  password_manager::PasswordForm form;
-  form.url = GURL(origin);
-  form.signon_realm = password_manager::GetSignonRealm(form.url);
-  form.username_value = username;
-  form.password_value = password;
-
-  profile_store_->AddLogin(form);
-}
-
-void PasswordUiViewAndroid::UpdatePasswordLists(JNIEnv* env) {
-  DCHECK_EQ(State::ALIVE, state_);
-  UpdatePasswordLists();
-}
-
-ScopedJavaLocalRef<jobject> PasswordUiViewAndroid::GetSavedPasswordEntry(
-    JNIEnv* env,
-    int index) {
-  DCHECK_EQ(State::ALIVE, state_);
-  if (static_cast<size_t>(index) >= passwords_.size()) {
-    return Java_PasswordUiView_createSavedPasswordEntry(
-        env, std::string(), std::u16string(), std::u16string());
-  }
-  return Java_PasswordUiView_createSavedPasswordEntry(
-      env, password_manager::GetShownOrigin(passwords_[index]),
-      passwords_[index].username, passwords_[index].password);
-}
-
-std::string PasswordUiViewAndroid::GetSavedPasswordException(JNIEnv* env,
-                                                             int index) {
-  DCHECK_EQ(State::ALIVE, state_);
-  if (static_cast<size_t>(index) >= blocked_sites_.size()) {
-    return "";
-  }
-  return password_manager::GetShownOrigin(blocked_sites_[index]);
-}
-
-void PasswordUiViewAndroid::HandleRemoveSavedPasswordEntry(JNIEnv* env,
-                                                           int index) {
-  DCHECK_EQ(State::ALIVE, state_);
-  if (static_cast<size_t>(index) >= passwords_.size()) {
-    return;
-  }
-  if (saved_passwords_presenter_.RemoveCredential(passwords_[index])) {
-    base::RecordAction(
-        base::UserMetricsAction("PasswordManager_RemoveSavedPassword"));
-  }
-}
-
-void PasswordUiViewAndroid::HandleRemoveSavedPasswordException(JNIEnv* env,
-                                                               int index) {
-  DCHECK_EQ(State::ALIVE, state_);
-  if (static_cast<size_t>(index) >= passwords_.size()) {
-    return;
-  }
-  if (saved_passwords_presenter_.RemoveCredential(passwords_[index])) {
-    base::RecordAction(
-        base::UserMetricsAction("PasswordManager_RemovePasswordException"));
-  }
-}
-
-void PasswordUiViewAndroid::HandleSerializePasswords(
-    JNIEnv* env,
-    const std::string& java_target_directory,
-    const JavaRef<jobject>& success_callback,
-    const JavaRef<jobject>& error_callback) {
-  switch (state_) {
-    case State::ALIVE:
-      state_ = State::ALIVE_SERIALIZATION_PENDING;
-      break;
-    case State::ALIVE_SERIALIZATION_PENDING:
-      // The UI should not allow the user to re-request export before finishing
-      // or cancelling the pending one.
-      NOTREACHED();
-    case State::DELETION_PENDING:
-      // The Java part should not first request destroying of |this| and then
-      // ask |this| for serialized passwords.
-      NOTREACHED();
-  }
-  std::vector<password_manager::CredentialUIEntry> credentials =
-      saved_passwords_presenter_.GetSavedCredentials();
-  std::erase_if(credentials, [](const auto& credential) {
-    return credential.blocked_by_user;
-  });
-
-  // The tasks are posted with base::Unretained, because deletion is postponed
-  // until the reply arrives (look for the occurrences of DELETION_PENDING in
-  // this file). The background processing is not expected to take very long,
-  // but still long enough not to block the UI thread. The main concern here is
-  // not to avoid the background computation if |this| is about to be deleted
-  // but to simply avoid use after free from the background task runner.
-  base::ThreadPool::PostTaskAndReplyWithResult(
-      FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()},
-      base::BindOnce(&SerializePasswords, base::FilePath(java_target_directory),
-                     std::move(credentials)),
-      base::BindOnce(
-          &PasswordUiViewAndroid::PostSerializedPasswords,
-          base::Unretained(this),
-          base::android::ScopedJavaGlobalRef<jobject>(env, success_callback),
-          base::android::ScopedJavaGlobalRef<jobject>(env, error_callback)));
-}
-
-void PasswordUiViewAndroid::HandleShowPasswordEntryEditingView(
-    JNIEnv* env,
-    const JavaParamRef<jobject>& context,
-    int index) {
-  if (static_cast<size_t>(index) >= passwords_.size() ||
-      credential_edit_bridge_) {
-    return;
-  }
-  bool is_using_account_store = passwords_[index].stored_in.contains(
-      password_manager::PasswordForm::Store::kAccountStore);
-  credential_edit_bridge_ = CredentialEditBridge::MaybeCreate(
-      passwords_[index], IsInsecureCredential(false),
-      GetUsernamesForRealm(saved_passwords_presenter_.GetSavedCredentials(),
-                           passwords_[index].GetFirstSignonRealm(),
-                           is_using_account_store),
-      &saved_passwords_presenter_,
-      base::BindOnce(&PasswordUiViewAndroid::OnEditUIDismissed,
-                     base::Unretained(this)),
-      context);
-}
-
-void PasswordUiViewAndroid::HandleShowBlockedCredentialView(
-    JNIEnv* env,
-    const JavaParamRef<jobject>& context,
-    int index) {
-  if (static_cast<size_t>(index) >= blocked_sites_.size() ||
-      credential_edit_bridge_) {
-    return;
-  }
-  credential_edit_bridge_ = CredentialEditBridge::MaybeCreate(
-      blocked_sites_[index], IsInsecureCredential(false),
-      std::vector<std::u16string>(), &saved_passwords_presenter_,
-      base::BindOnce(&PasswordUiViewAndroid::OnEditUIDismissed,
-                     base::Unretained(this)),
-      context);
-}
-
-void PasswordUiViewAndroid::OnEditUIDismissed() {
-  credential_edit_bridge_.reset();
-}
-
-std::string JNI_PasswordUiView_GetAccountDashboardURL(JNIEnv* env) {
-  return l10n_util::GetStringUTF8(IDS_PASSWORDS_WEB_LINK);
-}
-
-std::string JNI_PasswordUiView_GetTrustedVaultLearnMoreURL(JNIEnv* env) {
-  return chrome::kSyncTrustedVaultLearnMoreURL;
-}
-
-jboolean PasswordUiViewAndroid::IsWaitingForPasswordStore(JNIEnv* env) {
-  return saved_passwords_presenter_.IsWaitingForPasswordStore();
-}
-
-// static
-static jlong JNI_PasswordUiView_Init(
-    JNIEnv* env,
-    const base::android::JavaParamRef<jobject>& obj,
-    Profile* profile) {
-  PasswordUiViewAndroid* controller =
-      new PasswordUiViewAndroid(env, obj, profile);
-  return reinterpret_cast<intptr_t>(controller);
-}
-
-void PasswordUiViewAndroid::OnSavedPasswordsChanged(
-    const password_manager::PasswordStoreChangeList& changes) {
-  UpdatePasswordLists();
-}
-
-void PasswordUiViewAndroid::UpdatePasswordLists() {
-  passwords_.clear();
-  blocked_sites_.clear();
-  for (auto& credential : saved_passwords_presenter_.GetSavedCredentials()) {
-    if (credential.blocked_by_user) {
-      blocked_sites_.push_back(std::move(credential));
-    } else {
-      passwords_.push_back(std::move(credential));
-    }
-  }
-  JNIEnv* env = base::android::AttachCurrentThread();
-  ScopedJavaLocalRef<jobject> ui_controller = weak_java_ui_controller_.get(env);
-  if (!ui_controller.is_null()) {
-    Java_PasswordUiView_passwordListAvailable(
-        env, ui_controller, static_cast<int>(passwords_.size()));
-    Java_PasswordUiView_passwordExceptionListAvailable(
-        env, ui_controller, static_cast<int>(blocked_sites_.size()));
-  }
-}
-
-void PasswordUiViewAndroid::PostSerializedPasswords(
-    const base::android::JavaRef<jobject>& success_callback,
-    const base::android::JavaRef<jobject>& error_callback,
-    SerializationResult serialization_result) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  switch (state_) {
-    case State::ALIVE:
-      NOTREACHED();
-    case State::ALIVE_SERIALIZATION_PENDING: {
-      state_ = State::ALIVE;
-      if (export_target_for_testing_) {
-        *export_target_for_testing_ = serialization_result;
-      } else {
-        if (serialization_result.entries_count) {
-          base::android::RunIntStringCallbackAndroid(
-              success_callback, serialization_result.entries_count,
-              serialization_result.exported_file_path);
-        } else {
-          base::android::RunStringCallbackAndroid(error_callback,
-                                                  serialization_result.error);
-        }
-      }
-      break;
-    }
-    case State::DELETION_PENDING:
-      delete this;
-      break;
-  }
-}
diff --git a/chrome/browser/password_manager/android/password_ui_view_android.h b/chrome/browser/password_manager/android/password_ui_view_android.h
deleted file mode 100644
index 64d4d29..0000000
--- a/chrome/browser/password_manager/android/password_ui_view_android.h
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2013 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_PASSWORD_UI_VIEW_ANDROID_H_
-#define CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_PASSWORD_UI_VIEW_ANDROID_H_
-
-#include <stddef.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/android/jni_weak_ref.h"
-#include "base/android/scoped_java_ref.h"
-#include "base/memory/raw_ptr.h"
-#include "chrome/browser/affiliations/affiliation_service_factory.h"
-#include "chrome/browser/password_entry_edit/android/credential_edit_bridge.h"
-#include "chrome/browser/password_manager/account_password_store_factory.h"
-#include "chrome/browser/password_manager/profile_password_store_factory.h"
-#include "chrome/browser/signin/identity_manager_factory.h"
-#include "components/password_manager/core/browser/password_store/password_store_consumer.h"
-#include "components/password_manager/core/browser/ui/saved_passwords_presenter.h"
-
-class Profile;
-
-namespace password_manager {
-class CredentialProviderInterface;
-}
-
-// PasswordUIView for Android, contains jni hooks that allows Android UI to
-// display passwords and route UI commands back to SavedPasswordsPresenter.
-class PasswordUiViewAndroid
-    : public password_manager::SavedPasswordsPresenter::Observer {
- public:
-  // Result of transforming a vector of PasswordForms into their CSV
-  // description and writing that to disk.
-  struct SerializationResult {
-    // The number of password entries written. 0 if error encountered.
-    int entries_count;
-
-    // The path to the temporary file containing the serialized passwords. Empty
-    // if error encountered.
-    std::string exported_file_path;
-
-    // The error description recorded after the last write operation. Empty if
-    // no error encountered.
-    std::string error;
-  };
-
-  PasswordUiViewAndroid(JNIEnv* env,
-                        const jni_zero::JavaRef<jobject>& obj,
-                        Profile* profile);
-
-  PasswordUiViewAndroid(const PasswordUiViewAndroid&) = delete;
-  PasswordUiViewAndroid& operator=(const PasswordUiViewAndroid&) = delete;
-
-  ~PasswordUiViewAndroid() override;
-
-  // Calls from Java.
-  base::android::ScopedJavaLocalRef<jobject> GetSavedPasswordEntry(
-      JNIEnv* env,
-      int index);
-  std::string GetSavedPasswordException(JNIEnv* env,
-                                        int index);
-  void InsertPasswordEntryForTesting(JNIEnv* env,
-                                     const std::u16string& origin,
-                                     const std::u16string& username,
-                                     const std::u16string& password);
-  void UpdatePasswordLists(JNIEnv* env);
-  void HandleRemoveSavedPasswordEntry(JNIEnv* env,
-                                      int index);
-  void HandleRemoveSavedPasswordException(
-      JNIEnv* env,
-      int index);
-  void HandleSerializePasswords(
-      JNIEnv* env,
-      const std::string& java_target_directory,
-      const base::android::JavaRef<jobject>& success_callback,
-      const base::android::JavaRef<jobject>& error_callback);
-  void HandleShowPasswordEntryEditingView(
-      JNIEnv* env,
-      const base::android::JavaParamRef<jobject>& context,
-      int index);
-  void HandleShowBlockedCredentialView(
-      JNIEnv* env,
-      const base::android::JavaParamRef<jobject>& context,
-      int index);
-  jboolean IsWaitingForPasswordStore(JNIEnv* env);
-  // Destroy the native implementation.
-  void Destroy(JNIEnv*);
-
-  void OnEditUIDismissed();
-
-  void set_export_target_for_testing(
-      SerializationResult* export_target_for_testing) {
-    export_target_for_testing_ = export_target_for_testing;
-  }
-
-  void set_credential_provider_for_testing(
-      password_manager::CredentialProviderInterface* provider) {
-    credential_provider_for_testing_ = provider;
-  }
-
- private:
-  // Possible states in the life of PasswordUiViewAndroid.
-  // ALIVE:
-  //   * Destroy was not called and no background tasks are pending.
-  //   * All data members can be used on the main task runner.
-  // ALIVE_SERIALIZATION_PENDING:
-  //   * Destroy was not called, password serialization task on another task
-  //     runner is running.
-  //   * All data members can be used on the main task runner, except for
-  //     |saved_passwords_presenter_| which can only be used inside
-  //     ObtainAndSerializePasswords, which is being run on a backend task
-  //     runner.
-  // DELETION_PENDING:
-  //   * Destroy() was called, a background task is pending and |this| should
-  //     be deleted once the tasks complete.
-  //   * This state should not be reached anywhere but in the completion call
-  //     of the pending task.
-  enum class State { ALIVE, ALIVE_SERIALIZATION_PENDING, DELETION_PENDING };
-
-  // password_manager::SavedPasswordsPresenter::Observer implementation.
-  void OnSavedPasswordsChanged(
-      const password_manager::PasswordStoreChangeList& changes) override;
-
-  void UpdatePasswordLists();
-
-  // Sends |serialization_result| to Java via |success_callback| or
-  // |error_callback|, depending on whether the result is a success or an error.
-  void PostSerializedPasswords(
-      const base::android::JavaRef<jobject>& success_callback,
-      const base::android::JavaRef<jobject>& error_callback,
-      SerializationResult serialization_result);
-
-  // The |state_| must only be accessed on the main task runner.
-  State state_ = State::ALIVE;
-
-  // If not null, PostSerializedPasswords will write the serialized passwords to
-  // |*export_target_for_testing_| instead of passing them to Java. This must
-  // remain null in production code.
-  raw_ptr<SerializationResult> export_target_for_testing_ = nullptr;
-
-  raw_ptr<Profile> profile_;
-
-  // Pointer to the password store, powering |saved_passwords_presenter_|.
-  scoped_refptr<password_manager::PasswordStoreInterface> profile_store_;
-
-  // Manages the list of saved passwords, including updates.
-  password_manager::SavedPasswordsPresenter saved_passwords_presenter_;
-
-  // Cached passwords and blocked sites.
-  std::vector<password_manager::CredentialUIEntry> passwords_;
-  std::vector<password_manager::CredentialUIEntry> blocked_sites_;
-
-  // If not null, passwords for exporting will be obtained from
-  // |*credential_provider_for_testing_|, otherwise from
-  // |saved_passwords_presenter_|. This must remain null in production code.
-  raw_ptr<password_manager::CredentialProviderInterface>
-      credential_provider_for_testing_ = nullptr;
-
-  // Java side of UI controller.
-  JavaObjectWeakGlobalRef weak_java_ui_controller_;
-
-  // Used to open the view/edit/delete UI.
-  std::unique_ptr<CredentialEditBridge> credential_edit_bridge_;
-};
-
-#endif  // CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_PASSWORD_UI_VIEW_ANDROID_H_
diff --git a/chrome/browser/password_manager/android/password_ui_view_android_unittest.cc b/chrome/browser/password_manager/android/password_ui_view_android_unittest.cc
deleted file mode 100644
index 26acb30..0000000
--- a/chrome/browser/password_manager/android/password_ui_view_android_unittest.cc
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright 2017 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/password_manager/android/password_ui_view_android.h"
-
-#include <jni.h>
-
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/android/jni_android.h"
-#include "base/android/jni_string.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/memory/raw_ptr.h"
-#include "base/run_loop.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/types/fixed_array.h"
-#include "chrome/browser/password_manager/password_manager_test_util.h"
-#include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/profiles/profiles_state.h"
-#include "chrome/test/base/testing_browser_process.h"
-#include "chrome/test/base/testing_profile.h"
-#include "chrome/test/base/testing_profile_manager.h"
-#include "components/password_manager/core/browser/export/password_csv_writer.h"
-#include "components/password_manager/core/browser/password_form.h"
-#include "components/password_manager/core/browser/password_store/test_password_store.h"
-#include "components/password_manager/core/browser/ui/credential_ui_entry.h"
-#include "content/public/test/browser_task_environment.h"
-#include "content/public/test/test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-namespace android {
-
-using base::android::AttachCurrentThread;
-using base::android::JavaParamRef;
-using password_manager::PasswordForm;
-using password_manager::TestPasswordStore;
-
-namespace {
-
-// Specific deleter for PasswordUiViewAndroid, which calls
-// PasswordUiViewAndroid::Destroy on the object. Use this with a
-// std::unique_ptr.
-struct PasswordUiViewAndroidDestroyDeleter {
-  inline void operator()(void* ptr) const {
-    (static_cast<PasswordUiViewAndroid*>(ptr)->Destroy(nullptr));
-  }
-};
-
-}  // namespace
-
-class PasswordUiViewAndroidTest : public ::testing::Test {
- protected:
-  PasswordUiViewAndroidTest()
-      : testing_profile_manager_(TestingBrowserProcess::GetGlobal()),
-        env_(AttachCurrentThread()) {}
-
-  void SetUp() override {
-    ASSERT_TRUE(testing_profile_manager_.SetUp());
-    testing_profile_ =
-        testing_profile_manager_.CreateTestingProfile("TestProfile");
-    profiles::SetLastUsedProfile(testing_profile_->GetBaseName());
-
-    store_ = CreateAndUseTestPasswordStore(testing_profile_);
-    store_->Init(/*prefs=*/nullptr, /*affiliated_match_helper=*/nullptr);
-    ASSERT_TRUE(temp_dir().CreateUniqueTempDir());
-  }
-
-  void TearDown() override {
-    store_->ShutdownOnUIThread();
-    RunUntilIdle();
-  }
-
-  PasswordForm AddPasswordEntry(const std::string& origin,
-                                const std::string& username,
-                                const std::string& password) {
-    PasswordForm form;
-    form.url = GURL(origin);
-    form.signon_realm = origin;
-    form.username_value = base::UTF8ToUTF16(username);
-    form.password_value = base::UTF8ToUTF16(password);
-    store_->AddLogin(form);
-    RunUntilIdle();
-    return form;
-  }
-
-  void RunUntilIdle() { task_environment_.RunUntilIdle(); }
-
-  raw_ptr<JNIEnv> env() { return env_; }
-  base::ScopedTempDir& temp_dir() { return temp_dir_; }
-
- protected:
-  raw_ptr<TestingProfile> testing_profile_;
-
- private:
-  content::BrowserTaskEnvironment task_environment_;
-  TestingProfileManager testing_profile_manager_;
-  scoped_refptr<TestPasswordStore> store_;
-  raw_ptr<JNIEnv> env_;
-  base::ScopedTempDir temp_dir_;
-};
-
-// Test that the asynchronous processing of password serialization controlled by
-// PasswordUiViewAndroid arrives at the same result as synchronous way to
-// serialize the passwords.
-TEST_F(PasswordUiViewAndroidTest, GetSerializedPasswords) {
-  PasswordForm form =
-      AddPasswordEntry("https://example.com", "username", "password");
-
-  // Let the PasswordCSVWriter compute the result instead of hard-coding it,
-  // because this test focuses on PasswordUIView and not on detecting changes in
-  // PasswordCSVWriter.
-  const std::string expected_result =
-      password_manager::PasswordCSVWriter::SerializePasswords(
-          {password_manager::CredentialUIEntry(form)});
-
-  std::unique_ptr<PasswordUiViewAndroid, PasswordUiViewAndroidDestroyDeleter>
-      password_ui_view(new PasswordUiViewAndroid(
-          env(), JavaParamRef<jobject>(nullptr), testing_profile_));
-  // SavedPasswordsPresenter needs time to initialize and fetch passwords.
-  RunUntilIdle();
-
-  PasswordUiViewAndroid::SerializationResult serialized_passwords;
-  password_ui_view->set_export_target_for_testing(&serialized_passwords);
-  password_ui_view->HandleSerializePasswords(
-      env(), temp_dir().GetPath().AsUTF8Unsafe(), nullptr, nullptr);
-
-  content::RunAllTasksUntilIdle();
-  // The buffer for actual result is 1 byte longer than the expected data to be
-  // able to detect when the actual data are too long.
-  base::FixedArray<char> actual_result(expected_result.size() + 1);
-  int number_of_bytes_read = base::ReadFile(
-      base::FilePath::FromUTF8Unsafe(serialized_passwords.exported_file_path),
-      actual_result.data(), expected_result.size() + 1);
-  EXPECT_EQ(static_cast<int>(expected_result.size()), number_of_bytes_read);
-  EXPECT_EQ(expected_result,
-            std::string(actual_result.data(),
-                        (number_of_bytes_read < 0) ? 0 : number_of_bytes_read));
-  EXPECT_EQ(1, serialized_passwords.entries_count);
-  EXPECT_FALSE(serialized_passwords.exported_file_path.empty());
-  EXPECT_EQ(std::string(), serialized_passwords.error);
-}
-
-// Test that destroying the PasswordUIView when tasks are pending does not lead
-// to crashes.
-TEST_F(PasswordUiViewAndroidTest, GetSerializedPasswords_Cancelled) {
-  AddPasswordEntry("https://example.com", "username", "password");
-
-  std::unique_ptr<PasswordUiViewAndroid, PasswordUiViewAndroidDestroyDeleter>
-      password_ui_view(new PasswordUiViewAndroid(
-          env(), JavaParamRef<jobject>(nullptr), testing_profile_));
-  // SavedPasswordsPresenter needs time to initialize and fetch passwords.
-  RunUntilIdle();
-
-  PasswordUiViewAndroid::SerializationResult serialized_passwords;
-  serialized_passwords.entries_count = 123;
-  serialized_passwords.exported_file_path = "somepath";
-  password_ui_view->set_export_target_for_testing(&serialized_passwords);
-  password_ui_view->HandleSerializePasswords(
-      env(), temp_dir().GetPath().AsUTF8Unsafe(), nullptr, nullptr);
-  // Register the PasswordUIView for deletion. It should not destruct itself
-  // before the background tasks are run. The results of the background tasks
-  // are waited for and then thrown out, so |serialized_passwords| should not be
-  // overwritten.
-  password_ui_view.reset();
-  // Now run the background tasks (and the subsequent deletion).
-  content::RunAllTasksUntilIdle();
-  EXPECT_EQ(123, serialized_passwords.entries_count);
-  EXPECT_EQ("somepath", serialized_passwords.exported_file_path);
-  EXPECT_EQ(std::string(), serialized_passwords.error);
-}
-
-// Test that an I/O error is reported.
-TEST_F(PasswordUiViewAndroidTest, GetSerializedPasswords_WriteFailed) {
-  AddPasswordEntry("https://example.com", "username", "password");
-
-  std::unique_ptr<PasswordUiViewAndroid, PasswordUiViewAndroidDestroyDeleter>
-      password_ui_view(new PasswordUiViewAndroid(
-          env(), JavaParamRef<jobject>(nullptr), testing_profile_));
-  // SavedPasswordsPresenter needs time to initialize and fetch passwords.
-  RunUntilIdle();
-
-  PasswordUiViewAndroid::SerializationResult serialized_passwords;
-  password_ui_view->set_export_target_for_testing(&serialized_passwords);
-  password_ui_view->HandleSerializePasswords(
-      env(), "/This directory cannot be created", nullptr, nullptr);
-  content::RunAllTasksUntilIdle();
-  EXPECT_EQ(0, serialized_passwords.entries_count);
-  EXPECT_FALSE(serialized_passwords.error.empty());
-}
-
-}  //  namespace android
diff --git a/chrome/browser/password_manager/android/pwd_check_wrapper/BUILD.gn b/chrome/browser/password_manager/android/pwd_check_wrapper/BUILD.gn
index 441f327a..5dbb7d28 100644
--- a/chrome/browser/password_manager/android/pwd_check_wrapper/BUILD.gn
+++ b/chrome/browser/password_manager/android/pwd_check_wrapper/BUILD.gn
@@ -73,7 +73,7 @@
     "//content/public/android:content_full_java",
     "//google_apis/gaia/android:java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
   ]
 }
diff --git a/chrome/browser/password_manager/android/pwm_disabled/BUILD.gn b/chrome/browser/password_manager/android/pwm_disabled/BUILD.gn
index 8026854f..1aef14f 100644
--- a/chrome/browser/password_manager/android/pwm_disabled/BUILD.gn
+++ b/chrome/browser/password_manager/android/pwm_disabled/BUILD.gn
@@ -9,6 +9,10 @@
   resources_package = "org.chromium.chrome.browser.pwm_disabled"
 
   sources = [
+    "java/src/org/chromium/chrome/browser/pwm_disabled/CallbackDelayer.java",
+    "java/src/org/chromium/chrome/browser/pwm_disabled/DialogManager.java",
+    "java/src/org/chromium/chrome/browser/pwm_disabled/ExportErrorDialogFragment.java",
+    "java/src/org/chromium/chrome/browser/pwm_disabled/NonCancelableProgressBar.java",
     "java/src/org/chromium/chrome/browser/pwm_disabled/PasswordCsvDownloadDialogController.java",
     "java/src/org/chromium/chrome/browser/pwm_disabled/PasswordCsvDownloadDialogFragment.java",
     "java/src/org/chromium/chrome/browser/pwm_disabled/PasswordCsvDownloadDialogProperties.java",
@@ -18,6 +22,8 @@
     "java/src/org/chromium/chrome/browser/pwm_disabled/PasswordManagerUnavailableDialogCoordinator.java",
     "java/src/org/chromium/chrome/browser/pwm_disabled/PasswordManagerUnavailableDialogMediator.java",
     "java/src/org/chromium/chrome/browser/pwm_disabled/PwmDeprecationDialogsMetricsRecorder.java",
+    "java/src/org/chromium/chrome/browser/pwm_disabled/SingleThreadBarrierClosure.java",
+    "java/src/org/chromium/chrome/browser/pwm_disabled/TimedCallbackDelayer.java",
   ]
 
   deps = [
@@ -30,6 +36,7 @@
     "//chrome/browser/ui/android/strings:ui_strings_grd",
     "//components/browser_ui/settings/android:java",
     "//components/browser_ui/theme/android:java_resources",
+    "//components/browser_ui/widget/android:java",
     "//components/device_reauth:device_reauth_java_enums",
     "//components/prefs/android:java",
     "//components/strings:components_strings_grd",
@@ -53,9 +60,14 @@
   testonly = true
 
   sources = [
+    "java/src/org/chromium/chrome/browser/pwm_disabled/DialogManagerTest.java",
+    "java/src/org/chromium/chrome/browser/pwm_disabled/EnsureAsyncPostingRule.java",
+    "java/src/org/chromium/chrome/browser/pwm_disabled/ManualCallbackDelayer.java",
     "java/src/org/chromium/chrome/browser/pwm_disabled/PasswordCsvDownloadDialogTest.java",
     "java/src/org/chromium/chrome/browser/pwm_disabled/PasswordCsvDownloadFlowControllerTest.java",
     "java/src/org/chromium/chrome/browser/pwm_disabled/PasswordManagerUnavailableDialogTest.java",
+    "java/src/org/chromium/chrome/browser/pwm_disabled/SingleThreadBarrierClosureTest.java",
+    "java/src/org/chromium/chrome/browser/pwm_disabled/TimedCallbackDelayerTest.java",
   ]
 
   deps = [
@@ -70,9 +82,10 @@
     "//components/browser_ui/settings/android:java",
     "//components/browser_ui/test/android:test_support_java",
     "//components/device_reauth:device_reauth_java_enums",
+    "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_appcompat_appcompat_java",
     "//third_party/androidx:androidx_fragment_fragment_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
     "//ui/android:ui_no_recycler_view_java",
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/CallbackDelayer.java b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/CallbackDelayer.java
similarity index 83%
rename from chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/CallbackDelayer.java
rename to chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/CallbackDelayer.java
index 8619e4e..cdf67a9 100644
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/CallbackDelayer.java
+++ b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/CallbackDelayer.java
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.password_manager.settings;
+package org.chromium.chrome.browser.pwm_disabled;
 
 import org.chromium.build.annotations.NullMarked;
 
 /** This is an interface for delaying running of callbacks. */
 @NullMarked
-public interface CallbackDelayer {
+interface CallbackDelayer {
     /**
      * Run a callback after a delay specific to a particular implementation. The callback is always
      * run asynchronously.
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/DialogManager.java b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/DialogManager.java
similarity index 98%
rename from chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/DialogManager.java
rename to chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/DialogManager.java
index d1dd6352..7b56beb 100644
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/DialogManager.java
+++ b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/DialogManager.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.password_manager.settings;
+package org.chromium.chrome.browser.pwm_disabled;
 
 import androidx.annotation.IntDef;
 import androidx.fragment.app.DialogFragment;
@@ -23,7 +23,7 @@
  * testing purposes.
  */
 @NullMarked
-public final class DialogManager {
+final class DialogManager {
     /**
      * Contains the reference to a {@link android.app.DialogFragment} between the call to {@link
      * show} and dismissing the dialog.
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/password_manager/settings/DialogManagerTest.java b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/DialogManagerTest.java
similarity index 98%
rename from chrome/android/junit/src/org/chromium/chrome/browser/password_manager/settings/DialogManagerTest.java
rename to chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/DialogManagerTest.java
index c987d39..d0d13e5 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/password_manager/settings/DialogManagerTest.java
+++ b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/DialogManagerTest.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.password_manager.settings;
+package org.chromium.chrome.browser.pwm_disabled;
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.mock;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/password_manager/settings/EnsureAsyncPostingRule.java b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/EnsureAsyncPostingRule.java
similarity index 68%
rename from chrome/android/junit/src/org/chromium/chrome/browser/password_manager/settings/EnsureAsyncPostingRule.java
rename to chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/EnsureAsyncPostingRule.java
index e526aa9..979cfbf 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/password_manager/settings/EnsureAsyncPostingRule.java
+++ b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/EnsureAsyncPostingRule.java
@@ -2,22 +2,26 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.password_manager.settings;
+package org.chromium.chrome.browser.pwm_disabled;
 
 import org.junit.rules.ExternalResource;
 import org.robolectric.Robolectric;
 import org.robolectric.util.Scheduler;
 
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.Nullable;
+
 /**
  * A Rule for ensuring that posted tasks are run asynchronously (and on demand). To do so, the rule
  * pauses the Roboelectric scheduler before running the test and restores its state afterwards.
  */
-public class EnsureAsyncPostingRule extends ExternalResource {
+@NullMarked
+class EnsureAsyncPostingRule extends ExternalResource {
     /** Remembers the paused state of the scheduler so that it can be restored after the test. */
     private boolean mWasSchedulerPaused;
 
-    /** A reference to the scheduler which needs to be paused.*/
-    private Scheduler mScheduler;
+    /** A reference to the scheduler which needs to be paused. */
+    private @Nullable Scheduler mScheduler;
 
     @Override
     protected void before() {
@@ -30,6 +34,9 @@
 
     @Override
     protected void after() {
-        if (!mWasSchedulerPaused) mScheduler.unPause();
+        if (!mWasSchedulerPaused) {
+            assert mScheduler != null;
+            mScheduler.unPause();
+        }
     }
 }
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/ExportErrorDialogFragment.java b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/ExportErrorDialogFragment.java
similarity index 95%
rename from chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/ExportErrorDialogFragment.java
rename to chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/ExportErrorDialogFragment.java
index 38099b9..4081729 100644
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/ExportErrorDialogFragment.java
+++ b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/ExportErrorDialogFragment.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.password_manager.settings;
+package org.chromium.chrome.browser.pwm_disabled;
 
 import android.app.Dialog;
 import android.content.DialogInterface;
@@ -20,6 +20,9 @@
 /**
  * Shows the dialog that explains to the user the error which just happened during exporting and
  * optionally helps them to take actions to fix that (learning more, retrying export).
+ *
+ * <p>PasswordCsvDownloadFlowControllerTest requires the class to be public (and @VisibleForTesting
+ * can't be used in top-level classes).
  */
 @NullMarked
 public class ExportErrorDialogFragment extends DialogFragment {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/ManualCallbackDelayer.java b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/ManualCallbackDelayer.java
similarity index 85%
rename from chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/ManualCallbackDelayer.java
rename to chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/ManualCallbackDelayer.java
index bbe3d63b..eed24b8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/ManualCallbackDelayer.java
+++ b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/ManualCallbackDelayer.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.password_manager.settings;
+package org.chromium.chrome.browser.pwm_disabled;
 
 
 import org.chromium.build.annotations.NullMarked;
@@ -14,7 +14,7 @@
  * An implementation of {@link CallbackDelayer} for tests. It runs callbacks after a manual signal.
  */
 @NullMarked
-public final class ManualCallbackDelayer implements CallbackDelayer {
+final class ManualCallbackDelayer implements CallbackDelayer {
     /** The callbacks to be run within {@link runCallbacksSynchronously}.*/
     private final List<Runnable> mCallbacks = new ArrayList<>();
 
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/NonCancelableProgressBar.java b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/NonCancelableProgressBar.java
similarity index 90%
rename from chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/NonCancelableProgressBar.java
rename to chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/NonCancelableProgressBar.java
index 1d02d1ae..99cefe7 100644
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/NonCancelableProgressBar.java
+++ b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/NonCancelableProgressBar.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.password_manager.settings;
+package org.chromium.chrome.browser.pwm_disabled;
 
 import android.app.Activity;
 import android.app.Dialog;
@@ -20,6 +20,9 @@
 /**
  * Shows the dialog that informs the user that some operation is ongoing without indicating the
  * progress.
+ *
+ * <p>PasswordCsvDownloadFlowControllerTest requires the class to be public (and @VisibleForTesting
+ * can't be used in top-level classes).
  */
 @NullMarked
 public class NonCancelableProgressBar extends DialogFragment {
diff --git a/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/PasswordCsvDownloadFlowController.java b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/PasswordCsvDownloadFlowController.java
index a335899..35e67ef 100644
--- a/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/PasswordCsvDownloadFlowController.java
+++ b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/PasswordCsvDownloadFlowController.java
@@ -21,9 +21,6 @@
 import org.chromium.chrome.browser.device_reauth.DeviceAuthSource;
 import org.chromium.chrome.browser.device_reauth.ReauthenticatorBridge;
 import org.chromium.chrome.browser.password_manager.LoginDbDeprecationUtilBridge;
-import org.chromium.chrome.browser.password_manager.settings.DialogManager;
-import org.chromium.chrome.browser.password_manager.settings.ExportErrorDialogFragment;
-import org.chromium.chrome.browser.password_manager.settings.NonCancelableProgressBar;
 import org.chromium.chrome.browser.preferences.Pref;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.pwm_disabled.PwmDeprecationDialogsMetricsRecorder.DownloadCsvDialogType;
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/SingleThreadBarrierClosure.java b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/SingleThreadBarrierClosure.java
similarity index 92%
rename from chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/SingleThreadBarrierClosure.java
rename to chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/SingleThreadBarrierClosure.java
index 98db790..1aefcc5 100644
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/SingleThreadBarrierClosure.java
+++ b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/SingleThreadBarrierClosure.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.password_manager.settings;
+package org.chromium.chrome.browser.pwm_disabled;
 
 import org.chromium.build.annotations.NullMarked;
 
@@ -12,7 +12,7 @@
  * SingleThreadBarrierClosure is only meant to be used on a single thread and is not thread-safe.
  */
 @NullMarked
-public final class SingleThreadBarrierClosure implements Runnable {
+final class SingleThreadBarrierClosure implements Runnable {
     /** Counts the remaining number of runs. */
     private int mRemainingRuns;
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/password_manager/settings/SingleThreadBarrierClosureTest.java b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/SingleThreadBarrierClosureTest.java
similarity index 96%
rename from chrome/android/junit/src/org/chromium/chrome/browser/password_manager/settings/SingleThreadBarrierClosureTest.java
rename to chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/SingleThreadBarrierClosureTest.java
index affaa5c8..834f32f 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/password_manager/settings/SingleThreadBarrierClosureTest.java
+++ b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/SingleThreadBarrierClosureTest.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.password_manager.settings;
+package org.chromium.chrome.browser.pwm_disabled;
 
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
diff --git a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/TimedCallbackDelayer.java b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/TimedCallbackDelayer.java
similarity index 87%
rename from chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/TimedCallbackDelayer.java
rename to chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/TimedCallbackDelayer.java
index 249c4f4..d33c0a1 100644
--- a/chrome/browser/password_manager/android/java/src/org/chromium/chrome/browser/password_manager/settings/TimedCallbackDelayer.java
+++ b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/TimedCallbackDelayer.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.password_manager.settings;
+package org.chromium.chrome.browser.pwm_disabled;
 
 import android.os.Handler;
 
@@ -10,7 +10,7 @@
 
 /** An implementation of {@link CallbackDelayer} which runs callbacks after a fixed time delay. */
 @NullMarked
-public final class TimedCallbackDelayer implements CallbackDelayer {
+final class TimedCallbackDelayer implements CallbackDelayer {
     /** The {@link Handler} used to delay the callbacks. */
     private final Handler mHandler = new Handler();
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/password_manager/settings/TimedCallbackDelayerTest.java b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/TimedCallbackDelayerTest.java
similarity index 96%
rename from chrome/android/junit/src/org/chromium/chrome/browser/password_manager/settings/TimedCallbackDelayerTest.java
rename to chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/TimedCallbackDelayerTest.java
index f94f894..060d7b2 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/password_manager/settings/TimedCallbackDelayerTest.java
+++ b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/TimedCallbackDelayerTest.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.password_manager.settings;
+package org.chromium.chrome.browser.pwm_disabled;
 
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
diff --git a/chrome/browser/password_manager/android/test_support/java/src/org/chromium/chrome/browser/password_manager/FakePasswordManagerHandler.java b/chrome/browser/password_manager/android/test_support/java/src/org/chromium/chrome/browser/password_manager/FakePasswordManagerHandler.java
deleted file mode 100644
index 6f187c6..0000000
--- a/chrome/browser/password_manager/android/test_support/java/src/org/chromium/chrome/browser/password_manager/FakePasswordManagerHandler.java
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2021 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.password_manager;
-
-import android.content.Context;
-
-import androidx.annotation.Nullable;
-
-import org.chromium.base.Callback;
-import org.chromium.base.IntStringCallback;
-import org.chromium.chrome.browser.password_manager.settings.PasswordListObserver;
-import org.chromium.chrome.browser.password_manager.settings.PasswordManagerHandler;
-import org.chromium.chrome.browser.password_manager.settings.SavedPasswordEntry;
-
-import java.util.ArrayList;
-
-/** Fake implementation for the PasswordManagerHandler. */
-public final class FakePasswordManagerHandler implements PasswordManagerHandler {
-    // This class has exactly one observer, set on construction and expected to last at least as
-    // long as this object (a good candidate is the owner of this object).
-    private final PasswordListObserver mObserver;
-
-    // The faked contents of the password store to be displayed.
-    private ArrayList<SavedPasswordEntry> mSavedPasswords = new ArrayList<>();
-
-    // The faked contents of the saves password exceptions to be displayed.
-    private ArrayList<String> mSavedPasswordExeptions = new ArrayList<>();
-
-    // The following three data members are set once {@link #serializePasswords()} is called.
-    @Nullable private IntStringCallback mExportSuccessCallback;
-
-    @Nullable private Callback<String> mExportErrorCallback;
-
-    @Nullable private String mExportTargetPath;
-
-    private int mSerializationInvocationCount;
-
-    public void setSavedPasswords(ArrayList<SavedPasswordEntry> savedPasswords) {
-        mSavedPasswords = savedPasswords;
-    }
-
-    public void setSavedPasswordExceptions(ArrayList<String> savedPasswordExceptions) {
-        mSavedPasswordExeptions = savedPasswordExceptions;
-    }
-
-    public IntStringCallback getExportSuccessCallback() {
-        return mExportSuccessCallback;
-    }
-
-    public Callback<String> getExportErrorCallback() {
-        return mExportErrorCallback;
-    }
-
-    public String getExportTargetPath() {
-        return mExportTargetPath;
-    }
-
-    /**
-     * Constructor.
-     *
-     * @param observer The only observer.
-     */
-    public FakePasswordManagerHandler(PasswordListObserver observer) {
-        mObserver = observer;
-        mSerializationInvocationCount = 0;
-    }
-
-    /**
-     * A getter for the faked contents of the password store.
-     *
-     * @return the faked contents of the password store.
-     */
-    public ArrayList<SavedPasswordEntry> getSavedPasswordEntriesForTesting() {
-        return mSavedPasswords;
-    }
-
-    @Override
-    public void insertPasswordEntryForTesting(String origin, String username, String password) {
-        mSavedPasswords.add(new SavedPasswordEntry(origin, username, password));
-    }
-
-    // Pretends that the updated lists are |mSavedPasswords| for the saved passwords and an
-    // empty list for exceptions and immediately calls the observer.
-    @Override
-    public void updatePasswordLists() {
-        mObserver.passwordListAvailable(mSavedPasswords.size());
-        mObserver.passwordExceptionListAvailable(mSavedPasswordExeptions.size());
-    }
-
-    @Override
-    public SavedPasswordEntry getSavedPasswordEntry(int index) {
-        return mSavedPasswords.get(index);
-    }
-
-    @Override
-    public String getSavedPasswordException(int index) {
-        return mSavedPasswordExeptions.get(index);
-    }
-
-    @Override
-    public void removeSavedPasswordEntry(int index) {
-        assert false : "Define this method before starting to use it in tests.";
-    }
-
-    @Override
-    public void removeSavedPasswordException(int index) {
-        assert false : "Define this method before starting to use it in tests.";
-    }
-
-    @Override
-    public void serializePasswords(
-            String targetPath, IntStringCallback successCallback, Callback<String> errorCallback) {
-        mExportSuccessCallback = successCallback;
-        mExportErrorCallback = errorCallback;
-        mExportTargetPath = targetPath;
-        mSerializationInvocationCount += 1;
-    }
-
-    @Override
-    public void showPasswordEntryEditingView(
-            Context context, int index, boolean isBlockedCredential) {
-        assert false : "Define this method before starting to use it in tests.";
-    }
-
-    @Override
-    public boolean isWaitingForPasswordStore() {
-        return false;
-    }
-
-    public int getSerializationInvocationCount() {
-        return mSerializationInvocationCount;
-    }
-}
diff --git a/chrome/browser/password_manager/factories/BUILD.gn b/chrome/browser/password_manager/factories/BUILD.gn
index a79bafd6..51523e0 100644
--- a/chrome/browser/password_manager/factories/BUILD.gn
+++ b/chrome/browser/password_manager/factories/BUILD.gn
@@ -16,7 +16,7 @@
     "//base",
     "//chrome/browser/profiles:profile",
     "//components/keyed_service/core",
-    "//components/password_manager/core/browser:browser",
+    "//components/password_manager/core/browser",
     "//components/password_manager/core/browser/password_store:password_store_interface",
     "//content/public/browser",
   ]
@@ -83,7 +83,7 @@
     "//components/password_manager/core/browser:password_manager_buildflags",
     "//components/password_manager/core/browser/affiliation:affiliation_fetching",
     "//components/password_manager/core/browser/features:password_features",
-    "//components/password_manager/core/common:common",
+    "//components/password_manager/core/common",
     "//components/prefs",
   ]
   if (is_android) {
diff --git a/chrome/browser/payments/BUILD.gn b/chrome/browser/payments/BUILD.gn
index 6255459..7376eb8 100644
--- a/chrome/browser/payments/BUILD.gn
+++ b/chrome/browser/payments/BUILD.gn
@@ -52,7 +52,7 @@
     "//components/payments/core",
     "//components/payments/core:test_support",
     "//components/ukm:test_support",
-    "//components/webdata_services:webdata_services",
+    "//components/webdata_services",
     "//device/fido:test_support",
   ]
 
@@ -75,8 +75,8 @@
       "//chrome/test:test_support_ui",
       "//components/payments/content:utils",
       "//components/payments/content/utility",
-      "//components/permissions:permissions",
-      "//components/webdata_services:webdata_services",
+      "//components/permissions",
+      "//components/webdata_services",
     ]
   }
 
@@ -96,7 +96,7 @@
     "//chrome/test:test_support",
     "//components/content_settings/core/test:test_support",
     "//components/infobars/content",
-    "//components/permissions:permissions",
+    "//components/permissions",
   ]
 
   if (is_android) {
diff --git a/chrome/browser/permissions/BUILD.gn b/chrome/browser/permissions/BUILD.gn
index 59caecdc..942b737 100644
--- a/chrome/browser/permissions/BUILD.gn
+++ b/chrome/browser/permissions/BUILD.gn
@@ -225,7 +225,6 @@
     "//chrome/browser/search_engines",
     "//chrome/test:test_support",
     "//components/optimization_guide/core:test_support",
-    "//components/permissions:test_support",
     "//components/permissions/prediction_service",
     "//components/site_engagement/content",
     "//components/ukm/content",
diff --git a/chrome/browser/permissions/system/BUILD.gn b/chrome/browser/permissions/system/BUILD.gn
index 3efcf83..c22d377 100644
--- a/chrome/browser/permissions/system/BUILD.gn
+++ b/chrome/browser/permissions/system/BUILD.gn
@@ -28,7 +28,7 @@
     "//chrome/browser:browser_process",
     "//chrome/browser:global_features",
     "//chrome/browser/profiles",
-    "//services/device/public/cpp/geolocation:geolocation",
+    "//services/device/public/cpp/geolocation",
   ]
 
   if (is_mac) {
@@ -44,8 +44,8 @@
     sources += [ "system_permission_settings_chromeos.cc" ]
     deps += [
       "//chrome/browser:browser_public_dependencies",
-      "//chrome/browser/ash/privacy_hub:privacy_hub",
-      "//chrome/browser/web_applications:web_applications",
+      "//chrome/browser/ash/privacy_hub",
+      "//chrome/browser/web_applications",
     ]
   } else if (is_win) {
     sources += [
diff --git a/chrome/browser/picture_in_picture/BUILD.gn b/chrome/browser/picture_in_picture/BUILD.gn
index c391ac9..a967d28 100644
--- a/chrome/browser/picture_in_picture/BUILD.gn
+++ b/chrome/browser/picture_in_picture/BUILD.gn
@@ -76,7 +76,7 @@
     "//chrome/browser/media/webrtc",
     "//chrome/browser/permissions",
     "//chrome/browser/profiles:profile",
-    "//chrome/browser/safe_browsing:safe_browsing",
+    "//chrome/browser/safe_browsing",
     "//chrome/browser/ui:browser_navigator_params_headers",
     "//components/content_settings/core/browser",
     "//components/permissions",
diff --git a/chrome/browser/picture_in_picture/test/BUILD.gn b/chrome/browser/picture_in_picture/test/BUILD.gn
index ed9e1d46..7e8442ba 100644
--- a/chrome/browser/picture_in_picture/test/BUILD.gn
+++ b/chrome/browser/picture_in_picture/test/BUILD.gn
@@ -29,7 +29,7 @@
     "//content/public/android:content_java",
     "//third_party/androidx:androidx_test_monitor_java",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
   ]
 }
 
@@ -71,7 +71,7 @@
   deps = [
     ":jni_headers",
     "//base",
-    "//chrome/browser/picture_in_picture:picture_in_picture",
+    "//chrome/browser/picture_in_picture",
     "//content/public/browser",
   ]
 }
diff --git a/chrome/browser/policy/cloud/cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
index 46f9144..7f51614 100644
--- a/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
+++ b/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
@@ -343,7 +343,7 @@
   void SetServerPolicy(const em::CloudPolicySettings& settings,
                        int key_version) {
     test_server_->policy_storage()->SetPolicyPayload(
-        dm_protocol::kChromeUserPolicyType, settings.SerializeAsString());
+        dm_protocol::GetChromeUserPolicyType(), settings.SerializeAsString());
 
     test_server_->policy_storage()->add_managed_user("*");
     test_server_->policy_storage()->set_policy_user(GetTestUser());
diff --git a/chrome/browser/policy/cloud/cloud_policy_invalidator_unittest.cc b/chrome/browser/policy/cloud/cloud_policy_invalidator_unittest.cc
index 86f2f4b..dd15c97 100644
--- a/chrome/browser/policy/cloud/cloud_policy_invalidator_unittest.cc
+++ b/chrome/browser/policy/cloud/cloud_policy_invalidator_unittest.cc
@@ -180,7 +180,7 @@
 };
 
 CloudPolicyInvalidatorTestBase::CloudPolicyInvalidatorTestBase()
-    : core_(dm_protocol::kChromeUserPolicyType,
+    : core_(dm_protocol::GetChromeUserPolicyType(),
             std::string(),
             &store_,
             task_environment_.GetMainThreadTaskRunner(),
diff --git a/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc
index cf0f56b..d43e1c7 100644
--- a/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc
+++ b/chrome/browser/policy/cloud/component_cloud_policy_browsertest.cc
@@ -128,7 +128,7 @@
     client_info.device_token = kDMToken;
     client_info.allowed_policy_types = {
         policy::dm_protocol::kChromeExtensionPolicyType,
-        policy::dm_protocol::kChromeUserPolicyType,
+        policy::dm_protocol::GetChromeUserPolicyType(),
     };
     test_server_.client_storage()->RegisterClient(client_info);
     ASSERT_TRUE(test_server_.Start());
diff --git a/chrome/browser/policy/cloud/device_management_service_browsertest.cc b/chrome/browser/policy/cloud/device_management_service_browsertest.cc
index 70a3dd5c..da2b3da 100644
--- a/chrome/browser/policy/cloud/device_management_service_browsertest.cc
+++ b/chrome/browser/policy/cloud/device_management_service_browsertest.cc
@@ -193,7 +193,7 @@
         em::PolicyOptions::MANDATORY);
     settings.mutable_homepagelocation()->set_value("http://www.chromium.org");
     PolicyStorage* policy_storage = test_server_->policy_storage();
-    policy_storage->SetPolicyPayload(dm_protocol::kChromeUserPolicyType,
+    policy_storage->SetPolicyPayload(dm_protocol::GetChromeUserPolicyType(),
                                      settings.SerializeAsString());
     policy_storage->add_managed_user("*");
     policy_storage->set_robot_api_auth_code("fake_auth_code");
@@ -255,7 +255,7 @@
 
   em::DeviceManagementRequest request;
   request.mutable_policy_request()->add_requests()->set_policy_type(
-      dm_protocol::kChromeUserPolicyType);
+      dm_protocol::GetChromeUserPolicyType());
   std::unique_ptr<DeviceManagementService::Job> job =
       StartJob(DeviceManagementService::JobConfiguration::TYPE_POLICY_FETCH,
                false, DMAuth::FromDMToken(token_), "", request);
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_browsertest.cc b/chrome/browser/policy/cloud/user_policy_signin_service_browsertest.cc
index 18042799..15dc52f 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service_browsertest.cc
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_browsertest.cc
@@ -245,8 +245,9 @@
     settings.mutable_showhomebutton()->mutable_policy_options()->set_mode(
         em::PolicyOptions::MANDATORY);
     settings.mutable_showhomebutton()->set_value(true);
-    policy_storage->SetPolicyPayload(policy::dm_protocol::kChromeUserPolicyType,
-                                     settings.SerializeAsString());
+    policy_storage->SetPolicyPayload(
+        policy::dm_protocol::GetChromeUserPolicyType(),
+        settings.SerializeAsString());
     policy_storage->add_managed_user("*");
     policy_storage->set_policy_user(kTestEmail);
     policy_storage->signature_provider()->set_current_key_version(1);
diff --git a/chrome/browser/preferences/BUILD.gn b/chrome/browser/preferences/BUILD.gn
index c5f1d8c..e097670 100644
--- a/chrome/browser/preferences/BUILD.gn
+++ b/chrome/browser/preferences/BUILD.gn
@@ -103,7 +103,7 @@
     "//base/test:test_support_java",
     "//third_party/android_deps:guava_android_java",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
   ]
 }
diff --git a/chrome/browser/prefs/BUILD.gn b/chrome/browser/prefs/BUILD.gn
index 6d1542a..6e6e9c8 100644
--- a/chrome/browser/prefs/BUILD.gn
+++ b/chrome/browser/prefs/BUILD.gn
@@ -157,7 +157,7 @@
   }
 
   if (enable_background_mode) {
-    deps += [ "//chrome/browser/background/extensions:extensions" ]
+    deps += [ "//chrome/browser/background/extensions" ]
   }
 
   if (is_chromeos) {
@@ -491,7 +491,7 @@
       "//chrome/browser/preloading:prefs",
       "//chrome/browser/search_engines",
       "//chrome/browser/ui",
-      "//chrome/browser/ui/browser_window:browser_window",
+      "//chrome/browser/ui/browser_window",
       "//chrome/browser/ui/tabs:tab_strip",
       "//chrome/common:constants",
       "//chrome/common:non_code_constants",
diff --git a/chrome/browser/preloading/prerender/BUILD.gn b/chrome/browser/preloading/prerender/BUILD.gn
index 1737b0ab..49115d42 100644
--- a/chrome/browser/preloading/prerender/BUILD.gn
+++ b/chrome/browser/preloading/prerender/BUILD.gn
@@ -17,7 +17,7 @@
     "//chrome/browser/preloading:prefs",
     "//chrome/browser/search_engines",
     "//chrome/test:test_support",
-    "//components/page_load_metrics/browser:browser",
+    "//components/page_load_metrics/browser",
     "//third_party/blink/public/common:preloading_headers",
   ]
 
diff --git a/chrome/browser/preloading/search_preload/BUILD.gn b/chrome/browser/preloading/search_preload/BUILD.gn
index 1b3de718..66d00b91 100644
--- a/chrome/browser/preloading/search_preload/BUILD.gn
+++ b/chrome/browser/preloading/search_preload/BUILD.gn
@@ -28,8 +28,7 @@
     "//base",
     "//chrome/browser/profiles:profile",
     "//chrome/browser/search_engines",
-    "//chrome/browser/search_engines:search_engines",
-    "//components/omnibox/browser:browser",
+    "//components/omnibox/browser",
     "//components/omnibox/browser:mojo_bindings",
     "//components/search_engines",
   ]
diff --git a/chrome/browser/privacy/BUILD.gn b/chrome/browser/privacy/BUILD.gn
index 747febf8..d26f3e7 100644
--- a/chrome/browser/privacy/BUILD.gn
+++ b/chrome/browser/privacy/BUILD.gn
@@ -59,7 +59,7 @@
       "//chrome/android/junit:*",
       "//chrome/browser/feed/android:*",
       "//chrome/browser/ui/android/hats:*",
-      "//chrome/browser/ui/android/hats/*:*",
+      "//chrome/browser/ui/android/hats/*",
       "//chrome/browser/ui/android/omnibox:*",
       "//chrome/browser/ui/android/signin:*",
       "//chrome/browser/xsurface_provider:*",
diff --git a/chrome/browser/privacy_guide/android/BUILD.gn b/chrome/browser/privacy_guide/android/BUILD.gn
index e04a9072..662abb7 100644
--- a/chrome/browser/privacy_guide/android/BUILD.gn
+++ b/chrome/browser/privacy_guide/android/BUILD.gn
@@ -113,7 +113,7 @@
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/hamcrest:hamcrest_core_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
   ]
@@ -157,7 +157,7 @@
     "//third_party/hamcrest:hamcrest_core_java",
     "//third_party/hamcrest:hamcrest_library_java",
     "//third_party/jni_zero:gendeps_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
   ]
diff --git a/chrome/browser/privacy_sandbox/BUILD.gn b/chrome/browser/privacy_sandbox/BUILD.gn
index 84200d3e..4080ed4 100644
--- a/chrome/browser/privacy_sandbox/BUILD.gn
+++ b/chrome/browser/privacy_sandbox/BUILD.gn
@@ -60,7 +60,7 @@
     "//chrome/browser:browser_process",
     "//chrome/test:test_support",
     "//components/privacy_sandbox:features",
-    "//components/variations/service:service",
+    "//components/variations/service",
     "//testing/gmock",
     "//testing/gtest",
   ]
diff --git a/chrome/browser/privacy_sandbox/android/BUILD.gn b/chrome/browser/privacy_sandbox/android/BUILD.gn
index 6fbc8eaa1..3679cd20 100644
--- a/chrome/browser/privacy_sandbox/android/BUILD.gn
+++ b/chrome/browser/privacy_sandbox/android/BUILD.gn
@@ -152,7 +152,7 @@
     "//third_party/hamcrest:hamcrest_core_java",
     "//third_party/hamcrest:hamcrest_library_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
     "//ui/android:ui_no_recycler_view_java",
@@ -202,7 +202,7 @@
     "//third_party/hamcrest:hamcrest_core_java",
     "//third_party/hamcrest:hamcrest_library_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
     "//ui/android:ui_no_recycler_view_java",
diff --git a/chrome/browser/privacy_sandbox/incognito/BUILD.gn b/chrome/browser/privacy_sandbox/incognito/BUILD.gn
index 2fc3335..c74869a 100644
--- a/chrome/browser/privacy_sandbox/incognito/BUILD.gn
+++ b/chrome/browser/privacy_sandbox/incognito/BUILD.gn
@@ -61,7 +61,7 @@
     deps = [
       ":incognito_features",
       ":incognito_surveys",
-      "//chrome/browser/ui/hats:hats",
+      "//chrome/browser/ui/hats",
       "//chrome/browser/ui/hats:test_support",
       "//chrome/test:test_support",
     ]
diff --git a/chrome/browser/privacy_sandbox/notice/BUILD.gn b/chrome/browser/privacy_sandbox/notice/BUILD.gn
index b7b9901..cc97cfd5 100644
--- a/chrome/browser/privacy_sandbox/notice/BUILD.gn
+++ b/chrome/browser/privacy_sandbox/notice/BUILD.gn
@@ -33,8 +33,8 @@
     ":notice_definitions",
     ":notice_mojom",
     "//base",
-    "//base/version_info:version_info",
-    "//components/pref_registry:pref_registry",
+    "//base/version_info",
+    "//components/pref_registry",
     "//components/prefs",
     "//components/privacy_sandbox:features",
   ]
@@ -113,7 +113,7 @@
       "//chrome/browser/profiles:profile",
       "//chrome/browser/search_engine_choice",
       "//chrome/browser/sync",
-      "//chrome/browser/ui:ui",
+      "//chrome/browser/ui",
       "//chrome/browser/ui/browser_window",
       "//chrome/browser/ui/privacy_sandbox",
       "//chrome/browser/ui/profiles",
@@ -123,7 +123,7 @@
       "//components/regional_capabilities",
       "//components/search_engines:search_engines_switches",
       "//components/tabs:public",
-      "//components/web_modal:web_modal",
+      "//components/web_modal",
       "//content/public/browser",
     ]
   }
@@ -157,8 +157,8 @@
     ":interfaces",
     ":notice_mojom",
     "//base",
-    "//components/keyed_service/core:core",
-    "//content/public/browser:browser",
+    "//components/keyed_service/core",
+    "//content/public/browser",
     "//testing/gmock",
   ]
 
diff --git a/chrome/browser/profile_resetter/BUILD.gn b/chrome/browser/profile_resetter/BUILD.gn
index f8ae0ca2..2327fa61 100644
--- a/chrome/browser/profile_resetter/BUILD.gn
+++ b/chrome/browser/profile_resetter/BUILD.gn
@@ -16,19 +16,19 @@
       "fake_profile_resetter.h",
     ]
     deps = [
-      "//chrome/browser:browser",
+      "//chrome/browser",
       "//chrome/browser/browsing_data:constants",
-      "//chrome/browser/google:google",
-      "//chrome/browser/search/background:background",
-      "//chrome/browser/search_engines:search_engines",
+      "//chrome/browser/google",
+      "//chrome/browser/search/background",
+      "//chrome/browser/search_engines",
       "//chrome/test:test_support",
-      "//components/browsing_data/content:content",
-      "//components/language/core/browser:browser",
+      "//components/browsing_data/content",
+      "//components/language/core/browser",
     ]
     if (is_chromeos) {
       deps += [
         "//chromeos/ash/components/dbus/shill:test_support",
-        "//chromeos/ash/components/network:network",
+        "//chromeos/ash/components/network",
       ]
     }
   }
diff --git a/chrome/browser/profiles/BUILD.gn b/chrome/browser/profiles/BUILD.gn
index ad1035e..81d7fd8 100644
--- a/chrome/browser/profiles/BUILD.gn
+++ b/chrome/browser/profiles/BUILD.gn
@@ -126,7 +126,7 @@
     "//components/keyed_service/core",
     "//components/password_manager/core/browser/password_store:password_store_interface",
     "//components/signin/public/identity_manager:tribool",
-    "//device/fido:fido",
+    "//device/fido",
     "//mojo/public/cpp/bindings",
     "//services/preferences/public/mojom",
     "//skia",
@@ -232,7 +232,7 @@
     "//chrome/browser/ai",
     "//chrome/browser/autocomplete",
     "//chrome/browser/autofill",
-    "//chrome/browser/background:background",
+    "//chrome/browser/background",
     "//chrome/browser/bitmap_fetcher",
     "//chrome/browser/breadcrumbs",
     "//chrome/browser/commerce",
diff --git a/chrome/browser/profiles/profile_keyed_service_browsertest.cc b/chrome/browser/profiles/profile_keyed_service_browsertest.cc
index fd327f32..804724a 100644
--- a/chrome/browser/profiles/profile_keyed_service_browsertest.cc
+++ b/chrome/browser/profiles/profile_keyed_service_browsertest.cc
@@ -645,6 +645,7 @@
     "ExtensionInstallEventRouter",
 #endif  // BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
     "ExtensionManagement",
+    "ExtensionNavigationRegistry",
     "ExtensionPrefValueMap",
     "ExtensionPrefs",
     "ExtensionRegistrar",
@@ -677,7 +678,6 @@
     "HeavyAdService",
 #if BUILDFLAG(ENABLE_EXTENSIONS)
     "HidConnectionResourceManager",
-    "ExtensionNavigationRegistry",
 #endif
     "HidDeviceManager",
     "HistoryAPI",
diff --git a/chrome/browser/profiling_host/BUILD.gn b/chrome/browser/profiling_host/BUILD.gn
index 8f9900b4..e1d5dbb 100644
--- a/chrome/browser/profiling_host/BUILD.gn
+++ b/chrome/browser/profiling_host/BUILD.gn
@@ -25,7 +25,7 @@
     "//components/version_info",
     "//content/public/browser",
     "//content/public/common",
-    "//third_party/zlib:zlib",
+    "//third_party/zlib",
 
     # Added to support the dependency on //chrome/browser/metrics
     # TODO(darin): We should instead have a way to express that dependency here.
diff --git a/chrome/browser/push_notification/BUILD.gn b/chrome/browser/push_notification/BUILD.gn
index 954fc53..0fde17771 100644
--- a/chrome/browser/push_notification/BUILD.gn
+++ b/chrome/browser/push_notification/BUILD.gn
@@ -25,19 +25,19 @@
     "//base",
     "//chrome/browser/profiles:profile",
     "//chrome/browser/push_notification/protos:proto",
-    "//chromeos/ash/components/nearby/common/scheduling:scheduling",
-    "//components/cross_device/logging:logging",
-    "//components/gcm_driver:gcm_driver",
-    "//components/gcm_driver/instance_id:instance_id",
-    "//components/keyed_service/content:content",
-    "//components/keyed_service/core:core",
-    "//components/prefs:prefs",
+    "//chromeos/ash/components/nearby/common/scheduling",
+    "//components/cross_device/logging",
+    "//components/gcm_driver",
+    "//components/gcm_driver/instance_id",
+    "//components/keyed_service/content",
+    "//components/keyed_service/core",
+    "//components/prefs",
     "//components/push_notification",
-    "//components/signin/public/base:base",
-    "//components/signin/public/identity_manager:identity_manager",
-    "//components/user_manager:user_manager",
-    "//content/public/browser:browser",
-    "//google_apis:google_apis",
+    "//components/signin/public/base",
+    "//components/signin/public/identity_manager",
+    "//components/user_manager",
+    "//content/public/browser",
+    "//google_apis",
   ]
 }
 source_set("test_support") {
@@ -49,7 +49,7 @@
   deps = [
     "//base",
     "//base/test:test_support",
-    "//chrome/browser/push_notification:push_notification",
+    "//chrome/browser/push_notification",
     "//chrome/browser/push_notification/protos:proto",
     "//chrome/test:test_support",
     "//content/public/browser",
diff --git a/chrome/browser/quick_delete/BUILD.gn b/chrome/browser/quick_delete/BUILD.gn
index b6addaa..a1912c2 100644
--- a/chrome/browser/quick_delete/BUILD.gn
+++ b/chrome/browser/quick_delete/BUILD.gn
@@ -118,7 +118,7 @@
     "//content/public/android:content_full_java",
     "//content/public/test/android:content_java_test_support",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
     "//ui/android:ui_no_recycler_view_java",
@@ -173,7 +173,7 @@
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/hamcrest:hamcrest_core_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
     "//ui/android:ui_no_recycler_view_java",
diff --git a/chrome/browser/readaloud/android/BUILD.gn b/chrome/browser/readaloud/android/BUILD.gn
index 7edb3171..9cd3c87 100644
--- a/chrome/browser/readaloud/android/BUILD.gn
+++ b/chrome/browser/readaloud/android/BUILD.gn
@@ -381,7 +381,7 @@
     "//third_party/hamcrest:hamcrest_core_java",
     "//third_party/hamcrest:hamcrest_library_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_no_recycler_view_java",
   ]
diff --git a/chrome/browser/reading_list/android/BUILD.gn b/chrome/browser/reading_list/android/BUILD.gn
index 77dee51..c2832f19 100644
--- a/chrome/browser/reading_list/android/BUILD.gn
+++ b/chrome/browser/reading_list/android/BUILD.gn
@@ -26,7 +26,7 @@
     "//components/keyed_service/core",
     "//components/reading_list/core",
     "//skia",
-    "//ui/base:base",
+    "//ui/base",
     "//url",
   ]
 }
@@ -39,7 +39,7 @@
     "//base/test:test_support",
     "//chrome/browser/notifications/scheduler/test:test_support",
     "//components/bookmarks/browser",
-    "//components/reading_list/core:core",
+    "//components/reading_list/core",
     "//components/reading_list/core:test_support",
     "//components/sync",
     "//components/sync:test_support",
diff --git a/chrome/browser/recent_tabs/BUILD.gn b/chrome/browser/recent_tabs/BUILD.gn
index 41573382..f298e48 100644
--- a/chrome/browser/recent_tabs/BUILD.gn
+++ b/chrome/browser/recent_tabs/BUILD.gn
@@ -94,7 +94,7 @@
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/hamcrest:hamcrest_library_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java",
     "//url:gurl_java",
diff --git a/chrome/browser/recent_tabs/internal/BUILD.gn b/chrome/browser/recent_tabs/internal/BUILD.gn
index 23d8855e..ff5a6551 100644
--- a/chrome/browser/recent_tabs/internal/BUILD.gn
+++ b/chrome/browser/recent_tabs/internal/BUILD.gn
@@ -151,7 +151,7 @@
     "//third_party/hamcrest:hamcrest_java",
     "//third_party/hamcrest:hamcrest_library_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java",
     "//ui/android:ui_java_test_support",
@@ -188,7 +188,7 @@
     "//third_party/hamcrest:hamcrest_java",
     "//third_party/hamcrest:hamcrest_library_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java",
     "//ui/android:ui_java_test_support",
@@ -223,7 +223,7 @@
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/hamcrest:hamcrest_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_full_java",
     "//ui/android:ui_java_test_support",
diff --git a/chrome/browser/regional_capabilities/BUILD.gn b/chrome/browser/regional_capabilities/BUILD.gn
index 06ad625..3278f15 100644
--- a/chrome/browser/regional_capabilities/BUILD.gn
+++ b/chrome/browser/regional_capabilities/BUILD.gn
@@ -39,7 +39,7 @@
       "regional_capabilities_service_client_chromeos.h",
     ]
 
-    deps += [ "//chromeos/ash/components/system:system" ]
+    deps += [ "//chromeos/ash/components/system" ]
   }
 
   if (is_linux) {
@@ -87,7 +87,7 @@
   if (is_chromeos) {
     sources += [ "regional_capabilities_service_client_chromeos_unittest.cc" ]
 
-    deps += [ "//chromeos/ash/components/system:system" ]
+    deps += [ "//chromeos/ash/components/system" ]
   }
 
   if (is_linux) {
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn
index 224a372b..1897b195 100644
--- a/chrome/browser/resources/BUILD.gn
+++ b/chrome/browser/resources/BUILD.gn
@@ -294,7 +294,7 @@
     "//components/download/resources/download_internals:resources",
     "//components/history_clusters/history_clusters_internals/resources",
     "//components/metrics/debug:resources",
-    "//components/ntp_tiles/webui/resources:resources",
+    "//components/ntp_tiles/webui/resources",
     "//components/optimization_guide/optimization_guide_internals/resources",
     "//components/policy/resources/webui:resources",
     "//components/resources:dev_ui_components_resources",
diff --git a/chrome/browser/resources/chromeos/login/BUILD.gn b/chrome/browser/resources/chromeos/login/BUILD.gn
index 748a937..e621c58 100644
--- a/chrome/browser/resources/chromeos/login/BUILD.gn
+++ b/chrome/browser/resources/chromeos/login/BUILD.gn
@@ -52,7 +52,7 @@
   ]
 
   mojo_files_deps = [
-    "//chrome/browser/ui/webui/ash/login/mojom:mojom",
+    "//chrome/browser/ui/webui/ash/login/mojom",
     "//chrome/browser/ui/webui/ash/login/mojom:mojom_ts__generator",
   ]
 
diff --git a/chrome/browser/resources/chromeos/sys_internals/BUILD.gn b/chrome/browser/resources/chromeos/sys_internals/BUILD.gn
index f177b866..52dd524 100644
--- a/chrome/browser/resources/chromeos/sys_internals/BUILD.gn
+++ b/chrome/browser/resources/chromeos/sys_internals/BUILD.gn
@@ -16,7 +16,7 @@
   deps = [
     ":constants",
     ":types",
-    "line_chart:line_chart",
+    "line_chart",
     "line_chart:unit_label",
     "//ash/webui/common/resources:cr.m",
     "//ash/webui/common/resources:promise_resolver",
diff --git a/chrome/browser/resources/commerce/price_tracking/BUILD.gn b/chrome/browser/resources/commerce/price_tracking/BUILD.gn
index ebd136b..b6d2160 100644
--- a/chrome/browser/resources/commerce/price_tracking/BUILD.gn
+++ b/chrome/browser/resources/commerce/price_tracking/BUILD.gn
@@ -21,8 +21,8 @@
     "//components/commerce/core:utils",
     "//components/commerce/core/mojom:mojo_bindings",
     "//components/feature_engagement/public",
-    "//components/history/core/browser:browser",
-    "//components/optimization_guide/core:core",
+    "//components/history/core/browser",
+    "//components/optimization_guide/core",
     "//components/payments/core",
     "//components/power_bookmarks/core",
     "//components/prefs",
@@ -55,6 +55,6 @@
     "//mojo/public/cpp/bindings",
     "//services/metrics/public/cpp:ukm_builders",
     "//testing/gtest",
-    "//url:url",
+    "//url",
   ]
 }
diff --git a/chrome/browser/resources/glic/glic_api/glic_api.ts b/chrome/browser/resources/glic/glic_api/glic_api.ts
index c6e0e610..a230ca4 100644
--- a/chrome/browser/resources/glic/glic_api/glic_api.ts
+++ b/chrome/browser/resources/glic/glic_api/glic_api.ts
@@ -682,7 +682,7 @@
  * Provides measurement-related functionality to the Glic web client.
  *
  * The typical sequence of events should be either:
- *  (onUserInputSubmitted -> (onRequestStarted -> onResponseStarted ->
+ *  (onUserInputSubmitted -> (onResponseStarted ->
  *                            onResponseStopped)*
  *  )*
  * or
@@ -699,12 +699,6 @@
   onUserInputSubmitted?(mode: WebClientMode): void;
 
   /**
-   * Called when the web client has submitted a request to the server
-   * awaiting a response.
-   */
-  onRequestStarted?(): void;
-
-  /**
    * Called when the web client has sufficiently processed the input such that
    * it is able to start providing a response.
    */
diff --git a/chrome/browser/resources/glic/glic_api_impl/glic_api_client.ts b/chrome/browser/resources/glic/glic_api_impl/glic_api_client.ts
index 2bb4a7b..9f8df3e 100644
--- a/chrome/browser/resources/glic/glic_api_impl/glic_api_client.ts
+++ b/chrome/browser/resources/glic/glic_api_impl/glic_api_client.ts
@@ -803,10 +803,6 @@
     this.sender.requestNoResponse('glicBrowserOnUserInputSubmitted', {mode});
   }
 
-  onRequestStarted(): void {
-    this.sender.requestNoResponse('glicBrowserOnRequestStarted', undefined);
-  }
-
   onResponseStarted(): void {
     this.sender.requestNoResponse('glicBrowserOnResponseStarted', undefined);
   }
diff --git a/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts b/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts
index 133c6a6..e177528 100644
--- a/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts
+++ b/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts
@@ -656,10 +656,6 @@
     this.handler.onUserInputSubmitted(request.mode);
   }
 
-  glicBrowserOnRequestStarted(): void {
-    this.handler.onRequestStarted();
-  }
-
   glicBrowserOnResponseStarted(): void {
     this.handler.onResponseStarted();
   }
diff --git a/chrome/browser/resources/glic/glic_api_impl/request_types.ts b/chrome/browser/resources/glic/glic_api_impl/request_types.ts
index 7455dde..d8b1f1ff 100644
--- a/chrome/browser/resources/glic/glic_api_impl/request_types.ts
+++ b/chrome/browser/resources/glic/glic_api_impl/request_types.ts
@@ -266,7 +266,6 @@
       mode: number,
     },
   };
-  glicBrowserOnRequestStarted: {};
   glicBrowserOnResponseStarted: {};
   glicBrowserOnResponseStopped: {};
   glicBrowserOnSessionTerminated: {};
@@ -512,7 +511,6 @@
     JournalRecordFeedback: 0,
     OnUserInputSubmitted: 0,
     OnResponseRated: 0,
-    OnRequestStarted: 0,
     OnResponseStarted: 0,
     OnResponseStopped: 0,
     OnSessionTerminated: 0,
diff --git a/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.css b/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.css
index 97fd335b..e6c58b6d1 100644
--- a/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.css
+++ b/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.css
@@ -56,6 +56,17 @@
   margin: 0px;
 }
 
+/* Separate CSS classes are needed instead of setting the style directly so
+ * that when forced colors are active, the color menu isn't reshown through
+ * the code used to manage toolbar overflows. */
+.hidden {
+  display: none;
+}
+
+.visibility-hidden {
+  visibility: hidden;
+}
+
 .granularity-container-when-active-true {
   display: flex;
   flex-direction: row;
diff --git a/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.html.ts b/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.html.ts
index 53811aeb..b345998 100644
--- a/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.html.ts
+++ b/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.html.ts
@@ -139,10 +139,10 @@
     </cr-icon-button>
   `)}
   <cr-icon-button id="more" tabindex="-1" aria-label="$i18n{moreOptionsLabel}"
+      class="hidden"
       title="$i18n{moreOptionsLabel}"
       aria-haspopup="menu"
       iron-icon="cr:more-vert"
-      hidden
       @click="${this.onMoreOptionsClick_}">
   </cr-icon-button>
 
diff --git a/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.ts b/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.ts
index 5ff9d74..afc7118 100644
--- a/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.ts
+++ b/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.ts
@@ -262,15 +262,14 @@
 
   private hideElement_(element: HTMLElement, keepSpace: boolean) {
     if (keepSpace) {
-      element.style.visibility = 'hidden';
+      element.classList.add('visibility-hidden');
     } else {
-      element.style.display = 'none';
+      element.classList.add('hidden');
     }
   }
 
   private showElement_(element: HTMLElement) {
-    element.style.visibility = 'visible';
-    element.style.display = 'inline-block';
+    element.classList.remove('hidden', 'visibility-hidden');
   }
 
 
diff --git a/chrome/browser/safe_browsing/BUILD.gn b/chrome/browser/safe_browsing/BUILD.gn
index c9e1330d4..a8234106 100644
--- a/chrome/browser/safe_browsing/BUILD.gn
+++ b/chrome/browser/safe_browsing/BUILD.gn
@@ -26,7 +26,7 @@
     "//chrome/browser:browser_process",
     "//chrome/browser/google",
     "//chrome/browser/optimization_guide",
-    "//chrome/browser/password_manager/factories:factories",
+    "//chrome/browser/password_manager/factories",
     "//chrome/browser/profiles",
     "//chrome/browser/profiles:profile",
     "//chrome/browser/signin",
@@ -35,7 +35,7 @@
     "//chrome/common",
     "//chrome/common:constants",
     "//components/browser_sync",
-    "//components/enterprise:enterprise",
+    "//components/enterprise",
     "//components/enterprise/buildflags",
     "//components/enterprise/common:strings",
     "//components/enterprise/obfuscation/core:enterprise_obfuscation",
@@ -50,7 +50,7 @@
     "//components/resources:components_resources_grit",
     "//components/safe_browsing:buildflags",
     "//components/safe_browsing/content/browser",
-    "//components/safe_browsing/content/browser/notification_content_detection:notification_content_detection",
+    "//components/safe_browsing/content/browser/notification_content_detection",
     "//components/safe_browsing/content/browser/triggers:suspicious_site_trigger",
     "//components/safe_browsing/content/browser/web_ui",
     "//components/safe_browsing/content/browser/web_ui:local_state_delegate",
@@ -71,7 +71,7 @@
     "//components/sessions",
     "//components/signin/public/identity_manager",
     "//components/url_formatter",
-    "//components/vector_icons:vector_icons",
+    "//components/vector_icons",
     "//mojo/public/cpp/platform",
     "//mojo/public/cpp/system",
     "//services/metrics/public/cpp:ukm_builders",
@@ -103,7 +103,7 @@
   if (is_win || is_mac || is_linux || is_chromeos) {
     deps += [
       "//chrome/browser/ui/browser_window",
-      "//chrome/browser/ui/toasts:toasts",
+      "//chrome/browser/ui/toasts",
       "//chrome/browser/ui/toasts/api:toasts",
     ]
   }
@@ -287,11 +287,11 @@
       "//components/site_engagement/core/mojom:mojo_bindings",
       "//components/sync_user_events",
       "//components/unified_consent",
-      "//components/url_matcher:url_matcher",
+      "//components/url_matcher",
       "//components/variations/service",
       "//components/version_info",
       "//content/public/browser",
-      "//services/preferences/public/mojom:mojom",
+      "//services/preferences/public/mojom",
     ]
 
     allow_circular_includes_from += [ "//chrome/browser/ui/safety_hub" ]
@@ -452,7 +452,7 @@
         ":verdict_cache_manager_factory",
         "//build:branding_buildflags",
         "//build:chromeos_buildflags",
-        "//chrome/app/vector_icons:vector_icons",
+        "//chrome/app/vector_icons",
         "//chrome/browser/ui/hats",
         "//chrome/common",
         "//chrome/services/file_util/public/cpp",
@@ -480,7 +480,7 @@
         "//content/public/browser",
         "//extensions/browser",
         "//net",
-        "//services/network/public/cpp:cpp",
+        "//services/network/public/cpp",
         "//third_party/abseil-cpp:absl",
       ]
       if (is_mac) {
@@ -493,9 +493,9 @@
       }
       if (is_chromeos) {
         deps += [
-          "//ash/constants:constants",
-          "//chromeos/ash/components/browser_context_helper:browser_context_helper",
-          "//chromeos/components/mgs:mgs",
+          "//ash/constants",
+          "//chromeos/ash/components/browser_context_helper",
+          "//chromeos/components/mgs",
         ]
       }
       if (!is_android) {
@@ -519,14 +519,14 @@
         "telemetry/android/android_telemetry_service.h",
       ]
       deps += [
-        "//chrome/app/vector_icons:vector_icons",
+        "//chrome/app/vector_icons",
         "//chrome/browser/safe_browsing/android",
-        "//components/messages/android:android",
+        "//components/messages/android",
         "//components/safe_browsing:buildflags",
         "//components/safe_browsing/android:remote_database_manager",
         "//components/safe_browsing/android:safe_browsing_mobile",
         "//google_apis/common:request_util",
-        "//ui/android:android",
+        "//ui/android",
 
         # TODO(crbug.com/41437292): Use //chrome/browser after fixing cyclic
         # dependency.
@@ -664,15 +664,15 @@
 
     deps += [
       ":safe_browsing",
-      "//chrome/browser:browser",
+      "//chrome/browser",
       "//chrome/browser/content_settings:content_settings_factory",
       "//chrome/browser/profiles:profile",
-      "//chrome/browser/ui:ui",
+      "//chrome/browser/ui",
       "//chrome/common",
       "//chrome/common/safe_browsing:proto",
       "//components/enterprise/common/proto:connectors_proto",
       "//components/safe_browsing:buildflags",
-      "//components/safe_browsing/content/browser:browser",
+      "//components/safe_browsing/content/browser",
       "//components/safe_browsing/content/browser:safe_browsing_blocking_page",
       "//components/safe_browsing/content/browser:safe_browsing_service",
       "//components/safe_browsing/core/browser/db:database_manager",
diff --git a/chrome/browser/safety_check/android/BUILD.gn b/chrome/browser/safety_check/android/BUILD.gn
index 4612158..aa6fe90 100644
--- a/chrome/browser/safety_check/android/BUILD.gn
+++ b/chrome/browser/safety_check/android/BUILD.gn
@@ -111,7 +111,7 @@
     "//third_party/hamcrest:hamcrest_java",
     "//third_party/hamcrest:hamcrest_library_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_full_java",
   ]
@@ -163,7 +163,7 @@
     "//third_party/androidx:androidx_test_core_java",
     "//third_party/hamcrest:hamcrest_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_full_java",
   ]
diff --git a/chrome/browser/safety_hub/android/BUILD.gn b/chrome/browser/safety_hub/android/BUILD.gn
index 338b886..877e9e0 100644
--- a/chrome/browser/safety_hub/android/BUILD.gn
+++ b/chrome/browser/safety_hub/android/BUILD.gn
@@ -215,7 +215,7 @@
     "//third_party/hamcrest:hamcrest_core_java",
     "//third_party/hamcrest:hamcrest_library_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java",
     "//ui/android:ui_java_test_support",
@@ -274,7 +274,7 @@
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/hamcrest:hamcrest_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
     "//ui/android:ui_no_recycler_view_java",
@@ -302,7 +302,7 @@
     "//chrome/browser/ui/hats",
     "//chrome/common:constants",
     "//components/content_settings/core/common",
-    "//components/page_info:page_info",
+    "//components/page_info",
     "//components/pref_registry",
     "//components/prefs",
   ]
@@ -319,7 +319,7 @@
     ":android",
     "//base/test:test_support",
     "//chrome/browser/content_settings:content_settings_factory",
-    "//chrome/browser/permissions:permissions",
+    "//chrome/browser/permissions",
     "//chrome/browser/ui",
     "//chrome/browser/ui/safety_hub",
     "//chrome/browser/ui/safety_hub:test_support",
diff --git a/chrome/browser/screen_ai/BUILD.gn b/chrome/browser/screen_ai/BUILD.gn
index fcd8a7a..a0ba66e 100644
--- a/chrome/browser/screen_ai/BUILD.gn
+++ b/chrome/browser/screen_ai/BUILD.gn
@@ -64,11 +64,11 @@
     ":screen_ai_install_state",
     "//chrome/browser/profiles:profile",
     "//components/keyed_service/core",
-    "//components/performance_manager:performance_manager",
+    "//components/performance_manager",
     "//content/public/browser",
     "//services/screen_ai/public/cpp:utilities",
+    "//services/screen_ai/public/mojom",
     "//services/screen_ai/public/mojom:factory",
-    "//services/screen_ai/public/mojom:mojom",
   ]
 
   configs += [ "//build/config/compiler:wexit_time_destructors" ]
diff --git a/chrome/browser/search_resumption/BUILD.gn b/chrome/browser/search_resumption/BUILD.gn
index c23db06a..cbd65096 100644
--- a/chrome/browser/search_resumption/BUILD.gn
+++ b/chrome/browser/search_resumption/BUILD.gn
@@ -101,7 +101,7 @@
     "//third_party/androidx:androidx_core_core_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_no_recycler_view_java",
     "//url:gurl_java",
diff --git a/chrome/browser/segmentation_platform/BUILD.gn b/chrome/browser/segmentation_platform/BUILD.gn
index 2d3a085c..9070529c 100644
--- a/chrome/browser/segmentation_platform/BUILD.gn
+++ b/chrome/browser/segmentation_platform/BUILD.gn
@@ -39,7 +39,7 @@
       "//third_party/androidx:androidx_test_runner_java",
       "//third_party/hamcrest:hamcrest_core_java",
       "//third_party/hamcrest:hamcrest_library_java",
-      "//third_party/junit:junit",
+      "//third_party/junit",
       "//url:gurl_java",
     ]
   }
diff --git a/chrome/browser/selection/android/BUILD.gn b/chrome/browser/selection/android/BUILD.gn
index 3711f4bc..255f876 100644
--- a/chrome/browser/selection/android/BUILD.gn
+++ b/chrome/browser/selection/android/BUILD.gn
@@ -39,6 +39,6 @@
     "//third_party/androidx:androidx_activity_activity_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/hamcrest:hamcrest_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
   ]
 }
diff --git a/chrome/browser/serial/android/BUILD.gn b/chrome/browser/serial/android/BUILD.gn
index 8ab47a7..18272b02 100644
--- a/chrome/browser/serial/android/BUILD.gn
+++ b/chrome/browser/serial/android/BUILD.gn
@@ -57,7 +57,7 @@
     "//components/browser_ui/notifications/android:utils_java",
     "//components/url_formatter/android:url_formatter_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//url:gurl_java",
     "//url:gurl_junit_test_support",
diff --git a/chrome/browser/share/BUILD.gn b/chrome/browser/share/BUILD.gn
index 1db1260..b9deb48 100644
--- a/chrome/browser/share/BUILD.gn
+++ b/chrome/browser/share/BUILD.gn
@@ -31,8 +31,8 @@
     "//base",
     "//chrome/browser/favicon",
     "//chrome/browser/profiles",
-    "//chrome/browser/share/proto:proto",
-    "//components/leveldb_proto:leveldb_proto",
+    "//chrome/browser/share/proto",
+    "//components/leveldb_proto",
     "//components/qr_code_generator:bitmap_generator",
     "//components/shared_highlighting/core/common",
     "//content/public/browser",
@@ -52,9 +52,9 @@
     deps += [
       ":jni_headers",
       "//chrome/android:chrome_jni_headers",
-      "//components/history/core/browser:browser",
+      "//components/history/core/browser",
       "//components/translate/content/browser",
-      "//components/ukm/content:content",
+      "//components/ukm/content",
       "//ui/android",
       "//url",
     ]
diff --git a/chrome/browser/shortcuts/BUILD.gn b/chrome/browser/shortcuts/BUILD.gn
index 689a0a15..0b4ff13 100644
--- a/chrome/browser/shortcuts/BUILD.gn
+++ b/chrome/browser/shortcuts/BUILD.gn
@@ -181,7 +181,7 @@
 
   if (is_win) {
     sources += [ "shortcut_creator_win_unittest.cc" ]
-    deps += [ "//chrome/browser:browser" ]
+    deps += [ "//chrome/browser" ]
   }
 
   if (is_mac) {
diff --git a/chrome/browser/signin/e2e_tests/BUILD.gn b/chrome/browser/signin/e2e_tests/BUILD.gn
index 3153b2a..8a2beb2 100644
--- a/chrome/browser/signin/e2e_tests/BUILD.gn
+++ b/chrome/browser/signin/e2e_tests/BUILD.gn
@@ -26,7 +26,7 @@
       "//chrome/browser",
       "//chrome/browser:browser_process",
       "//chrome/browser/sync",
-      "//chrome/browser/ui:ui",
+      "//chrome/browser/ui",
       "//chrome/browser/ui/webui/signin",
       "//chrome/test:test_support_ui",
       "//components/signin/core/browser",
diff --git a/chrome/browser/single_tab/android/BUILD.gn b/chrome/browser/single_tab/android/BUILD.gn
index 2716046..017818cf 100644
--- a/chrome/browser/single_tab/android/BUILD.gn
+++ b/chrome/browser/single_tab/android/BUILD.gn
@@ -78,7 +78,7 @@
     "//components/embedder_support/android:util_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java",
     "//url:gurl_java",
diff --git a/chrome/browser/smart_card/BUILD.gn b/chrome/browser/smart_card/BUILD.gn
index 9dfee10..33c5c31 100644
--- a/chrome/browser/smart_card/BUILD.gn
+++ b/chrome/browser/smart_card/BUILD.gn
@@ -44,7 +44,7 @@
       "//chrome/browser/permissions",
       "//chrome/browser/profiles:profile",
       "//chrome/browser/ui/browser_window",
-      "//components/content_settings/browser:browser",
+      "//components/content_settings/browser",
       "//components/permissions",
       "//components/strings:components_strings_grit",
       "//content/public/browser",
@@ -82,10 +82,10 @@
     defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
 
     deps = [
-      "//chrome/browser/smart_card:smart_card",
+      "//chrome/browser/smart_card",
       "//chrome/browser/web_applications:web_applications_test_support",
       "//chrome/test:test_support",
-      "//components/content_settings/browser:browser",
+      "//components/content_settings/browser",
       "//content/test:test_support",
       "//testing/gmock",
       "//testing/gtest",
@@ -103,7 +103,7 @@
       ":smart_card",
       "//chrome/browser",
       "//chrome/browser/content_settings:content_settings_factory",
-      "//chrome/browser/permissions:permissions",
+      "//chrome/browser/permissions",
       "//chrome/browser/policy:test_support",
       "//chrome/browser/profiles:profile",
       "//chrome/browser/ui",
diff --git a/chrome/browser/status_icons/BUILD.gn b/chrome/browser/status_icons/BUILD.gn
index ed6539c..6b434bc 100644
--- a/chrome/browser/status_icons/BUILD.gn
+++ b/chrome/browser/status_icons/BUILD.gn
@@ -28,6 +28,6 @@
     ":status_icons",
     "//base",
     "//ui/base",
-    "//ui/gfx:gfx",
+    "//ui/gfx",
   ]
 }
diff --git a/chrome/browser/supervised_user/BUILD.gn b/chrome/browser/supervised_user/BUILD.gn
index f044e527..e55443e 100644
--- a/chrome/browser/supervised_user/BUILD.gn
+++ b/chrome/browser/supervised_user/BUILD.gn
@@ -233,7 +233,7 @@
       "//third_party/androidx:androidx_test_runner_java",
       "//third_party/hamcrest:hamcrest_java",
       "//third_party/jni_zero:jni_zero_java",
-      "//third_party/junit:junit",
+      "//third_party/junit",
       "//third_party/mockito:mockito_java",
       "//ui/android:ui_java_test_support",
       "//ui/android:ui_no_recycler_view_java",
@@ -254,7 +254,7 @@
       "//chrome/android:chrome_java",
       "//third_party/android_deps:robolectric_all_java",
       "//third_party/androidx:androidx_test_runner_java",
-      "//third_party/junit:junit",
+      "//third_party/junit",
     ]
   }
 
@@ -269,7 +269,7 @@
       deps = [
         "//base",
         "//chrome/browser/profiles:profile",
-        "//chrome/browser/sync:sync",
+        "//chrome/browser/sync",
         "//chrome/test:test_support",
         "//components/messages/android/test:test_support_cpp",
         "//components/safe_search_api:test_support",
diff --git a/chrome/browser/supervised_user/supervised_user_service_android_browsertest.cc b/chrome/browser/supervised_user/supervised_user_service_android_browsertest.cc
index 9b007d89..1607fb80 100644
--- a/chrome/browser/supervised_user/supervised_user_service_android_browsertest.cc
+++ b/chrome/browser/supervised_user/supervised_user_service_android_browsertest.cc
@@ -288,6 +288,9 @@
   if (GetParam().initial_browser_content_filters_value) {
     histogram_tester().ExpectBucketCount(
         "FamilyUser.WebFilterType", WebFilterType::kTryToBlockMatureSites, 1);
+  } else if (GetParam().initial_search_content_filters_value) {
+    histogram_tester().ExpectBucketCount("FamilyUser.WebFilterType",
+                                         WebFilterType::kDisabled, 1);
   } else {
     histogram_tester().ExpectTotalCount("FamilyUser.WebFilterType", 0);
   }
@@ -427,4 +430,4 @@
 }
 
 }  // namespace
-}  // namespace supervised_user
\ No newline at end of file
+}  // namespace supervised_user
diff --git a/chrome/browser/sync/android/BUILD.gn b/chrome/browser/sync/android/BUILD.gn
index 4f4060d0..3b86d335 100644
--- a/chrome/browser/sync/android/BUILD.gn
+++ b/chrome/browser/sync/android/BUILD.gn
@@ -72,7 +72,7 @@
     "//third_party/androidx:androidx_lifecycle_lifecycle_common_java",
     "//third_party/androidx:androidx_test_core_java",
     "//third_party/androidx:androidx_test_ext_junit_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java",
     "//ui/android:ui_java_test_support",
diff --git a/chrome/browser/sync/test/android/java/src/org/chromium/chrome/browser/sync/FakeSyncServiceImpl.java b/chrome/browser/sync/test/android/java/src/org/chromium/chrome/browser/sync/FakeSyncServiceImpl.java
index 43398f7..19cd077a 100644
--- a/chrome/browser/sync/test/android/java/src/org/chromium/chrome/browser/sync/FakeSyncServiceImpl.java
+++ b/chrome/browser/sync/test/android/java/src/org/chromium/chrome/browser/sync/FakeSyncServiceImpl.java
@@ -38,6 +38,7 @@
     private boolean mTrustedVaultRecoverabilityDegraded;
     private boolean mEncryptEverythingEnabled;
     private boolean mRequiresClientUpgrade;
+    private boolean mHasUnrecoverableError;
     private GoogleServiceAuthError mAuthError =
             new GoogleServiceAuthError(GoogleServiceAuthErrorState.NONE);
     private Set<Integer> mTypesWithUnsyncedData = Set.of();
@@ -77,6 +78,21 @@
     }
 
     @Override
+    public boolean hasUnrecoverableError() {
+        ThreadUtils.assertOnUiThread();
+        return mHasUnrecoverableError;
+    }
+
+    @AnyThread
+    public void setHasUnrecoverableError(boolean hasUnrecoverableError) {
+        ThreadUtils.runOnUiThreadBlocking(
+                () -> {
+                    mHasUnrecoverableError = hasUnrecoverableError;
+                    notifySyncStateChanged();
+                });
+    }
+
+    @Override
     public boolean isUsingExplicitPassphrase() {
         ThreadUtils.assertOnUiThread();
         return true;
@@ -208,11 +224,6 @@
         return mDelegate.isSyncDisabledByEnterprisePolicy();
     }
 
-    @Override
-    public boolean hasUnrecoverableError() {
-        return mDelegate.hasUnrecoverableError();
-    }
-
     @Nullable
     @Override
     public CoreAccountInfo getAccountInfo() {
diff --git a/chrome/browser/sync/test/integration/BUILD.gn b/chrome/browser/sync/test/integration/BUILD.gn
index 6875970..26411e5 100644
--- a/chrome/browser/sync/test/integration/BUILD.gn
+++ b/chrome/browser/sync/test/integration/BUILD.gn
@@ -17,7 +17,7 @@
   configs += [ "//build/config:precompiled_headers" ]
   defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
   deps = [
-    "//chrome/browser/password_manager/factories:factories",
+    "//chrome/browser/password_manager/factories",
     "//chrome/browser/plus_addresses",
     "//chrome/browser/prefs",
     "//chrome/browser/reading_list",
diff --git a/chrome/browser/tab_group_suggestion/BUILD.gn b/chrome/browser/tab_group_suggestion/BUILD.gn
index 0854b1b7..2aff45117 100644
--- a/chrome/browser/tab_group_suggestion/BUILD.gn
+++ b/chrome/browser/tab_group_suggestion/BUILD.gn
@@ -104,7 +104,7 @@
       "//components/embedder_support/android:util_java",
       "//components/visited_url_ranking/public:public_java",
       "//content/public/android:content_java",
-      "//third_party/junit:junit",
+      "//third_party/junit",
       "//third_party/mockito:mockito_java",
       "//ui/android:ui_java",
       "//url:gurl_junit_test_support",
diff --git a/chrome/browser/tab_group_sync/BUILD.gn b/chrome/browser/tab_group_sync/BUILD.gn
index b73422ce1..4755bda7 100644
--- a/chrome/browser/tab_group_sync/BUILD.gn
+++ b/chrome/browser/tab_group_sync/BUILD.gn
@@ -15,7 +15,7 @@
   ]
 
   deps = [
-    "//base:base",
+    "//base",
     "//chrome/browser/profiles",
     "//components/prefs",
     "//components/saved_tab_groups/public:features",
@@ -173,7 +173,7 @@
       "//third_party/android_deps:robolectric_all_java",
       "//third_party/androidx:androidx_annotation_annotation_java",
       "//third_party/jni_zero:gendeps_java",
-      "//third_party/junit:junit",
+      "//third_party/junit",
       "//third_party/mockito:mockito_java",
       "//ui/android:ui_java",
       "//url:url_java",
@@ -196,7 +196,7 @@
       "//third_party/androidx:androidx_test_runner_java",
       "//third_party/hamcrest:hamcrest_core_java",
       "//third_party/hamcrest:hamcrest_library_java",
-      "//third_party/junit:junit",
+      "//third_party/junit",
       "//url:url_java",
     ]
   }
diff --git a/chrome/browser/tab_ui/android/BUILD.gn b/chrome/browser/tab_ui/android/BUILD.gn
index bd054469..f707a8b 100644
--- a/chrome/browser/tab_ui/android/BUILD.gn
+++ b/chrome/browser/tab_ui/android/BUILD.gn
@@ -170,7 +170,7 @@
     "//third_party/androidx:androidx_test_ext_junit_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/jni_zero:gendeps_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java",
     "//ui/android:ui_java_test_support",
diff --git a/chrome/browser/task_manager/internal/android/BUILD.gn b/chrome/browser/task_manager/internal/android/BUILD.gn
index 5b132c3..d6e9bab 100644
--- a/chrome/browser/task_manager/internal/android/BUILD.gn
+++ b/chrome/browser/task_manager/internal/android/BUILD.gn
@@ -75,7 +75,7 @@
     "//third_party/androidx:androidx_appcompat_appcompat_java",
     "//third_party/androidx:androidx_recyclerview_recyclerview_java",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_no_recycler_view_java",
   ]
diff --git a/chrome/browser/thumbnail/generator/BUILD.gn b/chrome/browser/thumbnail/generator/BUILD.gn
index 5bffb7f3..d9a85a8 100644
--- a/chrome/browser/thumbnail/generator/BUILD.gn
+++ b/chrome/browser/thumbnail/generator/BUILD.gn
@@ -120,7 +120,7 @@
       "//third_party/androidx:androidx_annotation_annotation_java",
       "//third_party/androidx:androidx_core_core_java",
       "//third_party/androidx:androidx_test_runner_java",
-      "//third_party/junit:junit",
+      "//third_party/junit",
       "//third_party/mockito:mockito_java",
     ]
   }
diff --git a/chrome/browser/touch_to_fill/autofill/android/BUILD.gn b/chrome/browser/touch_to_fill/autofill/android/BUILD.gn
index 94bb8a23..8fb788da 100644
--- a/chrome/browser/touch_to_fill/autofill/android/BUILD.gn
+++ b/chrome/browser/touch_to_fill/autofill/android/BUILD.gn
@@ -29,7 +29,7 @@
     "//chrome/browser/profiles",
     "//components/autofill/android:main_autofill_jni_headers",
     "//components/autofill/core/common:features",
-    "//content/public/browser:browser",
+    "//content/public/browser",
     "//third_party/libaddressinput:util",
     "//ui/android",
   ]
diff --git a/chrome/browser/touch_to_fill/autofill/android/internal/BUILD.gn b/chrome/browser/touch_to_fill/autofill/android/internal/BUILD.gn
index 5b2f06a..1dbc42e0 100644
--- a/chrome/browser/touch_to_fill/autofill/android/internal/BUILD.gn
+++ b/chrome/browser/touch_to_fill/autofill/android/internal/BUILD.gn
@@ -138,7 +138,7 @@
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/hamcrest:hamcrest_java",
     "//third_party/hamcrest:hamcrest_library_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/accessibility:ax_base_java",
     "//ui/android:ui_java_test_support",
diff --git a/chrome/browser/touch_to_fill/common/android/BUILD.gn b/chrome/browser/touch_to_fill/common/android/BUILD.gn
index 7c01916..9a3fb8e5 100644
--- a/chrome/browser/touch_to_fill/common/android/BUILD.gn
+++ b/chrome/browser/touch_to_fill/common/android/BUILD.gn
@@ -68,7 +68,7 @@
     "//components/browser_ui/widget/android:java",
     "//content/public/android:content_full_java",
     "//content/public/test/android:content_java_test_support",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
     "//ui/android:ui_no_recycler_view_java",
diff --git a/chrome/browser/touch_to_fill/password_manager/no_passkeys/android/BUILD.gn b/chrome/browser/touch_to_fill/password_manager/no_passkeys/android/BUILD.gn
index 3178073..9579f9d 100644
--- a/chrome/browser/touch_to_fill/password_manager/no_passkeys/android/BUILD.gn
+++ b/chrome/browser/touch_to_fill/password_manager/no_passkeys/android/BUILD.gn
@@ -13,7 +13,7 @@
   deps = [
     "//base",
     "//chrome/browser/touch_to_fill/password_manager/no_passkeys/internal/android:jni",
-    "//ui/android:android",
+    "//ui/android",
     "//ui/gfx",
   ]
 }
@@ -26,7 +26,7 @@
     "//base",
     "//base/test:test_support",
     "//testing/gmock",
-    "//ui/android:android",
+    "//ui/android",
   ]
 
   sources = [ "no_passkeys_bottom_sheet_bridge_unittest.cc" ]
diff --git a/chrome/browser/touch_to_fill/password_manager/no_passkeys/internal/android/BUILD.gn b/chrome/browser/touch_to_fill/password_manager/no_passkeys/internal/android/BUILD.gn
index 4f06178..c542439 100644
--- a/chrome/browser/touch_to_fill/password_manager/no_passkeys/internal/android/BUILD.gn
+++ b/chrome/browser/touch_to_fill/password_manager/no_passkeys/internal/android/BUILD.gn
@@ -52,7 +52,7 @@
     "//third_party/androidx:androidx_appcompat_appcompat_java",
     "//third_party/androidx:androidx_test_core_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_no_recycler_view_java",
   ]
@@ -82,7 +82,7 @@
     "//components/browser_ui/widget/android:java",
     "//third_party/androidx:androidx_test_monitor_java",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
     "//ui/android:ui_no_recycler_view_java",
diff --git a/chrome/browser/touch_to_fill/password_manager/password_generation/android/BUILD.gn b/chrome/browser/touch_to_fill/password_manager/password_generation/android/BUILD.gn
index c0eb2d9..36916eb 100644
--- a/chrome/browser/touch_to_fill/password_manager/password_generation/android/BUILD.gn
+++ b/chrome/browser/touch_to_fill/password_manager/password_generation/android/BUILD.gn
@@ -8,12 +8,12 @@
   deps = [
     ":android",
     "//base",
-    "//chrome/browser/autofill:autofill",
+    "//chrome/browser/autofill",
     "//chrome/browser/keyboard_accessory/android:public",
     "//chrome/browser/password_manager/android:utils",
-    "//components/password_manager/content/browser:browser",
-    "//components/password_manager/core/browser:browser",
-    "//components/prefs:prefs",
+    "//components/password_manager/content/browser",
+    "//components/password_manager/core/browser",
+    "//components/prefs",
     "//content/public/browser",
   ]
 
@@ -34,9 +34,9 @@
   deps = [
     "//chrome/browser/touch_to_fill/password_manager/password_generation/android/internal:jni",
     "//components/password_manager/core/common:features",
-    "//components/prefs:prefs",
+    "//components/prefs",
     "//content/public/browser",
-    "//ui/android:android",
+    "//ui/android",
     "//ui/gfx:native_widget_types",
   ]
 }
@@ -47,7 +47,7 @@
   deps = [
     ":android",
     "//base",
-    "//content/public/browser:browser",
+    "//content/public/browser",
     "//testing/gmock",
     "//ui/gfx:native_widget_types",
   ]
@@ -70,7 +70,7 @@
     "//chrome/browser/keyboard_accessory/test_utils/android",
     "//chrome/browser/password_manager/android:utils",
     "//chrome/test:test_support",
-    "//components/password_manager/content/browser:browser",
+    "//components/password_manager/content/browser",
     "//content/test:test_support",
   ]
 
diff --git a/chrome/browser/touch_to_fill/password_manager/password_generation/android/internal/BUILD.gn b/chrome/browser/touch_to_fill/password_manager/password_generation/android/internal/BUILD.gn
index f7706c8..863b0cf 100644
--- a/chrome/browser/touch_to_fill/password_manager/password_generation/android/internal/BUILD.gn
+++ b/chrome/browser/touch_to_fill/password_manager/password_generation/android/internal/BUILD.gn
@@ -113,7 +113,7 @@
     "//content/public/android:content_full_java",
     "//content/public/test/android:content_java_test_support",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
     "//ui/android:ui_no_recycler_view_java",
diff --git a/chrome/browser/translate/android/BUILD.gn b/chrome/browser/translate/android/BUILD.gn
index 487af48a..f5d873d 100644
--- a/chrome/browser/translate/android/BUILD.gn
+++ b/chrome/browser/translate/android/BUILD.gn
@@ -56,7 +56,7 @@
     "//third_party/androidx:androidx_appcompat_appcompat_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java",
   ]
@@ -101,7 +101,7 @@
     "//components/language/core/browser:test_support",
     "//components/language/core/common",
     "//components/metrics",
-    "//components/pref_registry:pref_registry",
+    "//components/pref_registry",
     "//components/prefs",
     "//components/prefs:test_support",
     "//components/sync_preferences:test_support",
diff --git a/chrome/browser/ui/android/edge_to_edge/BUILD.gn b/chrome/browser/ui/android/edge_to_edge/BUILD.gn
index 4988e17..2648bd7 100644
--- a/chrome/browser/ui/android/edge_to_edge/BUILD.gn
+++ b/chrome/browser/ui/android/edge_to_edge/BUILD.gn
@@ -15,6 +15,7 @@
     "java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeFieldTrialImpl.java",
     "java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeUtils.java",
     "java/src/org/chromium/chrome/browser/ui/edge_to_edge/NavigationBarColorProvider.java",
+    "java/src/org/chromium/chrome/browser/ui/edge_to_edge/SimpleEdgeToEdgeController.java",
   ]
   deps = [
     "//base:base_java",
diff --git a/chrome/browser/ui/android/edge_to_edge/internal/BUILD.gn b/chrome/browser/ui/android/edge_to_edge/internal/BUILD.gn
index 87e0d5a..40c203e 100644
--- a/chrome/browser/ui/android/edge_to_edge/internal/BUILD.gn
+++ b/chrome/browser/ui/android/edge_to_edge/internal/BUILD.gn
@@ -58,6 +58,7 @@
     "junit/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerTest.java",
     "junit/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeDebuggingInfoTest.java",
     "junit/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeFieldTrialUnitTest.java",
+    "junit/src/org/chromium/chrome/browser/ui/edge_to_edge/SimpleEdgeToEdgeControllerUnitTest.java",
     "junit/src/org/chromium/chrome/browser/ui/edge_to_edge/SimpleEdgeToEdgePadAdjusterUnitTest.java",
   ]
 
diff --git a/chrome/browser/ui/android/edge_to_edge/internal/junit/src/org/chromium/chrome/browser/ui/edge_to_edge/SimpleEdgeToEdgeControllerUnitTest.java b/chrome/browser/ui/android/edge_to_edge/internal/junit/src/org/chromium/chrome/browser/ui/edge_to_edge/SimpleEdgeToEdgeControllerUnitTest.java
new file mode 100644
index 0000000..bbf069ca
--- /dev/null
+++ b/chrome/browser/ui/android/edge_to_edge/internal/junit/src/org/chromium/chrome/browser/ui/edge_to_edge/SimpleEdgeToEdgeControllerUnitTest.java
@@ -0,0 +1,193 @@
+// Copyright 2025 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+package org.chromium.chrome.browser.ui.edge_to_edge;
+
+import static androidx.core.view.WindowInsetsCompat.Type.navigationBars;
+import static androidx.core.view.WindowInsetsCompat.Type.statusBars;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import static org.chromium.ui.insets.InsetObserver.WindowInsetsConsumer.InsetConsumerSource.EDGE_TO_EDGE_CONTROLLER_IMPL;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.DisplayMetrics;
+import android.view.View;
+
+import androidx.core.graphics.Insets;
+import androidx.core.view.WindowInsetsCompat;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowBuild;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.components.browser_ui.edge_to_edge.EdgeToEdgePadAdjuster;
+import org.chromium.components.browser_ui.edge_to_edge.EdgeToEdgeSupplier;
+import org.chromium.ui.insets.InsetObserver;
+
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(shadows = ShadowBuild.class)
+public class SimpleEdgeToEdgeControllerUnitTest {
+    @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+    private static final int TOP_STATUS_INSET = 100;
+    private static final int BOTTOM_NAV_INSET = 100;
+    private static final WindowInsetsCompat WINDOW_INSETS_WITH_NAVBAR =
+            new WindowInsetsCompat.Builder()
+                    .setInsets(statusBars(), Insets.of(0, TOP_STATUS_INSET, 0, 0))
+                    .setInsets(navigationBars(), Insets.of(0, 0, 0, BOTTOM_NAV_INSET))
+                    .build();
+    private static final WindowInsetsCompat WINDOW_INSETS =
+            new WindowInsetsCompat.Builder()
+                    .setInsets(statusBars(), Insets.of(0, TOP_STATUS_INSET, 0, 0))
+                    .setInsets(navigationBars(), Insets.of(0, 0, 0, 0))
+                    .build();
+
+    @Mock private Context mContext;
+    @Mock private Resources mResources;
+    @Mock private DisplayMetrics mDisplayMetrics;
+    @Mock private View mView;
+    @Mock private InsetObserver mInsetObserver;
+    private SimpleEdgeToEdgeController mSimpleEdgeToEdgeController;
+
+    @Before
+    public void setup() {
+        doReturn(mResources).when(mContext).getResources();
+        doReturn(mDisplayMetrics).when(mResources).getDisplayMetrics();
+
+        mSimpleEdgeToEdgeController = new SimpleEdgeToEdgeController(mContext, mInsetObserver);
+        verify(mInsetObserver, times(1)).addInsetsConsumer(any(), eq(EDGE_TO_EDGE_CONTROLLER_IMPL));
+        verify(mInsetObserver, times(1)).retriggerOnApplyWindowInsets();
+    }
+
+    @Test
+    public void testSimpleEdgeToEdgeController_withNavBar() {
+        mSimpleEdgeToEdgeController.onApplyWindowInsets(mView, WINDOW_INSETS_WITH_NAVBAR);
+        assertEquals(
+                "The controller should return the correct bottom inset.",
+                BOTTOM_NAV_INSET,
+                mSimpleEdgeToEdgeController.getBottomInsetPx());
+        assertTrue(
+                "The controller should be drawing edge-to-edge.",
+                mSimpleEdgeToEdgeController.isDrawingToEdge());
+        assertTrue(
+                "The contorller should be opted into edge-to-edge.",
+                mSimpleEdgeToEdgeController.isPageOptedIntoEdgeToEdge());
+
+        // Verify that the inset is still correct after the same insets are seen again.
+        mSimpleEdgeToEdgeController.onApplyWindowInsets(mView, WINDOW_INSETS_WITH_NAVBAR);
+        assertEquals(
+                "The controller should return the correct bottom inset.",
+                BOTTOM_NAV_INSET,
+                mSimpleEdgeToEdgeController.getBottomInsetPx());
+    }
+
+    @Test
+    public void testSimpleEdgeToEdgeController_noNavBar() {
+        mSimpleEdgeToEdgeController.onApplyWindowInsets(mView, WINDOW_INSETS);
+        assertEquals(
+                "The controller should indicate a bottom inset of 0.",
+                0,
+                mSimpleEdgeToEdgeController.getBottomInsetPx());
+        assertFalse(
+                "The controller should not be drawing edge-to-edge.",
+                mSimpleEdgeToEdgeController.isDrawingToEdge());
+        assertFalse(
+                "The controller should not be opted into edge-to-edge.",
+                mSimpleEdgeToEdgeController.isPageOptedIntoEdgeToEdge());
+    }
+
+    @Test
+    public void testSimpleEdgeToEdgeController_notifiesObservers() {
+        TestChangeObserver changeObserver = new TestChangeObserver();
+        mSimpleEdgeToEdgeController.registerObserver(changeObserver);
+
+        mSimpleEdgeToEdgeController.onApplyWindowInsets(mView, WINDOW_INSETS_WITH_NAVBAR);
+        changeObserver.checkState(
+                BOTTOM_NAV_INSET, /* isDrawingToEdge= */ true, /* isPageOptInToEdge= */ true);
+
+        mSimpleEdgeToEdgeController.onApplyWindowInsets(mView, WINDOW_INSETS);
+        changeObserver.checkState(0, /* isDrawingToEdge= */ false, /* isPageOptInToEdge= */ false);
+
+        mSimpleEdgeToEdgeController.onApplyWindowInsets(mView, WINDOW_INSETS_WITH_NAVBAR);
+        changeObserver.checkState(
+                BOTTOM_NAV_INSET, /* isDrawingToEdge= */ true, /* isPageOptInToEdge= */ true);
+    }
+
+    @Test
+    public void testSimpleEdgeToEdgeController_notifiesAdjusters() {
+        TestPadAdjuster padAdjuster = new TestPadAdjuster();
+        mSimpleEdgeToEdgeController.registerAdjuster(padAdjuster);
+
+        mSimpleEdgeToEdgeController.onApplyWindowInsets(mView, WINDOW_INSETS_WITH_NAVBAR);
+        padAdjuster.checkInsets(BOTTOM_NAV_INSET);
+
+        mSimpleEdgeToEdgeController.onApplyWindowInsets(mView, WINDOW_INSETS);
+        padAdjuster.checkInsets(0);
+
+        mSimpleEdgeToEdgeController.onApplyWindowInsets(mView, WINDOW_INSETS_WITH_NAVBAR);
+        padAdjuster.checkInsets(BOTTOM_NAV_INSET);
+    }
+
+    private static class TestChangeObserver implements EdgeToEdgeSupplier.ChangeObserver {
+        private int mInset;
+        private boolean mIsDrawingToEdge;
+        private boolean mIsPageOptInToEdge;
+
+        TestChangeObserver() {}
+
+        @Override
+        public void onToEdgeChange(
+                int bottomInset, boolean isDrawingToEdge, boolean isPageOptInToEdge) {
+            mInset = bottomInset;
+            mIsDrawingToEdge = isDrawingToEdge;
+            mIsPageOptInToEdge = isPageOptInToEdge;
+        }
+
+        void checkState(int bottomInset, boolean isDrawingToEdge, boolean isPageOptInToEdge) {
+            assertEquals(
+                    "The change observer does not have the expected inset.", bottomInset, mInset);
+            assertEquals(
+                    "The change observer does not match the expected drawing toEdge state.",
+                    isDrawingToEdge,
+                    mIsDrawingToEdge);
+            assertEquals(
+                    "The change observer does not match the expected edge-to-edge opt-in state.",
+                    isPageOptInToEdge,
+                    mIsPageOptInToEdge);
+        }
+    }
+
+    private static class TestPadAdjuster implements EdgeToEdgePadAdjuster {
+        private int mInset;
+
+        TestPadAdjuster() {}
+
+        @Override
+        public void overrideBottomInset(int inset) {
+            mInset = inset;
+        }
+
+        @Override
+        public void destroy() {}
+
+        void checkInsets(int expected) {
+            assertEquals("The pad adjuster does not have the expected inset.", expected, mInset);
+        }
+    }
+}
diff --git a/chrome/browser/ui/android/edge_to_edge/java/src/org/chromium/chrome/browser/ui/edge_to_edge/SimpleEdgeToEdgeController.java b/chrome/browser/ui/android/edge_to_edge/java/src/org/chromium/chrome/browser/ui/edge_to_edge/SimpleEdgeToEdgeController.java
new file mode 100644
index 0000000..e5d2e14
--- /dev/null
+++ b/chrome/browser/ui/android/edge_to_edge/java/src/org/chromium/chrome/browser/ui/edge_to_edge/SimpleEdgeToEdgeController.java
@@ -0,0 +1,139 @@
+// Copyright 2025 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.ui.edge_to_edge;
+
+import static androidx.core.view.WindowInsetsCompat.Type.navigationBars;
+
+import static org.chromium.ui.insets.InsetObserver.WindowInsetsConsumer.InsetConsumerSource.EDGE_TO_EDGE_CONTROLLER_IMPL;
+
+import android.content.Context;
+import android.view.View;
+
+import androidx.annotation.Px;
+import androidx.annotation.VisibleForTesting;
+import androidx.core.graphics.Insets;
+import androidx.core.view.WindowInsetsCompat;
+
+import org.chromium.base.ObserverList;
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.components.browser_ui.edge_to_edge.EdgeToEdgePadAdjuster;
+import org.chromium.ui.insets.InsetObserver;
+
+/**
+ * A simple implementation of the {@link EdgeToEdgeController} that consumes the bottom navigation
+ * bar insets and makes them available to pad views containing content.
+ */
+@NullMarked
+public class SimpleEdgeToEdgeController implements EdgeToEdgeController {
+    private final InsetObserver mInsetObserver;
+    private final InsetObserver.WindowInsetsConsumer mWindowInsetsConsumer;
+    private final ObserverList<ChangeObserver> mObservers = new ObserverList<>();
+    private final ObserverList<EdgeToEdgePadAdjuster> mAdjusters = new ObserverList<>();
+
+    /** Multiplier to convert from pixels to DPs. */
+    private final float mPxToDp;
+
+    private @Px int mBottomInset;
+
+    /**
+     * Creates a simple edge-to-edge controller for consuming bottom navigation bar insets and
+     * padding views accordingly.
+     *
+     * @param context The context of the host view.
+     * @param insetObserver The {@link InsetObserver} for observing the system's window insets.
+     */
+    public SimpleEdgeToEdgeController(Context context, InsetObserver insetObserver) {
+        mPxToDp = 1.f / context.getResources().getDisplayMetrics().density;
+        mInsetObserver = insetObserver;
+        mWindowInsetsConsumer = this::onApplyWindowInsets;
+        mInsetObserver.addInsetsConsumer(mWindowInsetsConsumer, EDGE_TO_EDGE_CONTROLLER_IMPL);
+        mInsetObserver.retriggerOnApplyWindowInsets();
+    }
+
+    @VisibleForTesting
+    WindowInsetsCompat onApplyWindowInsets(View view, WindowInsetsCompat windowInsetsCompat) {
+        Insets navigationBarInsets = windowInsetsCompat.getInsets(navigationBars());
+        if (mBottomInset != navigationBarInsets.bottom) {
+            mBottomInset = navigationBarInsets.bottom;
+            updateObservers();
+            updatePadAdjusters();
+        }
+        return new WindowInsetsCompat.Builder(windowInsetsCompat)
+                .setInsets(
+                        navigationBars(),
+                        Insets.of(
+                                navigationBarInsets.left,
+                                navigationBarInsets.top,
+                                navigationBarInsets.right,
+                                0))
+                .build();
+    }
+
+    @Override
+    public void destroy() {
+        if (mInsetObserver != null) {
+            mInsetObserver.removeInsetsConsumer(mWindowInsetsConsumer);
+        }
+    }
+
+    @Override
+    public int getBottomInset() {
+        return (int) Math.ceil(mBottomInset * mPxToDp);
+    }
+
+    @Override
+    public int getBottomInsetPx() {
+        return mBottomInset;
+    }
+
+    @Override
+    public int getSystemBottomInsetPx() {
+        return mBottomInset;
+    }
+
+    @Override
+    public boolean isDrawingToEdge() {
+        return mBottomInset > 0;
+    }
+
+    @Override
+    public boolean isPageOptedIntoEdgeToEdge() {
+        return isDrawingToEdge();
+    }
+
+    @Override
+    public void registerObserver(ChangeObserver changeObserver) {
+        mObservers.addObserver(changeObserver);
+        changeObserver.onToEdgeChange(mBottomInset, isDrawingToEdge(), isPageOptedIntoEdgeToEdge());
+    }
+
+    @Override
+    public void unregisterObserver(ChangeObserver changeObserver) {
+        mObservers.removeObserver(changeObserver);
+    }
+
+    @Override
+    public void registerAdjuster(EdgeToEdgePadAdjuster adjuster) {
+        mAdjusters.addObserver(adjuster);
+        adjuster.overrideBottomInset(mBottomInset);
+    }
+
+    @Override
+    public void unregisterAdjuster(EdgeToEdgePadAdjuster adjuster) {
+        mAdjusters.removeObserver(adjuster);
+    }
+
+    private void updateObservers() {
+        for (ChangeObserver observer : mObservers) {
+            observer.onToEdgeChange(mBottomInset, isDrawingToEdge(), isPageOptedIntoEdgeToEdge());
+        }
+    }
+
+    private void updatePadAdjusters() {
+        for (EdgeToEdgePadAdjuster adjuster : mAdjusters) {
+            adjuster.overrideBottomInset(mBottomInset);
+        }
+    }
+}
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
index 971dabe..aa4ae610 100644
--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
+++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -689,12 +689,6 @@
       <message name="IDS_PASSWORD_SAVING_OFF_BY_ADMINISTRATOR" desc="Subtitle for the settings menu item leading to the Password Manager UI surface, shown when the device administrator set saving passwords to disabled.">
         Password saving is turned off by your administrator
       </message>
-      <message name="IDS_PASSWORD_SETTINGS_SAVE_PASSWORDS" desc="Title for the checkbox toggling whether passwords are saved or not. [CHAR_LIMIT=32]">
-        Save passwords
-      </message>
-      <message name="IDS_PASSWORDS_AUTO_SIGNIN_TITLE" desc="Title for checkbox to enable automatically signing the user in to websites">
-        Auto Sign-in
-      </message>
       <message name="IDS_PASSWORDS_ACCOUNT_STORAGE_NOTICE_TITLE" desc="Title of the sheet that notifies the user they are saving passwords to their Google Account.">
         Passwords on all your devices
       </message>
@@ -713,9 +707,6 @@
       <message name="IDS_PASSWORDS_ACCOUNT_STORAGE_NOTICE_CLOSED_ACCESSIBILITY_LABEL" desc="Accessibility label of the sheet that notifies the user they are saving passwords to their Google Account, when the sheet is closed.">
         Passwords on all your devices closed
       </message>
-      <message name="IDS_PASSWORDS_AUTO_SIGNIN_DESCRIPTION" desc="Text under 'Auto sign-in' checkbox">
-        Automatically sign in to websites using stored credentials. When the feature is off, you’ll be asked for verification every time before signing in to a website.
-      </message>
       <message name="IDS_PASSWORDS_LEAK_DETECTION_SWITCH_TITLE" desc="Title for the switch toggling whether Chrome should check that entered credentials have been part of a leak.">
         Warn you if a password was compromised in a data breach
       </message>
@@ -725,30 +716,9 @@
       <message name="IDS_PASSWORDS_CHECK_TITLE" desc="Title for the check passwords button which allows to check whether the user's passwords have been compromised.">
         Check passwords
       </message>
-      <message name="IDS_PASSWORDS_CHECK_DESCRIPTION" desc="Text explaining the benefits of checking the passwords, to be displayed under the Check Passwords button title.">
-        Keep your passwords safe from data breaches and other security issues
-      </message>
-      <message name="IDS_ANDROID_TRUSTED_VAULT_BANNER_LABEL" desc="Title for the on-device encryption banner in password settings.">
-        On-device encryption
-      </message>
-      <message name="IDS_ANDROID_TRUSTED_VAULT_BANNER_SUB_LABEL_OFFER_OPT_IN" desc="Sub-label for the on-device encryption banner when the user is offered to opt in.">
-        For added safety, encrypt passwords on your device before they‘re saved to Google Password Manager
-      </message>
-      <message name="IDS_ANDROID_TRUSTED_VAULT_BANNER_SUB_LABEL_OPTED_IN" desc="Sub-label for the on-device encryption banner when the user is already opted in.">
-        Your passwords are encrypted on your device before they’re saved to Google Password Manager
-      </message>
       <message name="IDS_SECTION_SAVED_PASSWORDS_EXCEPTIONS" desc="Header for the list of websites for which user selected to never save passwords. [CHAR_LIMIT=32]">
         Never saved
       </message>
-      <message name="IDS_MANAGE_PASSWORDS_TEXT" desc="Text for link to manage passwords on Account Central.">
-        View and manage saved passwords in your <ph name="BEGIN_LINK">&lt;link&gt;</ph>Google Account<ph name="END_LINK">&lt;/link&gt;</ph>
-      </message>
-      <message name="IDS_SAVED_PASSWORDS_NONE_TEXT" desc="Text when there are no saved passwords/exceptions.">
-        Saved passwords will appear here.
-      </message>
-      <message name="IDS_PASSWORD_NO_RESULT" desc="Text when a password search returned no results.">
-        Can’t find that password. Check your spelling and try again.
-      </message>
       <message name="IDS_PASSWORD_EDIT_HINT" desc="Small hint on the editing screens that advises users to store the same password as they use on the currently edited site.">
         Make sure the password you are saving matches your password for <ph name="SITE">%1$s<ex>example.com</ex></ph>
       </message>
@@ -821,30 +791,12 @@
       <message name="IDS_PASSWORD_EXPORT_SET_LOCK_SCREEN" desc="Text prompting user to set device lock in order to be able to export passwords">
         Turn on screen lock in Settings to export your passwords from this device
       </message>
-      <message name="IDS_PASSWORD_SETTINGS_EXPORT_ACTION_TITLE" desc="The title of a menu item to trigger exporting passwords from the password settings.">
-        Export passwords…
-      </message>
-      <message name="IDS_PASSWORD_SETTINGS_EXPORT_ACTION_DESCRIPTION" desc="The description of a menu item to trigger exporting passwords from the password settings.">
-        Export passwords stored with Chrome
-      </message>
-      <message name="IDS_SETTINGS_PASSWORDS_PREPARING_EXPORT" desc="Text shown to the user above a progress bar, informing the user that passwords are being prepared for export.">
-        Preparing passwords…
-      </message>
       <message name="IDS_PASSWORD_SETTINGS_EXPORT_ERROR_TITLE" desc="The title of a dialog showing an error encountered during exporting passwords from the passwords settings.">
         Can’t export passwords
       </message>
-      <message name="IDS_PASSWORD_SETTINGS_EXPORT_LEARN_GOOGLE_DRIVE" desc="The label of a button in an error dialog after exporting passwords from the settings failed. The button takes the user to a help article about using Google Drive.">
-        Learn how to use Google Drive
-      </message>
-      <message name="IDS_PASSWORD_SETTINGS_EXPORT_NO_APP" desc="The explanation of the error when exporting passwords fails because the user has no Android app installed which could consume the exported data. The description is shown in the body of an alert dialog.">
-        Your device doesn’t have an app to store the passwords file.
-      </message>
       <message name="IDS_PASSWORD_SETTINGS_EXPORT_TIPS" desc="Tips on how to fix an error with exporting passwords. They are shown in the body of an alert dialog.">
         Try the following tips: make sure there is enough space on your device, try to export again.
       </message>
-      <message name="IDS_PASSWORD_SETTINGS_EXPORT_ERROR_DETAILS" desc="A short prefix to introduce a technical error message passed to the user from Android after exporting passwords through a temporary file fails. Both the prefix and the error message are shown in the body of an alert dialog.">
-        Details: <ph name="ERROR_DESCRIPTION">%1$s<ex>IOException: No space left on device</ex></ph>
-      </message>
       <message name="IDS_PASSWORDS_NOT_SECURE_FILLING" desc="The title of the dialog which is shown when the user attempts to enter obfuscated text to a regular text field.">
         Not secure
       </message>
@@ -929,9 +881,6 @@
       <message name="IDS_LOCKSCREEN_DESCRIPTION_EDIT" desc="When a user attempts to edit a password for a particular website in Chrome's settings, Chrome launches a lock screen to verify the user's identity and displays the following explanation.">
         Unlock to edit your password
       </message>
-      <message name="IDS_LOCKSCREEN_DESCRIPTION_EXPORT" desc="When a user attempts to export saved passwords in Chrome's settings, Chrome launches a lock screen to verify the user's identity and displays the following explanation.">
-        Unlock to export your passwords
-      </message>
 
       <!-- Homepage preferences -->
       <message name="IDS_OPTIONS_HOMEPAGE_EDIT_HINT" desc="Hint for the text edit on Homepage Preference setting, guiding user to enter their customized homepage setting">
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_TRUSTED_VAULT_BANNER_LABEL.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_TRUSTED_VAULT_BANNER_LABEL.png.sha1
deleted file mode 100644
index 8d5a058..0000000
--- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_TRUSTED_VAULT_BANNER_LABEL.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-d28d4141f2fe2ce44e78f6896cadb5ecd86d4ffe
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_TRUSTED_VAULT_BANNER_SUB_LABEL_OFFER_OPT_IN.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_TRUSTED_VAULT_BANNER_SUB_LABEL_OFFER_OPT_IN.png.sha1
deleted file mode 100644
index 8d5a058..0000000
--- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_TRUSTED_VAULT_BANNER_SUB_LABEL_OFFER_OPT_IN.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-d28d4141f2fe2ce44e78f6896cadb5ecd86d4ffe
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_TRUSTED_VAULT_BANNER_SUB_LABEL_OPTED_IN.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_TRUSTED_VAULT_BANNER_SUB_LABEL_OPTED_IN.png.sha1
deleted file mode 100644
index 26df889..0000000
--- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ANDROID_TRUSTED_VAULT_BANNER_SUB_LABEL_OPTED_IN.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-6eba108be0894a08ee8671f01afc350b282295c4
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PASSWORDS_CHECK_DESCRIPTION.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PASSWORDS_CHECK_DESCRIPTION.png.sha1
deleted file mode 100644
index 7dde38f..0000000
--- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PASSWORDS_CHECK_DESCRIPTION.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-dde9e67e02af87bf8b25a1dff9de112432fff9cc
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PASSWORD_NO_RESULT.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PASSWORD_NO_RESULT.png.sha1
deleted file mode 100644
index 683a145..0000000
--- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PASSWORD_NO_RESULT.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-821ca2ab80b59d7b81213e77ed7efc201dbe31f6
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java
index 0f967915..dff065e 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java
@@ -137,6 +137,11 @@
      * @param trackerSupplier Provides a {@link Tracker} when available.
      * @param homeButtonDisplay The {@link HomeButtonDisplay} to manage the display and behavior of
      *     home button(s). Should be null on custom tabs.
+     * @param extensionToolbarCoordinator Provides an {@link ExtensionToolbarCoordinator} for
+     *     interacting with extension-related toolbar UI.
+     * @param normalThemeColorProvider The {@link ThemeColorProvider} for normal mode.
+     * @param incognitoStateProvider The {@link IncognitoStateProvider} for observering incognito
+     *     state.
      */
     @CallSuper
     @Initializer
@@ -152,12 +157,17 @@
             @Nullable ReloadButtonCoordinator reloadButtonCoordinator,
             @Nullable BackButtonCoordinator backButtonCoordinator,
             @Nullable HomeButtonDisplay homeButtonDisplay,
-            @Nullable ExtensionToolbarCoordinator extensionToolbarCoordinator) {
+            @Nullable ExtensionToolbarCoordinator extensionToolbarCoordinator,
+            ThemeColorProvider themeColorProvider,
+            IncognitoStateProvider incognitoStateProvider) {
         mToolbarDataProvider = toolbarDataProvider;
         mToolbarTabController = tabController;
         mMenuButtonCoordinator = menuButtonCoordinator;
         mTabSwitcherButtonCoordinator = tabSwitcherButtonCoordinator;
         mProgressBar = progressBar;
+
+        setThemeColorProvider(themeColorProvider);
+        setIncognitoStateProvider(incognitoStateProvider);
     }
 
     /**
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
index df9d64d76..7fbf64a 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
@@ -62,7 +62,9 @@
 import org.chromium.chrome.browser.omnibox.styles.OmniboxResourceProvider;
 import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestionsDropdownScrollListener;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider;
 import org.chromium.chrome.browser.theme.SurfaceColorUpdateUtils;
+import org.chromium.chrome.browser.theme.ThemeColorProvider;
 import org.chromium.chrome.browser.theme.ThemeUtils;
 import org.chromium.chrome.browser.toolbar.R;
 import org.chromium.chrome.browser.toolbar.ToolbarDataProvider;
@@ -365,7 +367,9 @@
             @Nullable ReloadButtonCoordinator reloadButtonCoordinator,
             @Nullable BackButtonCoordinator backButtonCoordinator,
             @Nullable HomeButtonDisplay homeButtonDisplay,
-            @Nullable ExtensionToolbarCoordinator extensionToolbarCoordinator) {
+            @Nullable ExtensionToolbarCoordinator extensionToolbarCoordinator,
+            ThemeColorProvider themeColorProvider,
+            IncognitoStateProvider incognitoStateProvider) {
         super.initialize(
                 toolbarDataProvider,
                 tabController,
@@ -378,7 +382,9 @@
                 reloadButtonCoordinator,
                 backButtonCoordinator,
                 homeButtonDisplay,
-                extensionToolbarCoordinator);
+                extensionToolbarCoordinator,
+                themeColorProvider,
+                incognitoStateProvider);
         mUserEducationHelper = userEducationHelper;
         mTrackerSupplier = trackerSupplier;
         mHomeButtonDisplay = assumeNonNull(homeButtonDisplay);
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java
index 2f4836f..0b0f140 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java
@@ -39,7 +39,9 @@
 import org.chromium.chrome.browser.omnibox.UrlBarData;
 import org.chromium.chrome.browser.omnibox.status.StatusCoordinator;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider;
 import org.chromium.chrome.browser.theme.SurfaceColorUpdateUtils;
+import org.chromium.chrome.browser.theme.ThemeColorProvider;
 import org.chromium.chrome.browser.theme.ThemeUtils;
 import org.chromium.chrome.browser.toolbar.R;
 import org.chromium.chrome.browser.toolbar.ToolbarDataProvider;
@@ -396,7 +398,9 @@
             @Nullable ReloadButtonCoordinator reloadButtonCoordinator,
             @Nullable BackButtonCoordinator backButtonCoordinator,
             @Nullable HomeButtonDisplay homeButtonDisplay,
-            @Nullable ExtensionToolbarCoordinator extensionToolbarCoordinator) {
+            @Nullable ExtensionToolbarCoordinator extensionToolbarCoordinator,
+            ThemeColorProvider themeColorProvider,
+            IncognitoStateProvider incognitoStateProvider) {
         super.initialize(
                 toolbarDataProvider,
                 tabController,
@@ -409,7 +413,9 @@
                 reloadButtonCoordinator,
                 backButtonCoordinator,
                 homeButtonDisplay,
-                extensionToolbarCoordinator);
+                extensionToolbarCoordinator,
+                themeColorProvider,
+                incognitoStateProvider);
         mHistoryDelegate = historyDelegate;
         mReloadButtonCoordinator = assertNonNull(reloadButtonCoordinator);
         mBackButtonCoordinator = assertNonNull(backButtonCoordinator);
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTabletUnitTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTabletUnitTest.java
index 560f71a7..1d6035f 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTabletUnitTest.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTabletUnitTest.java
@@ -53,6 +53,8 @@
 import org.chromium.chrome.browser.omnibox.LocationBarLayout;
 import org.chromium.chrome.browser.omnibox.NewTabPageDelegate;
 import org.chromium.chrome.browser.omnibox.status.StatusCoordinator;
+import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider;
+import org.chromium.chrome.browser.theme.ThemeColorProvider;
 import org.chromium.chrome.browser.theme.ThemeUtils;
 import org.chromium.chrome.browser.toolbar.R;
 import org.chromium.chrome.browser.toolbar.ToolbarDataProvider;
@@ -90,6 +92,8 @@
     @Mock private NewTabPageDelegate mNewTabPageDelegate;
     @Mock private ReloadButtonCoordinator mReloadButtonCoordinator;
     @Mock private BackButtonCoordinator mBackButtonCoordinator;
+    @Mock private ThemeColorProvider mThemeColorProvider;
+    @Mock private IncognitoStateProvider mIncognitoStateProvider;
     private Activity mActivity;
     private ToolbarTablet mToolbarTablet;
     private LinearLayout mToolbarTabletLayout;
@@ -177,7 +181,9 @@
                 mReloadButtonCoordinator,
                 mBackButtonCoordinator,
                 /* homeButtonDisplay= */ null,
-                null);
+                null,
+                mThemeColorProvider,
+                mIncognitoStateProvider);
         when(mToolbarDataProvider.getNewTabPageDelegate()).thenReturn(mNewTabPageDelegate);
         when(mToolbarDataProvider.isIncognitoBranded()).thenReturn(true);
         mToolbarTablet.onTabOrModelChanged();
@@ -271,7 +277,9 @@
                 mReloadButtonCoordinator,
                 mBackButtonCoordinator,
                 /* homeButtonDisplay= */ null,
-                null);
+                null,
+                mThemeColorProvider,
+                mIncognitoStateProvider);
         when(mToolbarDataProvider.getNewTabPageDelegate()).thenReturn(mNewTabPageDelegate);
         when(mToolbarDataProvider.isIncognitoBranded()).thenReturn(true);
         mToolbarTablet.onTabOrModelChanged();
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
index 725d4df..0b3dc67b 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
@@ -4,7 +4,6 @@
 
 package org.chromium.chrome.browser.toolbar.top;
 
-import android.content.Context;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.view.View;
@@ -37,7 +36,6 @@
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabObscuringHandler;
 import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider;
-import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider.IncognitoStateObserver;
 import org.chromium.chrome.browser.theme.ThemeColorProvider;
 import org.chromium.chrome.browser.theme.TopUiThemeColorProvider;
 import org.chromium.chrome.browser.toolbar.R;
@@ -58,7 +56,6 @@
 import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper;
 import org.chromium.chrome.browser.user_education.UserEducationHelper;
 import org.chromium.components.browser_ui.desktop_windowing.DesktopWindowStateManager;
-import org.chromium.components.browser_ui.styles.ChromeColors;
 import org.chromium.components.browser_ui.widget.ClipDrawableProgressBar.DrawingInfo;
 import org.chromium.components.feature_engagement.Tracker;
 import org.chromium.ui.resources.ResourceManager;
@@ -103,9 +100,6 @@
      */
     private final ToolbarColorObserverManager mToolbarColorObserverManager;
 
-    private @Nullable IncognitoStateProvider mIncognitoStateProvider;
-    private @Nullable IncognitoStateObserver mIncognitoStateObserver;
-
     private final TabObscuringHandler mTabObscuringHandler;
     private final @Nullable DesktopWindowStateManager mDesktopWindowStateManager;
     private final OneshotSupplier<TabStripTransitionDelegate> mTabStripTransitionDelegateSupplier;
@@ -130,6 +124,8 @@
      *     browsing mode toolbar.
      * @param layoutStateProviderSupplier Supplier of the {@link LayoutStateProvider}.
      * @param normalThemeColorProvider The {@link ThemeColorProvider} for normal mode.
+     * @param incognitoStateProvider The {@link IncognitoStateProvider} for observering incognito
+     *     state.
      * @param browsingModeMenuButtonCoordinator Root component for app menu.
      * @param appMenuButtonHelperSupplier For specific handling of the app menu button.
      * @param tabCountSupplier Supplier of {@link
@@ -163,6 +159,7 @@
             List<ButtonDataProvider> buttonDataProviders,
             OneshotSupplier<LayoutStateProvider> layoutStateProviderSupplier,
             ThemeColorProvider normalThemeColorProvider,
+            IncognitoStateProvider incognitoStateProvider,
             MenuButtonCoordinator browsingModeMenuButtonCoordinator,
             ObservableSupplier<AppMenuButtonHelper> appMenuButtonHelperSupplier,
             ToggleTabStackButtonCoordinator tabSwitcherButtonCoordinator,
@@ -252,8 +249,9 @@
                 mReloadButtonCoordinator,
                 mBackButtonCoordinator,
                 homeButtonDisplay,
-                extensionToolbarCoordinator);
-        mToolbarLayout.setThemeColorProvider(normalThemeColorProvider);
+                extensionToolbarCoordinator,
+                normalThemeColorProvider,
+                incognitoStateProvider);
         mAppMenuButtonHelperSupplier = appMenuButtonHelperSupplier;
         new OneShotCallback<>(mAppMenuButtonHelperSupplier, this::setAppMenuButtonHelper);
         homepageEnabledSupplier.addObserver(
@@ -430,7 +428,6 @@
             mTabStripTransitionCoordinator.destroy();
             mTabStripTransitionCoordinator = null;
         }
-        cleanUpIncognitoStateObserver();
     }
 
     /**
@@ -663,31 +660,6 @@
     }
 
     /**
-     * @param provider The provider used to determine incognito state.
-     * @param overviewColorSupplier Optional override for toolbar color, otherwise it is derived
-     *     from incognito state.
-     */
-    public void setIncognitoStateProvider(
-            IncognitoStateProvider provider,
-            @Nullable ObservableSupplier<Integer> overviewColorSupplier) {
-        mToolbarLayout.setIncognitoStateProvider(provider);
-        if (overviewColorSupplier == null) {
-            assert mToolbarLayout != null;
-            cleanUpIncognitoStateObserver();
-            ObservableSupplierImpl<Integer> supplierImpl = new ObservableSupplierImpl<>();
-            Context context = mToolbarLayout.getContext();
-            mIncognitoStateObserver =
-                    (boolean isIncognito) -> {
-                        @ColorInt
-                        int color = ChromeColors.getPrimaryBackgroundColor(context, isIncognito);
-                        supplierImpl.set(color);
-                    };
-            mIncognitoStateProvider = provider;
-            provider.addIncognitoStateObserverAndTrigger(mIncognitoStateObserver);
-        }
-    }
-
-    /**
      * Gives inheriting classes the chance to update themselves based on default search engine
      * changes.
      */
@@ -748,14 +720,6 @@
         return mToolbarLayout.getLocationBar();
     }
 
-    private void cleanUpIncognitoStateObserver() {
-        if (mIncognitoStateProvider != null && mIncognitoStateObserver != null) {
-            mIncognitoStateProvider.removeObserver(mIncognitoStateObserver);
-            mIncognitoStateProvider = null;
-            mIncognitoStateObserver = null;
-        }
-    }
-
     @Override
     public int getHeight() {
         return mToolbarLayout.getHeight();
diff --git a/chrome/browser/ui/ash/network/network_portal_notification_controller_unittest.cc b/chrome/browser/ui/ash/network/network_portal_notification_controller_unittest.cc
index fcfab0d..93ae996 100644
--- a/chrome/browser/ui/ash/network/network_portal_notification_controller_unittest.cc
+++ b/chrome/browser/ui/ash/network/network_portal_notification_controller_unittest.cc
@@ -48,6 +48,8 @@
   void SetUp() override {
     BrowserWithTestWindowTest::SetUp();
 
+    controller_.emplace();
+
     TestingBrowserProcess::GetGlobal()->SetSystemNotificationHelper(
         std::make_unique<SystemNotificationHelper>());
     display_service_ = std::make_unique<NotificationDisplayServiceTester>(
@@ -67,7 +69,7 @@
  protected:
   void PortalStateChanged(const NetworkState* network,
                           NetworkState::PortalState portal_state) {
-    controller_.PortalStateChanged(network, portal_state);
+    controller_->PortalStateChanged(network, portal_state);
   }
 
   bool HasNotification() {
@@ -75,7 +77,7 @@
   }
 
   std::unique_ptr<NotificationDisplayServiceTester> display_service_;
-  NetworkPortalNotificationController controller_;
+  std::optional<NetworkPortalNotificationController> controller_;
 };
 
 TEST_F(NetworkPortalNotificationControllerTest, NetworkStateChangedPortal) {
diff --git a/chrome/browser/ui/ash/shelf/BUILD.gn b/chrome/browser/ui/ash/shelf/BUILD.gn
index 163ade0..61ca6bf 100644
--- a/chrome/browser/ui/ash/shelf/BUILD.gn
+++ b/chrome/browser/ui/ash/shelf/BUILD.gn
@@ -96,6 +96,7 @@
     "//chrome/browser/ash/arc/fileapi",
     "//chrome/browser/ash/arc/pip",
     "//chrome/browser/ash/arc/session",
+    "//chrome/browser/ash/browser_delegate",
     "//chrome/browser/ash/crostini",
     "//chrome/browser/ash/eche_app",
     "//chrome/browser/ash/extensions",
@@ -142,6 +143,7 @@
     "//components/favicon/content",
     "//components/pref_registry",
     "//components/prefs",
+    "//components/session_manager/core",
     "//components/sync_preferences",
     "//components/webapps/common",
     "//extensions/browser",
@@ -220,6 +222,7 @@
     "//chrome/browser/ash/arc",
     "//chrome/browser/ash/arc:arc_util",
     "//chrome/browser/ash/arc/session",
+    "//chrome/browser/ash/browser_delegate:impl",
     "//chrome/browser/ash/crostini:test_support",
     "//chrome/browser/ash/eche_app",
     "//chrome/browser/ash/file_manager",
diff --git a/chrome/browser/ui/ash/shelf/DEPS b/chrome/browser/ui/ash/shelf/DEPS
index 7c930b9..8e04fe6 100644
--- a/chrome/browser/ui/ash/shelf/DEPS
+++ b/chrome/browser/ui/ash/shelf/DEPS
@@ -1,16 +1,8 @@
 include_rules = [
+  "+chromeos/ash/experiences/system_web_apps/types",
   "+components/services/app_service/public",
   "+components/app_restore/full_restore_utils.h",
   "+components/app_icon_loader",
-  "+chromeos/ash/experiences/system_web_apps/types",
-
-  # ChromeOS should not depend on //chrome. See //docs/chromeos/code.md for
-  # details.
-  "-chrome",
-
-  # This directory is in //chrome, which violates the rule above. Allow this
-  # directory to #include its own files.
-  "+chrome/browser/ui/ash/shelf",
 
   # Existing dependencies within //chrome. There is an active effort to
   # refactor ash codes in //chrome to break these dependencies; see b/332804822.
@@ -88,6 +80,7 @@
 
 specific_include_rules = {
   "chrome_shelf_controller_unittest\.cc": [
+    "+chrome/browser/ash/browser_delegate/browser_controller_impl.h",
     "+chrome/browser/ash/wallpaper_handlers/wallpaper_fetcher_delegate.h",
     "+chrome/browser/ui/ash/wallpaper/wallpaper_controller_client_impl.h",
     "+chrome/browser/ui/web_applications/test",
diff --git a/chrome/browser/ui/ash/shelf/browser_status_monitor.cc b/chrome/browser/ui/ash/shelf/browser_status_monitor.cc
index 5586d58d..a97c940f 100644
--- a/chrome/browser/ui/ash/shelf/browser_status_monitor.cc
+++ b/chrome/browser/ui/ash/shelf/browser_status_monitor.cc
@@ -10,6 +10,7 @@
 #include "base/containers/contains.h"
 #include "base/debug/dump_without_crashing.h"
 #include "base/memory/raw_ptr.h"
+#include "chrome/browser/ash/browser_delegate/browser_controller.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
 #include "chrome/browser/ui/ash/shelf/app_service/app_service_app_window_shelf_controller.h"
 #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h"
@@ -23,6 +24,7 @@
 #include "chrome/browser/web_applications/web_app_helpers.h"
 #include "chrome/browser/web_applications/web_app_utils.h"
 #include "chrome/common/chrome_features.h"
+#include "components/user_manager/user_manager.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/navigation_handle.h"
@@ -450,7 +452,9 @@
 void BrowserStatusMonitor::SetShelfIDForBrowserWindowContents(
     Browser* browser,
     content::WebContents* web_contents) {
-  shelf_controller_->SetShelfIDForBrowserWindowContents(browser, web_contents);
+  shelf_controller_->SetShelfIDForBrowserWindowContents(
+      ash::BrowserController::GetInstance()->GetDelegate(browser),
+      web_contents);
 
   if (app_service_instance_helper_) {
     app_service_instance_helper_->OnSetShelfIDForBrowserWindowContents(
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc
index 5e283ff..40bb62e 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc
@@ -48,6 +48,8 @@
 #include "chrome/browser/ash/app_list/arc/arc_app_utils.h"
 #include "chrome/browser/ash/app_list/md_icon_normalizer.h"
 #include "chrome/browser/ash/arc/arc_util.h"
+#include "chrome/browser/ash/browser_delegate/browser_controller.h"
+#include "chrome/browser/ash/browser_delegate/browser_delegate.h"
 #include "chrome/browser/ash/system_web_apps/system_web_app_manager.h"
 #include "chrome/browser/extensions/chrome_app_icon_loader.h"
 #include "chrome/browser/extensions/extension_util.h"
@@ -371,7 +373,8 @@
     if (IsBrowserRepresentedInBrowserList(browser, model_) &&
         browser->tab_strip_model()->GetActiveWebContents()) {
       SetShelfIDForBrowserWindowContents(
-          browser, browser->tab_strip_model()->GetActiveWebContents());
+          ash::BrowserController::GetInstance()->GetDelegate(browser),
+          browser->tab_strip_model()->GetActiveWebContents());
     }
   }
 
@@ -579,7 +582,9 @@
       }
       UpdateAppState(web_contents, false /*remove*/);
       if (browser->tab_strip_model()->GetActiveWebContents() == web_contents) {
-        SetShelfIDForBrowserWindowContents(browser, web_contents);
+        SetShelfIDForBrowserWindowContents(
+            ash::BrowserController::GetInstance()->GetDelegate(browser),
+            web_contents);
       }
     }
   }
@@ -771,13 +776,25 @@
 }
 
 void ChromeShelfController::SetShelfIDForBrowserWindowContents(
-    Browser* browser,
+    ash::BrowserDelegate* browser,
     content::WebContents* web_contents) {
+  if (!browser) {
+    return;
+  }
+
   // We need to set the window ShelfID for V1 applications since they are
   // content which might change and as such change the application type.
   // The browser window may not exist in unit tests.
-  if (!browser || !browser->window() || !browser->window()->GetNativeWindow() ||
-      !multi_user_util::IsProfileFromActiveUser(browser->profile())) {
+  aura::Window* window = browser->GetNativeWindow();
+  if (!window) {
+    return;
+  }
+
+  const session_manager::Session* active_session =
+      session_manager::SessionManager::Get()->GetActiveSession();
+  const AccountId active_id =
+      active_session ? active_session->account_id() : EmptyAccountId();
+  if (browser->GetAccountId() != active_id) {
     return;
   }
 
@@ -785,14 +802,11 @@
   if (app_id.empty()) {
     app_id = kChromeAppId;
   }
-
-  browser->window()->GetNativeWindow()->SetProperty(ash::kAppIDKey,
-                                                    new std::string(app_id));
+  window->SetProperty(ash::kAppIDKey, new std::string(app_id));
 
   const ash::ShelfItem* item = GetItem(ash::ShelfID(app_id));
   const ash::ShelfID shelf_id = item ? item->id : ash::ShelfID(kChromeAppId);
-  browser->window()->GetNativeWindow()->SetProperty(
-      ash::kShelfIDKey, new std::string(shelf_id.Serialize()));
+  window->SetProperty(ash::kShelfIDKey, new std::string(shelf_id.Serialize()));
 }
 
 void ChromeShelfController::OnUserProfileReadyToSwitch(Profile* profile) {
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.h b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.h
index 2722951e..9c7a6f4b 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.h
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.h
@@ -45,6 +45,7 @@
 }
 
 namespace ash {
+class BrowserDelegate;
 class ShelfModel;
 FORWARD_DECLARE_TEST(SpokenFeedbackTest, ShelfIconFocusForward);
 FORWARD_DECLARE_TEST(SpokenFeedbackTest, SpeakingTextUnderMouseForShelfItem);
@@ -211,7 +212,7 @@
   void UpdateBrowserItemState();
 
   // Sets the shelf id for the browser window if the browser is represented.
-  void SetShelfIDForBrowserWindowContents(Browser* browser,
+  void SetShelfIDForBrowserWindowContents(ash::BrowserDelegate* browser,
                                           content::WebContents* web_contents);
 
   // Called when the user profile is fully loaded and ready to switch to.
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
index 5c41a8c..3fe36b9 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
@@ -89,6 +89,7 @@
 #include "chrome/browser/ash/apps/apk_web_app_service.h"
 #include "chrome/browser/ash/arc/arc_util.h"
 #include "chrome/browser/ash/arc/session/arc_session_manager.h"
+#include "chrome/browser/ash/browser_delegate/browser_controller_impl.h"
 #include "chrome/browser/ash/crostini/crostini_test_helper.h"
 #include "chrome/browser/ash/crostini/crostini_util.h"
 #include "chrome/browser/ash/eche_app/app_id.h"
@@ -622,6 +623,8 @@
     if (StartWebAppProviderForMainProfile()) {
       StartWebAppProvider(profile());
     }
+
+    browser_controller_.emplace();
   }
 
   virtual bool StartWebAppProviderForMainProfile() const { return true; }
@@ -713,6 +716,7 @@
   }
 
   void TearDown() override {
+    browser_controller_.reset();
     app_registry_cache_observer_.Reset();
     arc_test_.TearDown();
     shelf_controller_ = nullptr;
@@ -743,6 +747,14 @@
     shelf_controller_->SetProfileForTest(profile());
     shelf_controller_->SetShelfControllerHelperForTest(
         std::make_unique<ShelfControllerHelper>(profile()));
+
+    // MultiUserWindowManagerImpl is created (indirectly) by
+    // ChromeShelfController when there's more than one user.
+    if (ash::MultiUserWindowManagerImpl::Get()) {
+      ash::MultiUserWindowManagerImpl::Get()->SetAnimationSpeedForTest(
+          ash::MultiUserWindowManagerImpl::ANIMATION_SPEED_DISABLED);
+    }
+
     return shelf_controller_.get();
   }
 
@@ -1331,6 +1343,10 @@
     return extension ? extension->is_platform_app() : false;
   }
 
+  const AccountId& account_id() const {
+    return CHECK_DEREF(ash::AnnotatedAccountId::Get(profile()));
+  }
+
   // Needed for extension service & friends to work.
   scoped_refptr<Extension> extension_chrome_;
   scoped_refptr<Extension> extension1_;
@@ -1383,6 +1399,7 @@
 
   std::unique_ptr<WallpaperControllerClientImpl> wallpaper_controller_client_;
   apps::AppServiceTest app_service_test_;
+  std::optional<ash::BrowserControllerImpl> browser_controller_;
 };
 
 class ChromeShelfControllerWithArcTest : public ChromeShelfControllerTestBase {
@@ -1516,12 +1533,16 @@
     ash::ProfileHelper::Get();  // Instantiate
     ash::BrowserContextHelper::Get()->SetUseAnnotatedAccountIdForTesting();
     ChromeShelfControllerTestBase::SetUp();
-    // Ensure there are multiple profiles. User 0 is created during setup.
-    CreateMultiUserProfile("user1@example.com", GaiaId("fakegaia1"));
+
+    // Add another user but make sure user0 (created in SetUp) is active when
+    // test bodies run.
+    profile1_ = LogInSecondaryUser("user1@example.com", GaiaId("fakegaia1"));
+    SwitchActiveUserByAccountId(account_id());
     ASSERT_TRUE(SessionControllerClientImpl::IsMultiProfileAvailable());
   }
 
   void TearDown() override {
+    profile1_ = nullptr;
     ChromeShelfControllerTestBase::TearDown();
 
     // A Task is leaked if we don't destroy everything, then run the message
@@ -1530,26 +1551,27 @@
   }
 
   bool StartWebAppProviderForMainProfile() const override {
-    // The provider is started in CreateMultiUserProfile()
+    // The provider is started in CreateProfile().
     return false;
   }
 
-  // Creates a user and profile for a given `email`. Note that this class will
-  // keep the ownership of the created object.
-  TestingProfile* CreateMultiUserProfile(std::string_view email,
-                                         const GaiaId& gaia_id) {
+  // Creates a user and logs in, i.e. starts a session, creates a profile, and
+  // makes the user the active one. Returns the created profile, of which it
+  // keeps ownership.
+  TestingProfile* LogInSecondaryUser(std::string_view email,
+                                     const GaiaId& gaia_id) {
     LogIn(email, gaia_id);
-    return CreateProfile(std::string(email));
+    auto* result = CreateProfile(std::string(email));
+    // Note: Part of the active user switching already happens in CreateProfile
+    // (see SessionManager::OnUserProfileCreated).
+    return result;
   }
 
   // Switch to another user by AccountId.
   // TODO(b/40286020): Migrate into SwitchActiveUser().
   void SwitchActiveUserByAccountId(const AccountId& account_id) {
     user_manager()->SwitchActiveUser(account_id);
-    ash::MultiUserWindowManagerImpl::Get()->SetAnimationSpeedForTest(
-        ash::MultiUserWindowManagerImpl::ANIMATION_SPEED_DISABLED);
-    ash::MultiUserWindowManagerImpl::Get()->OnActiveUserSessionChanged(
-        account_id);
+    SwitchActiveUser(account_id.GetUserEmail());
   }
 
   // Creates a browser with a |profile| and load a tab with a |title| and |url|.
@@ -1584,15 +1606,6 @@
     return "user0@example.com";
   }
 
-  void LogIn(std::string_view email, const GaiaId& gaia_id) override {
-    // TODO(crbug.com/40286020): Merge into BrowserWithTestWindowTest.
-    const AccountId account_id = AccountId::FromUserEmailGaiaId(email, gaia_id);
-    // Add a user to the fake user manager.
-    user_manager()->AddGaiaUser(account_id, user_manager::UserType::kRegular);
-    user_manager()->UserLoggedIn(
-        account_id, user_manager::TestHelper::GetFakeUsernameHash(account_id));
-  }
-
   TestingProfile* CreateProfile(const std::string& profile_name) override {
     const user_manager::User* user =
         user_manager()->FindUser(AccountId::FromUserEmail(profile_name));
@@ -1617,8 +1630,15 @@
     return profile;
   }
 
+  Profile* profile1() const { return profile1_.get(); }
+
+  const AccountId& account_id1() const {
+    return CHECK_DEREF(ash::AnnotatedAccountId::Get(profile1()));
+  }
+
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
+  raw_ptr<Profile> profile1_ = nullptr;
 };
 
 class ChromeShelfControllerMultiProfileWithArcTest
@@ -2376,8 +2396,6 @@
   EXPECT_EQ("Chrome, app1, app2, gmail", GetPinnedAppStatus());
 
   // Remember the current order of applications for the current user.
-  const AccountId& current_account_id =
-      multi_user_util::GetAccountIdFromProfile(profile());
   RememberUnpinnedRunningApplicationOrder();
 
   // Switch some items and check that restoring a user which was not yet
@@ -2390,7 +2408,7 @@
   EXPECT_EQ("Chrome, app2, app1, gmail", GetPinnedAppStatus());
 
   // Restoring the stored user should however do the right thing.
-  RestoreUnpinnedRunningApplicationOrder(current_account_id);
+  RestoreUnpinnedRunningApplicationOrder(account_id());
   EXPECT_EQ("Chrome, app1, app2, gmail", GetPinnedAppStatus());
 
   // Switch again some items and even delete one - making sure that the missing
@@ -2398,15 +2416,15 @@
   model_->Move(2, 3);
   shelf_controller_->SetAppStatus(extension1_->id(), ash::STATUS_CLOSED);
   EXPECT_EQ("Chrome, gmail, app2", GetPinnedAppStatus());
-  RestoreUnpinnedRunningApplicationOrder(current_account_id);
+  RestoreUnpinnedRunningApplicationOrder(account_id());
   EXPECT_EQ("Chrome, app2, gmail", GetPinnedAppStatus());
 
   // Check that removing more items does not crash and changes nothing.
   shelf_controller_->SetAppStatus(extension2_->id(), ash::STATUS_CLOSED);
-  RestoreUnpinnedRunningApplicationOrder(current_account_id);
+  RestoreUnpinnedRunningApplicationOrder(account_id());
   EXPECT_EQ("Chrome, gmail", GetPinnedAppStatus());
   shelf_controller_->SetAppStatus(ash::kGmailAppId, ash::STATUS_CLOSED);
-  RestoreUnpinnedRunningApplicationOrder(current_account_id);
+  RestoreUnpinnedRunningApplicationOrder(account_id());
   EXPECT_EQ("Chrome", GetPinnedAppStatus());
 }
 
@@ -2583,14 +2601,15 @@
   // user is active.
   // Gmail created when secondary user is active.
 
+  // TODO(crbug.com/369688254): Use user1 created by the parent SetUp.
   constexpr char kUser2[] = "user2@example.com";
   const GaiaId kFakeGaia2("fakegaia2");
-  TestingProfile* profile2 = CreateMultiUserProfile(kUser2, kFakeGaia2);
-  const AccountId account_id(
-      multi_user_util::GetAccountIdFromProfile(profile()));
+  TestingProfile* profile2 = LogInSecondaryUser(kUser2, kFakeGaia2);
   const AccountId account_id2(
       multi_user_util::GetAccountIdFromProfile(profile2));
 
+  SwitchActiveUserByAccountId(account_id());
+
   const std::string arc_app_id1 =
       ArcAppTest::GetAppId(*arc_test_.fake_apps()[0]);
   const std::string arc_app_id2 =
@@ -2626,7 +2645,7 @@
   arc_test_.app_instance()->SendTaskDestroyed(2);
 
   shelf_controller_->SetProfileForTest(profile());
-  SwitchActiveUserByAccountId(account_id);
+  SwitchActiveUserByAccountId(account_id());
 
   EXPECT_TRUE(shelf_controller_->GetItem(ash::ShelfID(arc_app_id1)));
   EXPECT_FALSE(shelf_controller_->GetItem(ash::ShelfID(arc_app_id2)));
@@ -3087,18 +3106,11 @@
     EXPECT_EQ(2, model_->item_count());
 
     // After switching to a second user the item should be gone.
-    const char kUser2[] = "user2@example.com";
-    const GaiaId kFakeGaia2("fakegaia2");
-    TestingProfile* profile2 = CreateMultiUserProfile(kUser2, kFakeGaia2);
-    const AccountId account_id2(
-        multi_user_util::GetAccountIdFromProfile(profile2));
-    const AccountId account_id(
-        multi_user_util::GetAccountIdFromProfile(profile()));
-    SwitchActiveUserByAccountId(account_id2);
+    SwitchActiveUserByAccountId(account_id1());
     EXPECT_EQ(1, model_->item_count());
 
     // After switching back the item should be back.
-    SwitchActiveUserByAccountId(account_id);
+    SwitchActiveUserByAccountId(account_id());
     EXPECT_EQ(2, model_->item_count());
     // Note we destroy now the gmail app with the closure end.
   }
@@ -3111,34 +3123,23 @@
   // Create a browser item in the controller.
   InitShelfController();
 
-  // First test: Create an app when the user is not active.
-  constexpr char kUser2[] = "user2@example.com";
-  const GaiaId kFakeGaia2("fakegaia2");
-  TestingProfile* profile2 = CreateMultiUserProfile(kUser2, kFakeGaia2);
-  const AccountId account_id2(
-      multi_user_util::GetAccountIdFromProfile(profile2));
-  const AccountId account_id(
-      multi_user_util::GetAccountIdFromProfile(profile()));
-  {
-    // Create a "windowed gmail app".
-    std::unique_ptr<V1App> v1_app(
-        CreateRunningV1App(profile2, extension_misc::kGmailAppId, kGmailUrl));
-    EXPECT_EQ(1, model_->item_count());
-
-    // However - switching to the user should show it.
-    SwitchActiveUserByAccountId(account_id2);
-    EXPECT_EQ(2, model_->item_count());
-
-    // Second test: Remove the app when the user is not active and see that it
-    // works.
-    SwitchActiveUserByAccountId(account_id);
-    EXPECT_EQ(1, model_->item_count());
-    // Note: the closure ends and the browser will go away.
-  }
+  // First test: Create an app for user1 when a different user is active.
+  std::unique_ptr<V1App> v1_app(
+      CreateRunningV1App(profile1(), extension_misc::kGmailAppId, kGmailUrl));
   EXPECT_EQ(1, model_->item_count());
-  SwitchActiveUserByAccountId(account_id2);
+
+  // Switching to user1 should show it.
+  SwitchActiveUserByAccountId(account_id1());
+  EXPECT_EQ(2, model_->item_count());
+
+  // Second test: Remove the app when user1 is not active.
+  SwitchActiveUserByAccountId(account_id());
   EXPECT_EQ(1, model_->item_count());
-  SwitchActiveUserByAccountId(account_id);
+  v1_app.reset();
+  EXPECT_EQ(1, model_->item_count());
+  SwitchActiveUserByAccountId(account_id1());
+  EXPECT_EQ(1, model_->item_count());
+  SwitchActiveUserByAccountId(account_id());
   EXPECT_EQ(1, model_->item_count());
 }
 
@@ -3148,34 +3149,23 @@
   // Create a browser item in the controller.
   InitShelfController();
 
-  // First create an app when the user is active.
-  constexpr char kUser2[] = "user2@example.com";
-  const GaiaId kFakeGaia2("fakegaia2");
-  TestingProfile* profile2 = CreateMultiUserProfile(kUser2, kFakeGaia2);
-  const AccountId account_id(
-      multi_user_util::GetAccountIdFromProfile(profile()));
-  const AccountId account_id2(
-      multi_user_util::GetAccountIdFromProfile(profile2));
-  {
-    // Create a "windowed gmail app".
-    std::unique_ptr<V1App> v1_app(CreateRunningV1App(
-        profile(), extension_misc::kGmailAppId, kGmailLaunchURL));
-    EXPECT_EQ(2, model_->item_count());
-    SwitchActiveUserByAccountId(account_id2);
-    EXPECT_EQ(1, model_->item_count());
-  }
-  // After the app was destroyed, switch back. (which caused already a crash).
-  SwitchActiveUserByAccountId(account_id);
-
-  // Create the same app again - which was also causing the crash.
+  // First create an app for user0 when it is active. After the app was
+  // destroyed, switch back (which caused already a crash).
+  std::unique_ptr<V1App> v1_app(CreateRunningV1App(
+      profile(), extension_misc::kGmailAppId, kGmailLaunchURL));
+  EXPECT_EQ(2, model_->item_count());
+  SwitchActiveUserByAccountId(account_id1());
   EXPECT_EQ(1, model_->item_count());
-  {
-    // Create a "windowed gmail app".
-    std::unique_ptr<V1App> v1_app(CreateRunningV1App(
-        profile(), extension_misc::kGmailAppId, kGmailLaunchURL));
-    EXPECT_EQ(2, model_->item_count());
-  }
-  SwitchActiveUserByAccountId(account_id2);
+  v1_app.reset();
+  SwitchActiveUserByAccountId(account_id());
+
+  // Create the same app again - which was also causing a crash.
+  EXPECT_EQ(1, model_->item_count());
+  v1_app.reset(CreateRunningV1App(profile(), extension_misc::kGmailAppId,
+                                  kGmailLaunchURL));
+  EXPECT_EQ(2, model_->item_count());
+  v1_app.reset();
+  SwitchActiveUserByAccountId(account_id1());
   EXPECT_EQ(1, model_->item_count());
 }
 
@@ -3185,75 +3175,54 @@
   // Create a browser item in the controller.
   InitShelfController();
 
-  // First test: Create an app when the user is not active.
-  constexpr char kUser2[] = "user2@example.com";
-  const GaiaId kFakeGaia2("fakegaia2");
-  TestingProfile* profile2 = CreateMultiUserProfile(kUser2, kFakeGaia2);
-  const AccountId account_id(
-      multi_user_util::GetAccountIdFromProfile(profile()));
-  const AccountId account_id2(
-      multi_user_util::GetAccountIdFromProfile(profile2));
-  SwitchActiveUserByAccountId(account_id2);
-  {
-    // Create a "windowed gmail app".
-    std::unique_ptr<V1App> v1_app(
-        CreateRunningV1App(profile(), extension_misc::kGmailAppId, kGmailUrl));
-    EXPECT_EQ(1, model_->item_count());
-
-    // However - switching to the user should show it.
-    SwitchActiveUserByAccountId(account_id);
-    EXPECT_EQ(2, model_->item_count());
-
-    // Second test: Remove the app when the user is not active and see that it
-    // works.
-    SwitchActiveUserByAccountId(account_id2);
-    EXPECT_EQ(1, model_->item_count());
-    v1_app.reset();
-  }
+  // First test: Create an app for user0 when a different user is active.
+  SwitchActiveUserByAccountId(account_id1());
+  std::unique_ptr<V1App> v1_app(
+      CreateRunningV1App(profile(), extension_misc::kGmailAppId, kGmailUrl));
   EXPECT_EQ(1, model_->item_count());
-  SwitchActiveUserByAccountId(account_id);
+  // Switching to user0 should show it.
+  SwitchActiveUserByAccountId(account_id());
+  EXPECT_EQ(2, model_->item_count());
+
+  // Second test: Remove the app when user0 is not active.
+  SwitchActiveUserByAccountId(account_id1());
   EXPECT_EQ(1, model_->item_count());
-  SwitchActiveUserByAccountId(account_id2);
+  v1_app.reset();
+  EXPECT_EQ(1, model_->item_count());
+  SwitchActiveUserByAccountId(account_id());
+  EXPECT_EQ(1, model_->item_count());
+  SwitchActiveUserByAccountId(account_id1());
   EXPECT_EQ(1, model_->item_count());
 }
 
-// Check that activating an item which is on another user's desktop, will bring
-// it back.
+// Check that activating an item that is on another user's desktop will bring it
+// back.
 TEST_F(MultiProfileMultiBrowserShelfLayoutChromeShelfControllerTest,
        TestShelfActivationPullsBackWindow) {
   // Create a browser item in the controller.
   InitShelfController();
+
   ash::MultiUserWindowManager* window_manager =
       MultiUserWindowManagerHelper::GetWindowManager();
 
-  // Create a second test profile. The first is the one in profile() created in
-  // BrowserWithTestWindowTest::SetUp(). No need to add the profiles to the
-  // MultiUserWindowManagerHelper here. CreateMultiUserProfile() already does
-  // that.
-  TestingProfile* profile2 =
-      CreateMultiUserProfile("user2@example.com", GaiaId("fakegaia2"));
-  const AccountId current_user =
-      multi_user_util::GetAccountIdFromProfile(profile());
-
-  // Create a browser window with a native window for the current user.
+  // Create a browser window with a native window for user0.
   std::unique_ptr<Browser> browser(
       CreateBrowserWithTestWindowForProfile(profile()));
   BrowserWindow* browser_window = browser->window();
   aura::Window* window = browser_window->GetNativeWindow();
-  window_manager->SetWindowOwner(window, current_user);
+  window_manager->SetWindowOwner(window, account_id());
 
   // Check that an activation of the window on its owner's desktop does not
   // change the visibility to another user.
   shelf_controller_->ActivateWindowOrMinimizeIfActive(browser_window, false);
-  EXPECT_TRUE(IsWindowOnDesktopOfUser(window, current_user));
+  EXPECT_TRUE(IsWindowOnDesktopOfUser(window, account_id()));
 
   // Transfer the window to another user's desktop and check that activating it
   // does pull it back to that user.
-  window_manager->ShowWindowForUser(
-      window, multi_user_util::GetAccountIdFromProfile(profile2));
-  EXPECT_FALSE(IsWindowOnDesktopOfUser(window, current_user));
+  window_manager->ShowWindowForUser(window, account_id1());
+  EXPECT_FALSE(IsWindowOnDesktopOfUser(window, account_id()));
   shelf_controller_->ActivateWindowOrMinimizeIfActive(browser_window, false);
-  EXPECT_TRUE(IsWindowOnDesktopOfUser(window, current_user));
+  EXPECT_TRUE(IsWindowOnDesktopOfUser(window, account_id()));
 }
 
 // Tests that web app icon is removed from shelf after user switch if the app is
@@ -3264,14 +3233,7 @@
   // Create a browser item in the controller.
   InitShelfController();
 
-  constexpr char kUser2[] = "user2@example.com";
-  const GaiaId kFakeGaia2("fakegaia2");
-  TestingProfile* profile2 = CreateMultiUserProfile(kUser2, kFakeGaia2);
-  const AccountId account_id(
-      multi_user_util::GetAccountIdFromProfile(profile()));
-  const AccountId account_id2(
-      multi_user_util::GetAccountIdFromProfile(profile2));
-
+  SwitchActiveUserByAccountId(account_id());
   constexpr char kWebAppUrl[] = "https://webappone.com/";
   constexpr char kWebAppName[] = "WebApp1";
 
@@ -3285,21 +3247,19 @@
       web_app::test::InstallWebApp(profile(), std::move(web_app_info));
   PinAppWithIDToShelf(installed_app_id);
 
-  std::unique_ptr<Browser> profile2_browser =
-      CreateBrowserAndTabWithProfile(profile2, kWebAppName, kWebAppUrl);
-
+  std::unique_ptr<Browser> profile1_browser =
+      CreateBrowserAndTabWithProfile(profile1(), kWebAppName, kWebAppUrl);
   EXPECT_EQ(
       std::vector<std::string>({app_constants::kChromeAppId, installed_app_id}),
       GetAppsShownInShelf());
 
   // Switch to the secondary user, and verify the app only installed in the
   // primary profile is removed from the model.
-  SwitchActiveUserByAccountId(account_id2);
-
+  SwitchActiveUserByAccountId(account_id1());
   EXPECT_EQ(std::vector<std::string>({app_constants::kChromeAppId}),
             GetAppsShownInShelf());
 
-  chrome::CloseTab(profile2_browser.get());
+  chrome::CloseTab(profile1_browser.get());
 }
 
 // Check that a running windowed V1 application will be properly pinned and
@@ -3742,34 +3702,29 @@
 
   // Show the created |browser()| by showing its window.
   browser()->window()->Show();
-  std::u16string title1 = u"Test1";
-  NavigateAndCommitActiveTabWithTitle(browser(), GURL("http://test1"), title1);
-  std::u16string one_menu_item1[] = {title1};
-  CheckAppMenu(shelf_controller_.get(), item_browser, 1, one_menu_item1);
+  std::u16string title = u"Test";
+  NavigateAndCommitActiveTabWithTitle(browser(), GURL("http://test"), title);
+  std::u16string one_menu_item[] = {title};
+  CheckAppMenu(shelf_controller_.get(), item_browser, 1, one_menu_item);
 
   // Create a browser for another user and check that it is not included in the
   // users running browser list.
-  constexpr char kUser2[] = "user2@example.com";
-  const GaiaId kFakeGaia2("fakegaia2");
-  TestingProfile* profile2 = CreateMultiUserProfile(kUser2, kFakeGaia2);
-  const AccountId account_id2(
-      multi_user_util::GetAccountIdFromProfile(profile2));
-  std::unique_ptr<Browser> browser2(
-      CreateBrowserAndTabWithProfile(profile2, "user2", "http://test2"));
-  std::u16string one_menu_item2[] = {u"user2"};
-  CheckAppMenu(shelf_controller_.get(), item_browser, 1, one_menu_item1);
+  std::unique_ptr<Browser> browser1(
+      CreateBrowserAndTabWithProfile(profile1(), "user1", "http://test1"));
+  CheckAppMenu(shelf_controller_.get(), item_browser, 1, one_menu_item);
 
   // Switch to the other user and make sure that only that browser window gets
   // shown.
-  SwitchActiveUserByAccountId(account_id2);
-  CheckAppMenu(shelf_controller_.get(), item_browser, 1, one_menu_item2);
+  SwitchActiveUserByAccountId(account_id1());
+  std::u16string one_menu_item1[] = {u"user1"};
+  CheckAppMenu(shelf_controller_.get(), item_browser, 1, one_menu_item1);
 
   // Transferred browsers of other users should not show up in the list.
   MultiUserWindowManagerHelper::GetWindowManager()->ShowWindowForUser(
-      browser()->window()->GetNativeWindow(), account_id2);
-  CheckAppMenu(shelf_controller_.get(), item_browser, 1, one_menu_item2);
+      browser()->window()->GetNativeWindow(), account_id1());
+  CheckAppMenu(shelf_controller_.get(), item_browser, 1, one_menu_item1);
 
-  chrome::CloseTab(browser2.get());
+  chrome::CloseTab(browser1.get());
 }
 
 // Check that V1 apps are correctly reflected in the shelf menu using the
@@ -3867,13 +3822,7 @@
   std::u16string one_menu_item[] = {title1};
   CheckAppMenu(shelf_controller_.get(), item_gmail, 1, one_menu_item);
 
-  // Create a second profile and switch to that user.
-  constexpr char kUser2[] = "user2@example.com";
-  const GaiaId kFakeGaia2("fakegaia2");
-  TestingProfile* profile2 = CreateMultiUserProfile(kUser2, kFakeGaia2);
-  const AccountId account_id2(
-      multi_user_util::GetAccountIdFromProfile(profile2));
-  SwitchActiveUserByAccountId(account_id2);
+  SwitchActiveUserByAccountId(account_id1());
 
   // No item should have content yet.
   CheckAppMenu(shelf_controller_.get(), item_browser, 0, nullptr);
@@ -3881,7 +3830,7 @@
 
   // Transfer the browser of the first user - it should still not show up.
   MultiUserWindowManagerHelper::GetWindowManager()->ShowWindowForUser(
-      browser()->window()->GetNativeWindow(), account_id2);
+      browser()->window()->GetNativeWindow(), account_id1());
 
   CheckAppMenu(shelf_controller_.get(), item_browser, 0, nullptr);
   CheckAppMenu(shelf_controller_.get(), item_gmail, 0, nullptr);
@@ -3892,8 +3841,7 @@
 TEST_F(MultiProfileMultiBrowserShelfLayoutChromeShelfControllerTest,
        V2AppHandlingTwoUsers) {
   InitShelfController();
-  const AccountId account_id(
-      multi_user_util::GetAccountIdFromProfile(profile()));
+
   // Check that there is a browser.
   EXPECT_EQ(1, model_->item_count());
 
@@ -3902,18 +3850,12 @@
   V2App v2_app(profile(), extension1_.get());
   EXPECT_EQ(2, model_->item_count());
 
-  // Create a profile for our second user (will be destroyed by the framework).
-  TestingProfile* profile2 =
-      CreateMultiUserProfile("user2@example.com", GaiaId("fakegaia2"));
-  const AccountId account_id2(
-      multi_user_util::GetAccountIdFromProfile(profile2));
-
   // After switching users the item should go away.
-  SwitchActiveUserByAccountId(account_id2);
+  SwitchActiveUserByAccountId(account_id1());
   EXPECT_EQ(1, model_->item_count());
 
   // And it should come back when switching back.
-  SwitchActiveUserByAccountId(account_id);
+  SwitchActiveUserByAccountId(account_id());
   EXPECT_EQ(2, model_->item_count());
 }
 
@@ -3923,34 +3865,26 @@
 TEST_F(MultiProfileMultiBrowserShelfLayoutChromeShelfControllerTest,
        V2AppHandlingTwoUsersEdgeCases) {
   InitShelfController();
-  // Create a profile for our second user (will be destroyed by the framework).
-  TestingProfile* profile2 =
-      CreateMultiUserProfile("user2@example.com", GaiaId("fakegaia2"));
-  const AccountId account_id(
-      multi_user_util::GetAccountIdFromProfile(profile()));
-  const AccountId account_id2(
-      multi_user_util::GetAccountIdFromProfile(profile2));
-  // Check that there is a browser, back button and an app.
   EXPECT_EQ(1, model_->item_count());
 
-  // Switch to an inactive user.
-  SwitchActiveUserByAccountId(account_id2);
+  // Switch to user1.
+  SwitchActiveUserByAccountId(account_id1());
   EXPECT_EQ(1, model_->item_count());
 
-  // Add the v2 app to the inactive user and check that no item was added to
-  // the shelf.
+  // Add the v2 app to the inactive user0 and check that no item gets added to
+  // the shelf now.
   {
     AddExtension(extension1_.get());
     V2App v2_app(profile(), extension1_.get());
     EXPECT_EQ(1, model_->item_count());
 
     // Switch to the primary user and check that the item is shown.
-    SwitchActiveUserByAccountId(account_id);
+    SwitchActiveUserByAccountId(account_id());
     EXPECT_EQ(2, model_->item_count());
 
     // Switch to the second user and check that the item goes away - even if the
     // item gets closed.
-    SwitchActiveUserByAccountId(account_id2);
+    SwitchActiveUserByAccountId(account_id1());
     EXPECT_EQ(1, model_->item_count());
   }
 
@@ -3959,7 +3893,7 @@
 
   // Switching then back to the default user should not show the additional
   // item anymore.
-  SwitchActiveUserByAccountId(account_id);
+  SwitchActiveUserByAccountId(account_id());
   EXPECT_EQ(1, model_->item_count());
 }
 
@@ -4027,17 +3961,18 @@
 
   // Create and add three users / profiles, and go to #1's desktop.
   TestingProfile* profile1 =
-      CreateMultiUserProfile("user-1@example.com", GaiaId("fakegaia1"));
+      LogInSecondaryUser("user-1@example.com", GaiaId("fakegaia-1"));
   TestingProfile* profile2 =
-      CreateMultiUserProfile("user-2@example.com", GaiaId("fakegaia2"));
+      LogInSecondaryUser("user-2@example.com", GaiaId("fakegaia-2"));
   TestingProfile* profile3 =
-      CreateMultiUserProfile("user-3@example.com", GaiaId("fakegaia3"));
+      LogInSecondaryUser("user-3@example.com", GaiaId("fakegaia-3"));
   const AccountId account_id1(
       multi_user_util::GetAccountIdFromProfile(profile1));
   const AccountId account_id2(
       multi_user_util::GetAccountIdFromProfile(profile2));
   const AccountId account_id3(
       multi_user_util::GetAccountIdFromProfile(profile3));
+  SwitchActiveUserByAccountId(account_id1);
 
   extensions::TestExtensionSystem* extension_system1(
       static_cast<extensions::TestExtensionSystem*>(
@@ -4047,8 +3982,6 @@
           base::CommandLine::ForCurrentProcess(), base::FilePath(), false);
   extension_service1->Init();
 
-  SwitchActiveUserByAccountId(account_id1);
-
   // A v2 app for user #1 should be shown first and get hidden when switching
   // to desktop #2.
   extensions::ExtensionRegistrar::Get(profile1)->AddExtension(extension1_);
@@ -4109,17 +4042,11 @@
   InitShelfController();
 
   TestingProfile* profile2 =
-      CreateMultiUserProfile("user-2@example.com", GaiaId("fakegaia2"));
+      LogInSecondaryUser("user-2@example.com", GaiaId("fakegaia2"));
   const AccountId account_id2(
       multi_user_util::GetAccountIdFromProfile(profile2));
-  // If switch to account_id2 is not run, the following switch to account_id
-  // is invalid, because the user account is not changed, so switch to
-  // account_id2 first.
-  SwitchActiveUserByAccountId(account_id2);
 
-  const AccountId account_id(
-      multi_user_util::GetAccountIdFromProfile(profile()));
-  SwitchActiveUserByAccountId(account_id);
+  SwitchActiveUserByAccountId(account_id());
   EXPECT_EQ(1, model_->item_count());
 
   AddExtension(extension1_.get());
@@ -4144,7 +4071,7 @@
     v2_app_1.window()->Show(extensions::AppWindow::SHOW_ACTIVE);
     EXPECT_EQ(1, model_->item_count());
 
-    SwitchActiveUserByAccountId(account_id);
+    SwitchActiveUserByAccountId(account_id());
     EXPECT_EQ(2, model_->item_count());
   }
   {
@@ -4155,12 +4082,8 @@
     v2_app_1.window()->Hide();
     EXPECT_EQ(1, model_->item_count());
 
-    SwitchActiveUserByAccountId(account_id);
-    // The following expectation does not work in current impl. It was working
-    // before because MultiProfileSupport is not attached to user associated
-    // with profile() hence not actually handling windows for the user. It is
-    // a real bug. See http://crbug.com/693634 EXPECT_EQ(2,
-    // model_->item_count());
+    SwitchActiveUserByAccountId(account_id());
+    EXPECT_EQ(2, model_->item_count());
 
     v2_app_1.window()->Show(extensions::AppWindow::SHOW_ACTIVE);
     EXPECT_EQ(2, model_->item_count());
@@ -4187,17 +4110,8 @@
        SpinnersUpdateOnUserSwitch) {
   InitShelfController();
 
-  const AccountId account_id(
-      multi_user_util::GetAccountIdFromProfile(profile()));
-  constexpr char kUser2[] = "user2@example.com";
-  const GaiaId kFakeGaia2("fakegaia2");
-  const TestingProfile* profile2 = CreateMultiUserProfile(kUser2, kFakeGaia2);
-  const AccountId account_id2(
-      multi_user_util::GetAccountIdFromProfile(profile2));
-
   const std::string app_id = extension1_->id();
   extension_registrar_->AddExtension(extension1_.get());
-
   EXPECT_EQ(1, model_->item_count());
   EXPECT_FALSE(shelf_controller_->GetShelfSpinnerController()->HasApp(app_id));
 
@@ -4207,13 +4121,13 @@
   EXPECT_EQ(2, model_->item_count());
   EXPECT_TRUE(shelf_controller_->GetShelfSpinnerController()->HasApp(app_id));
 
-  // Switch to a new profile
-  SwitchActiveUserByAccountId(account_id2);
+  // Switch to a different profile
+  SwitchActiveUserByAccountId(account_id1());
   EXPECT_EQ(1, model_->item_count());
   EXPECT_FALSE(shelf_controller_->GetShelfSpinnerController()->HasApp(app_id));
 
   // Switch back
-  SwitchActiveUserByAccountId(account_id);
+  SwitchActiveUserByAccountId(account_id());
   EXPECT_EQ(2, model_->item_count());
   EXPECT_TRUE(shelf_controller_->GetShelfSpinnerController()->HasApp(app_id));
 
@@ -4229,17 +4143,8 @@
        PinnedSpinnersUpdateOnUserSwitch) {
   InitShelfController();
 
-  const AccountId account_id(
-      multi_user_util::GetAccountIdFromProfile(profile()));
-  constexpr char kUser2[] = "user2@example.com";
-  const GaiaId kFakeGaia2("fakegaia2");
-  const TestingProfile* profile2 = CreateMultiUserProfile(kUser2, kFakeGaia2);
-  const AccountId account_id2(
-      multi_user_util::GetAccountIdFromProfile(profile2));
-
   const std::string app_id = extension1_->id();
   AddExtension(extension1_.get());
-
   EXPECT_EQ(1, model_->item_count());
   EXPECT_FALSE(shelf_controller_->GetShelfSpinnerController()->HasApp(app_id));
 
@@ -4256,14 +4161,14 @@
   EXPECT_EQ(2, model_->item_count());
   EXPECT_TRUE(shelf_controller_->GetShelfSpinnerController()->HasApp(app_id));
 
-  // Switch to a new profile
-  SwitchActiveUserByAccountId(account_id2);
+  // Switch to a different profile
+  SwitchActiveUserByAccountId(account_id1());
   EXPECT_FALSE(shelf_controller_->IsAppPinned(app_id));
   EXPECT_EQ(1, model_->item_count());
   EXPECT_FALSE(shelf_controller_->GetShelfSpinnerController()->HasApp(app_id));
 
   // Switch back
-  SwitchActiveUserByAccountId(account_id);
+  SwitchActiveUserByAccountId(account_id());
   EXPECT_TRUE(shelf_controller_->IsAppPinned(app_id));
   EXPECT_EQ(2, model_->item_count());
   EXPECT_TRUE(shelf_controller_->GetShelfSpinnerController()->HasApp(app_id));
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views_unittest.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views_unittest.cc
index 945cdc7..eb3e88c 100644
--- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views_unittest.cc
+++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views_unittest.cc
@@ -38,6 +38,7 @@
 #include "chrome/browser/ash/app_list/arc/arc_app_list_prefs.h"
 #include "chrome/browser/ash/app_list/arc/arc_app_test.h"
 #include "chrome/browser/ash/app_list/arc/arc_app_utils.h"
+#include "chrome/browser/ash/browser_delegate/browser_controller_impl.h"
 #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h"
 #include "chrome/browser/ui/ash/shelf/shelf_controller_helper.h"
 #include "chromeos/ash/components/browser_context_helper/annotated_account_id.h"
@@ -106,6 +107,7 @@
     arc_test_->SetUp(extension_environment_.profile());
 
     shelf_model_ = std::make_unique<ash::ShelfModel>();
+    browser_controller_.emplace();
     chrome_shelf_controller_ = std::make_unique<ChromeShelfController>(
         extension_environment_.profile(), shelf_model_.get());
     chrome_shelf_controller_->SetProfileForTest(
@@ -126,6 +128,7 @@
     chrome_app_ = nullptr;
 #if BUILDFLAG(IS_CHROMEOS)
     chrome_shelf_controller_.reset();
+    browser_controller_.reset();
     shelf_model_.reset();
     if (arc_test_) {
       arc_test_->TearDown();
@@ -211,6 +214,7 @@
   };
 #if BUILDFLAG(IS_CHROMEOS)
   std::unique_ptr<ash::ShelfModel> shelf_model_;
+  std::optional<ash::BrowserControllerImpl> browser_controller_;
   std::unique_ptr<ChromeShelfController> chrome_shelf_controller_;
   std::unique_ptr<ArcAppTest> arc_test_;
 #endif
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_browsertest.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_browsertest.cc
index b25d328..d40e7c8d 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_browsertest.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_browsertest.cc
@@ -453,7 +453,6 @@
 
 // Following definitions are equal to content::PrerenderFinalStatus.
 constexpr int kFinalStatusActivated = 0;
-constexpr int kFinalStatusTriggerDestroyed = 16;
 
 constexpr int kPreloadingTriggeringOutcomeSuccess = 5;
 
@@ -623,247 +622,7 @@
   }
 }
 
-class PrerenderBookmarkBarOnHoverNavigationTest
-    : public PrerenderBookmarkBarNavigationTestBase {
- public:
-  PrerenderBookmarkBarOnHoverNavigationTest() {
-    // Mousedown prerender trigger is disabled explicitly and onHover delay is
-    // set to 0ms for testing.
-    scoped_feature_list_.InitWithFeaturesAndParameters(
-        {
-            {features::kBookmarkTriggerForPrerender2,
-             {{"preconnect_start_delay_on_mouse_hover_ms", "0"},
-              {"prerender_start_delay_on_mouse_hover_ms", "0"},
-              {"prerender_bookmarkbar_on_mouse_pressed_trigger", "false"},
-              {"prerender_bookmarkbar_on_mouse_hover_trigger", "true"}}},
-        },
-        /*disabled_features=*/{});
-  }
-
-  const content::test::PreloadingAttemptUkmEntryBuilder& ukm_entry_builder() {
-    return *ukm_entry_builder_;
-  }
-
-  void SetUpOnMainThread() override {
-    PrerenderBookmarkBarNavigationTestBase::SetUpOnMainThread();
-    ukm_entry_builder_ =
-        std::make_unique<content::test::PreloadingAttemptUkmEntryBuilder>(
-            chrome_preloading_predictor::kMouseHoverOrMouseDownOnBookmarkBar);
-  }
-
-  void TriggerPrerenderByMouseHoverOnBookmark(bool expect_completion) {
-    views::LabelButton* button = GetBookmarkButton(0);
-
-    gfx::Point center(10, 10);
-    button->OnMouseEntered(ui::MouseEvent(
-        ui::EventType::kMouseEntered, center, center, ui::EventTimeForNow(),
-        /*flags=*/ui::EF_NONE,
-        /*changed_button_flags=*/ui::EF_NONE));
-
-    if (expect_completion) {
-      content::test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
-          *GetActiveWebContents(),
-          https_test_server()->GetURL("/empty.html?prerender"));
-    } else {
-      base::RunLoop().RunUntilIdle();
-    }
-  }
-
-  void StopPrerenderingByMouseExited() {
-    views::LabelButton* button = GetBookmarkButton(0);
-
-    gfx::Point center(10, 10);
-    button->OnMouseExited(ui::MouseEvent(ui::EventType::kMouseExited, center,
-                                         center, ui::EventTimeForNow(),
-                                         /*flags=*/ui::EF_NONE,
-                                         /*changed_button_flags=*/ui::EF_NONE));
-  }
-
- private:
-  base::test::ScopedFeatureList scoped_feature_list_;
-  std::unique_ptr<content::test::PreloadingAttemptUkmEntryBuilder>
-      ukm_entry_builder_;
-};
-
-IN_PROC_BROWSER_TEST_F(PrerenderBookmarkBarOnHoverNavigationTest,
-                       PrerenderActivation) {
-  base::HistogramTester histogram_tester;
-  // Navigate to an non-empty tab
-  ASSERT_TRUE(ui_test_utils::NavigateToURL(
-      browser(), https_test_server()->GetURL("/empty.html")));
-  GURL prerender_url = https_test_server()->GetURL("/empty.html?prerender");
-
-  content::NavigationHandleObserver activation_observer(GetActiveWebContents(),
-                                                        prerender_url);
-
-  CreateBookmarkButton(prerender_url);
-  NavigateToBookmarkByMousePressed(prerender_url, true);
-  EXPECT_EQ(GetActiveWebContents()->GetLastCommittedURL(),
-            https_test_server()->GetURL("/empty.html?prerender"));
-
-  {
-    ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
-    // Navigate away to flush the metrics and check.
-    ASSERT_TRUE(
-        ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-    auto ukm_entries = test_ukm_recorder()->GetEntries(
-        Preloading_Attempt::kEntryName,
-        content::test::kPreloadingAttemptUkmMetrics);
-    EXPECT_EQ(ukm_entries.size(), 1u);
-
-    std::vector<UkmEntry> expected_entries = {
-        ukm_entry_builder().BuildEntry(
-            ukm_source_id, content::PreloadingType::kPrerender,
-            content::PreloadingEligibility::kEligible,
-            content::PreloadingHoldbackStatus::kAllowed,
-            content::PreloadingTriggeringOutcome::kSuccess,
-            content::PreloadingFailureReason::kUnspecified,
-            /*accurate=*/true,
-            /*ready_time=*/kMockElapsedTime),
-    };
-    EXPECT_THAT(ukm_entries,
-                testing::UnorderedElementsAreArray(expected_entries))
-        << content::test::ActualVsExpectedUkmEntriesToString(ukm_entries,
-                                                             expected_entries);
-  }
-
-  histogram_tester.ExpectUniqueSample(
-      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_BookmarkBar",
-      kFinalStatusActivated, 1);
-  histogram_tester.ExpectUniqueSample(
-      "Preloading.Prerender.Attempt.MouseHoverOrMouseDownOnBookmarkBar."
-      "TriggeringOutcome",
-      kPreloadingTriggeringOutcomeSuccess, 1);
-  ASSERT_EQ(bookmark_navigation_list().size(), 2u);
-  for (int i = 0; i < 2; ++i) {
-    EXPECT_EQ(bookmark_navigation_list()[i],
-              page_load_metrics::NavigationHandleUserData::InitiatorLocation::
-                  kBookmarkBar);
-  }
-  histogram_tester.ExpectTotalCount(
-      "Bookmarks.BookmarkBar.PrerenderNavigationToActivation", 1);
-}
-
-IN_PROC_BROWSER_TEST_F(PrerenderBookmarkBarOnHoverNavigationTest,
-                       DestroyedOnNavigatedAway) {
-  base::HistogramTester histogram_tester;
-
-  // Navigate to an initial page.
-  ASSERT_TRUE(ui_test_utils::NavigateToURL(
-      browser(), https_test_server()->GetURL("/empty.html")));
-
-  GURL prerender_url = https_test_server()->GetURL("/simple.html?prerender");
-
-  BookmarkBarPreloadPipelineManager::CreateForWebContents(
-      GetActiveWebContents());
-  auto* bookmarkbar_preload_manager =
-      BookmarkBarPreloadPipelineManager::FromWebContents(
-          GetActiveWebContents());
-
-  bookmarkbar_preload_manager->StartPrerender(prerender_url);
-  content::test::PrerenderTestHelper::WaitForPrerenderLoadCompletion(
-      *GetActiveWebContents(), prerender_url);
-  content::FrameTreeNodeId host_id =
-      prerender_helper().GetHostForUrl(prerender_url);
-  ASSERT_TRUE(host_id);
-
-  // Navigate to a different page. This should cancel prerendering.
-  content::test::PrerenderHostObserver prerender_observer(
-      *GetActiveWebContents(), host_id);
-  ASSERT_TRUE(ui_test_utils::NavigateToURL(
-      browser(), https_test_server()->GetURL("/simple.html?different")));
-  prerender_observer.WaitForDestroyed();
-
-  histogram_tester.ExpectUniqueSample(
-      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_BookmarkBar",
-      kFinalStatusTriggerDestroyed, 1);
-}
-
-// TODO(crbug.com/40285326): This fails with the field trial testing config.
-class PrerenderBookmarkBarOnHoverNavigationTestNoTestingConfig
-    : public PrerenderBookmarkBarOnHoverNavigationTest {
- public:
-  void SetUpCommandLine(base::CommandLine* command_line) override {
-    PrerenderBookmarkBarOnHoverNavigationTest::SetUpCommandLine(command_line);
-    command_line->AppendSwitch("disable-field-trial-config");
-  }
-};
-
-// This test verifies prerender cancellation triggered by mouseExited, and
-// another prerender can trigger normally after that.
-// TODO(crbug.com/40935967): Test times out.
-IN_PROC_BROWSER_TEST_F(
-    PrerenderBookmarkBarOnHoverNavigationTestNoTestingConfig,
-    DISABLED_PrerenderMouseExitedCancellationAndPrerenderActivation) {
-  base::HistogramTester histogram_tester;
-  // Navigate to an non-empty tab
-  ASSERT_TRUE(ui_test_utils::NavigateToURL(
-      browser(), https_test_server()->GetURL("/empty.html")));
-  GURL prerender_url = https_test_server()->GetURL("/empty.html?prerender");
-
-  content::NavigationHandleObserver activation_observer(GetActiveWebContents(),
-                                                        prerender_url);
-
-  CreateBookmarkButton(prerender_url);
-  // Check mouseExited will cancel the mouseHover prerendering.
-  TriggerPrerenderByMouseHoverOnBookmark(true);
-  StopPrerenderingByMouseExited();
-
-  EXPECT_EQ(GetActiveWebContents()->GetLastCommittedURL(),
-            https_test_server()->GetURL("/empty.html"));
-  histogram_tester.ExpectUniqueSample(
-      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_BookmarkBar",
-      kFinalStatusTriggerDestroyed, 1);
-
-  // Prerender can trigger and activate normally after previous cancellation.
-  NavigateToBookmarkByMousePressed(prerender_url, true);
-  EXPECT_EQ(GetActiveWebContents()->GetLastCommittedURL(),
-            https_test_server()->GetURL("/empty.html?prerender"));
-
-  {
-    ukm::SourceId ukm_source_id = activation_observer.next_page_ukm_source_id();
-    // Navigate away to flush the metrics and check.
-    ASSERT_TRUE(
-        ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-    auto ukm_entries = test_ukm_recorder()->GetEntries(
-        Preloading_Attempt::kEntryName,
-        content::test::kPreloadingAttemptUkmMetrics);
-    EXPECT_EQ(ukm_entries.size(), 2u);
-
-    std::vector<UkmEntry> expected_entries = {
-        ukm_entry_builder().BuildEntry(
-            ukm_source_id, content::PreloadingType::kPrerender,
-            content::PreloadingEligibility::kEligible,
-            content::PreloadingHoldbackStatus::kAllowed,
-            content::PreloadingTriggeringOutcome::kReady,
-            content::PreloadingFailureReason::kUnspecified,
-            /*accurate=*/true,
-            /*ready_time=*/kMockElapsedTime),
-        ukm_entry_builder().BuildEntry(
-            ukm_source_id, content::PreloadingType::kPrerender,
-            content::PreloadingEligibility::kEligible,
-            content::PreloadingHoldbackStatus::kAllowed,
-            content::PreloadingTriggeringOutcome::kSuccess,
-            content::PreloadingFailureReason::kUnspecified,
-            /*accurate=*/true,
-            /*ready_time=*/kMockElapsedTime),
-    };
-    EXPECT_THAT(ukm_entries,
-                testing::UnorderedElementsAreArray(expected_entries))
-        << content::test::ActualVsExpectedUkmEntriesToString(ukm_entries,
-                                                             expected_entries);
-  }
-
-  histogram_tester.ExpectBucketCount(
-      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_BookmarkBar",
-      kFinalStatusActivated, 1);
-  histogram_tester.ExpectBucketCount(
-      "Preloading.Prerender.Attempt.MouseHoverOrMouseDownOnBookmarkBar."
-      "TriggeringOutcome",
-      kPreloadingTriggeringOutcomeSuccess, 1);
-}
-
-IN_PROC_BROWSER_TEST_F(PrerenderBookmarkBarOnHoverNavigationTest,
+IN_PROC_BROWSER_TEST_F(PrerenderBookmarkBarOnPressedNavigationTest,
                        SetIsNavigationInDomainCallback) {
   base::HistogramTester histogram_tester;
   // Navigate to an non-empty tab
@@ -908,45 +667,6 @@
       /*content::PredictorConfusionMatrix::kFalseNegative*/ 3, 1);
 }
 
-IN_PROC_BROWSER_TEST_F(PrerenderBookmarkBarOnHoverNavigationTest,
-                       PrerenderNonHttps) {
-  base::HistogramTester histogram_tester;
-  // Navigate to an non-empty tab
-  ASSERT_TRUE(ui_test_utils::NavigateToURL(
-      browser(), https_test_server()->GetURL("/empty.html")));
-  GURL prerender_url = http_test_server()->GetURL("/empty.html?prerender");
-
-  content::NavigationHandleObserver activation_observer(GetActiveWebContents(),
-                                                        prerender_url);
-
-  CreateBookmarkButton(prerender_url);
-  // Check mouseExited will cancel the mouseHover prerendering.
-  TriggerPrerenderByMouseHoverOnBookmark(false);
-
-  {
-    // Navigate away to flush the metrics and check.
-    ASSERT_TRUE(
-        ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
-    ukm::SourceId ukm_source_id =
-        GetActiveWebContents()->GetPrimaryMainFrame()->GetPageUkmSourceId();
-    auto attempt_ukm_entries = test_ukm_recorder()->GetEntries(
-        Preloading_Attempt::kEntryName,
-        content::test::kPreloadingAttemptUkmMetrics);
-    EXPECT_EQ(attempt_ukm_entries.size(), 1u);
-
-    UkmEntry expected_entry = ukm_entry_builder().BuildEntry(
-        ukm_source_id, content::PreloadingType::kPrerender,
-        content::PreloadingEligibility::kHttpsOnly,
-        content::PreloadingHoldbackStatus::kUnspecified,
-        content::PreloadingTriggeringOutcome::kUnspecified,
-        content::PreloadingFailureReason::kUnspecified,
-        /*accurate=*/false);
-    EXPECT_EQ(attempt_ukm_entries[0], expected_entry)
-        << content::test::ActualVsExpectedUkmEntryToString(
-               attempt_ukm_entries[0], expected_entry);
-  }
-}
-
 class PrerenderBookmarkBarDisabledNavigationTest
     : public PrerenderBookmarkBarNavigationTestBase {
  public:
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_button.cc b/chrome/browser/ui/views/bookmarks/bookmark_button.cc
index f27b449..617cd930 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_button.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_button.cc
@@ -40,19 +40,8 @@
 
 // These are used as control the behavior of kBookmarkTriggerForPrerender2.
 const base::FeatureParam<int> kPreconnectStartDelayOnMouseHoverByMiliseconds{
-    &features::kBookmarkTriggerForPrerender2,
+    &features::kBookmarkTriggerForPreconnect,
     "preconnect_start_delay_on_mouse_hover_ms", 100};
-const base::FeatureParam<int> kPrerenderStartDelayOnMouseHoverByMiliseconds{
-    &features::kBookmarkTriggerForPrerender2,
-    "prerender_start_delay_on_mouse_hover_ms", 300};
-const base::FeatureParam<bool> kPrerenderBookmarkBarOnMousePressedTrigger{
-    &features::kBookmarkTriggerForPrerender2,
-    "prerender_bookmarkbar_on_mouse_pressed_trigger", true};
-// The hover trigger is not enabled as we are aware that this negatively
-// affects other navigations like Omnibox search.
-const base::FeatureParam<bool> kPrerenderBookmarkBarOnMouseHoverTrigger{
-    &features::kBookmarkTriggerForPrerender2,
-    "prerender_bookmarkbar_on_mouse_hover_trigger", false};
 
 // BookmarkButtonBase -----------------------------------------------
 
@@ -175,14 +164,17 @@
 
   BookmarkButtonBase::OnMouseEntered(event);
 
-  if (base::FeatureList::IsEnabled(features::kBookmarkTriggerForPrerender2) &&
-      kPrerenderBookmarkBarOnMouseHoverTrigger.Get()) {
+  if (base::FeatureList::IsEnabled(features::kBookmarkTriggerForPreconnect)) {
     preloading_timer_.Start(
         FROM_HERE,
         base::Milliseconds(
             kPreconnectStartDelayOnMouseHoverByMiliseconds.Get()),
         base::BindRepeating(&BookmarkButton::StartPreconnecting,
                             base::Unretained(this), *url_));
+  }
+
+  if (base::FeatureList::IsEnabled(features::kBookmarkTriggerForPreconnect) ||
+      base::FeatureList::IsEnabled(features::kBookmarkTriggerForPrerender2)) {
     // Now we should register the callback function that will be used to
     // compute the preloading recall.
     if (auto* web_contents =
@@ -220,8 +212,7 @@
                                   PreloadBookmarkMetricsEvent::kMouseDown);
   }
   if (event.IsOnlyLeftMouseButton() &&
-      base::FeatureList::IsEnabled(features::kBookmarkTriggerForPrerender2) &&
-      kPrerenderBookmarkBarOnMousePressedTrigger.Get()) {
+      base::FeatureList::IsEnabled(features::kBookmarkTriggerForPrerender2)) {
     StartPrerendering(*url_);
   }
   return result;
@@ -237,33 +228,20 @@
 }
 
 void BookmarkButton::StartPreconnecting(GURL url) {
-  CHECK(base::FeatureList::IsEnabled(features::kBookmarkTriggerForPrerender2));
+  // TODO(crbug.com/413259638): Introduce preconnect related tests once the
+  // related infrastructure is completed.
+  CHECK(base::FeatureList::IsEnabled(features::kBookmarkTriggerForPreconnect));
   if (bookmarkbar_preload_manager_ &&
       bookmarkbar_preload_manager_->IsPreloadingStarted()) {
     return;
   }
 
-  // Directly start prerendering to avoid timer overhead.
-  if (kPrerenderStartDelayOnMouseHoverByMiliseconds.Get() -
-          kPreconnectStartDelayOnMouseHoverByMiliseconds.Get() <=
-      0) {
-    StartPrerendering(url);
-  } else {
-    auto* loading_predictor =
-        predictors::LoadingPredictorFactory::GetForProfile(browser_->profile());
-    if (loading_predictor) {
-      loading_predictor->PrepareForPageLoad(
-          /*initiator_origin=*/std::nullopt, url,
-          predictors::HintOrigin::BOOKMARK_BAR, true);
-    }
-
-    preloading_timer_.Start(
-        FROM_HERE,
-        base::Milliseconds(
-            kPrerenderStartDelayOnMouseHoverByMiliseconds.Get() -
-            kPreconnectStartDelayOnMouseHoverByMiliseconds.Get()),
-        base::BindRepeating(&BookmarkButton::StartPrerendering,
-                            base::Unretained(this), url));
+  auto* loading_predictor =
+      predictors::LoadingPredictorFactory::GetForProfile(browser_->profile());
+  if (loading_predictor) {
+    loading_predictor->PrepareForPageLoad(
+        /*initiator_origin=*/std::nullopt, url,
+        predictors::HintOrigin::BOOKMARK_BAR, true);
   }
 }
 
diff --git a/chrome/browser/ui/views/permissions/chip/chip_controller.cc b/chrome/browser/ui/views/permissions/chip/chip_controller.cc
index b7d62d7b..3bbfaf93 100644
--- a/chrome/browser/ui/views/permissions/chip/chip_controller.cc
+++ b/chrome/browser/ui/views/permissions/chip/chip_controller.cc
@@ -439,7 +439,7 @@
            (active_chip_permission_request_manager_.value()
                 ->web_contents()
                 ->GetVisibleURL() != GURL(chrome::kChromeUINewTabURL)))) {
-        active_chip_permission_request_manager_.value()->RecreateView();
+        active_chip_permission_request_manager_.value()->Ignore();
       }
       active_chip_permission_request_manager_.reset();
     }
diff --git a/chrome/browser/ui/views/permissions/chip/permission_chip_interactive_uitest.cc b/chrome/browser/ui/views/permissions/chip/permission_chip_interactive_uitest.cc
index 1143b28..4ffd16e 100644
--- a/chrome/browser/ui/views/permissions/chip/permission_chip_interactive_uitest.cc
+++ b/chrome/browser/ui/views/permissions/chip/permission_chip_interactive_uitest.cc
@@ -21,6 +21,7 @@
 #include "chrome/browser/ui/test/test_browser_dialog.h"
 #include "chrome/browser/ui/views/content_setting_bubble_contents.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/omnibox/omnibox_view_views.h"
 #include "chrome/browser/ui/views/page_info/page_info_bubble_view.h"
 #include "chrome/browser/ui/views/page_info/page_info_view_factory.h"
 #include "chrome/browser/ui/views/permissions/chip/chip_controller.h"
@@ -403,6 +404,31 @@
   ASSERT_FALSE(GetChip()->GetVisible());
 }
 
+IN_PROC_BROWSER_TEST_F(ConfirmationChipEnabledInteractiveTest,
+                       HideChipWhenOmniboxIsEdited) {
+  RequestPermission(permissions::RequestType::kGeolocation);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_TRUE(GetChip()->GetVisible());
+  EXPECT_TRUE(GetChip()->GetText() ==
+              l10n_util::GetStringUTF16(IDS_GEOLOCATION_PERMISSION_CHIP));
+
+  test_api_->manager()->Accept();
+  EXPECT_TRUE(GetChip()->GetVisible());
+  EXPECT_TRUE(GetChip()->GetText() ==
+              l10n_util::GetStringUTF16(
+                  IDS_PERMISSIONS_PERMISSION_ALLOWED_CONFIRMATION));
+  EXPECT_EQ(GetChip()->theme(), PermissionChipTheme::kNormalVisibility);
+
+  // Simulate the user editing the omnibox.
+  OmniboxView* omnibox_view = GetLocationBarView()->GetOmniboxView();
+  omnibox_view->SetFocus(/*is_user_initiated=*/true);
+  omnibox_view->SetUserText(u"Typing in the Omnibox...");
+  views::test::RunScheduledLayout(GetLocationBarView());
+  EXPECT_TRUE(GetLocationBarView()->IsEditingOrEmpty());
+  EXPECT_FALSE(GetChip()->GetVisible());
+}
+
+
 class PageInfoChangedWithin1mUmaTest : public PermissionChipInteractiveUITest {
  public:
   PageInfoChangedWithin1mUmaTest() = default;
@@ -1544,6 +1570,23 @@
   permission_prompt_waiter->WaitForHide();
 }
 
+IN_PROC_BROWSER_TEST_F(PermissionChipInteractiveUITest,
+                       IgnoreRequestWhenOmniboxIsEdited) {
+  RequestPermission(permissions::RequestType::kGeolocation);
+  EXPECT_TRUE(GetChip()->GetVisible());
+  EXPECT_TRUE(test_api_->manager()->IsRequestInProgress());
+
+  // Simulate the user editing the omnibox.
+  OmniboxView* omnibox_view = GetLocationBarView()->GetOmniboxView();
+  omnibox_view->SetFocus(/*is_user_initiated=*/true);
+  omnibox_view->SetUserText(u"Typing in the Omnibox...");
+  views::test::RunScheduledLayout(GetLocationBarView());
+  ASSERT_TRUE(GetLocationBarView()->IsEditingOrEmpty());
+
+  EXPECT_FALSE(test_api_->manager()->IsRequestInProgress());
+  EXPECT_FALSE(GetChip()->GetVisible());
+}
+
 class TestWebContentsObserver : content::WebContentsObserver {
  public:
   explicit TestWebContentsObserver(content::WebContents* web_contents)
diff --git a/chrome/browser/ui/webui_browser/BUILD.gn b/chrome/browser/ui/webui_browser/BUILD.gn
index 280f71c..82bac89 100644
--- a/chrome/browser/ui/webui_browser/BUILD.gn
+++ b/chrome/browser/ui/webui_browser/BUILD.gn
@@ -18,6 +18,7 @@
   deps = [
     ":webui_browser",
     "//base",
+    "//chrome/common:chrome_features",
     "//components/input",
     "//components/sharing_message",
     "//content/public/browser",
diff --git a/chrome/browser/ui/webui_browser/webui_browser.cc b/chrome/browser/ui/webui_browser/webui_browser.cc
index 8e03fd9..07f4ae8 100644
--- a/chrome/browser/ui/webui_browser/webui_browser.cc
+++ b/chrome/browser/ui/webui_browser/webui_browser.cc
@@ -4,10 +4,13 @@
 
 #include "chrome/browser/ui/webui_browser/webui_browser.h"
 
+#include "base/feature_list.h"
+#include "chrome/common/chrome_features.h"
+
 namespace webui_browser {
 
 bool IsWebUIBrowserEnabled() {
-  return false;
+  return base::FeatureList::IsEnabled(features::kWebium);
 }
 
 }  // namespace webui_browser
diff --git a/chrome/browser/uid/android/BUILD.gn b/chrome/browser/uid/android/BUILD.gn
index 887e4e8a..ef94eee 100644
--- a/chrome/browser/uid/android/BUILD.gn
+++ b/chrome/browser/uid/android/BUILD.gn
@@ -37,7 +37,7 @@
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_test_core_java",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
   ]
 }
diff --git a/chrome/browser/updates/announcement_notification/BUILD.gn b/chrome/browser/updates/announcement_notification/BUILD.gn
index e6ccc53..44d68aa 100644
--- a/chrome/browser/updates/announcement_notification/BUILD.gn
+++ b/chrome/browser/updates/announcement_notification/BUILD.gn
@@ -52,7 +52,7 @@
     "//chrome/browser/profiles:profile",
     "//components/keyed_service/content",
     "//components/pref_registry",
-    "//components/prefs:prefs",
+    "//components/prefs",
     "//skia",
     "//ui/base",
     "//url",
diff --git a/chrome/browser/usb/android/BUILD.gn b/chrome/browser/usb/android/BUILD.gn
index 56c194f..80ecdeaa 100644
--- a/chrome/browser/usb/android/BUILD.gn
+++ b/chrome/browser/usb/android/BUILD.gn
@@ -59,7 +59,7 @@
     "//components/browser_ui/notifications/android:utils_java",
     "//components/url_formatter/android:url_formatter_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//url:gurl_java",
     "//url:gurl_junit_test_support",
diff --git a/chrome/browser/vr/BUILD.gn b/chrome/browser/vr/BUILD.gn
index 85c2902..7085645 100644
--- a/chrome/browser/vr/BUILD.gn
+++ b/chrome/browser/vr/BUILD.gn
@@ -16,7 +16,7 @@
 
 source_set("vr") {
   public = [ "vr_tab_helper.h" ]
-  public_deps = [ "//content/public/browser:browser" ]
+  public_deps = [ "//content/public/browser" ]
 }
 
 source_set("impl") {
@@ -24,13 +24,13 @@
   deps = [
     ":vr",
     "//chrome/browser:browser_public_dependencies",
-    "//chrome/browser/ui:ui",
-    "//device/vr/buildflags:buildflags",
+    "//chrome/browser/ui",
+    "//device/vr/buildflags",
     "//third_party/blink/public/common:headers",
   ]
 
   if (is_android) {
-    deps += [ "//base:base" ]
+    deps += [ "//base" ]
   }
 }
 
@@ -41,7 +41,7 @@
 
   deps = [
     ":vr",
-    "//testing/gtest:gtest",
+    "//testing/gtest",
   ]
 }
 
@@ -133,7 +133,7 @@
       "//components/vector_icons",
       "//device/base",
       "//device/vr:vr_base",
-      "//device/vr/buildflags:buildflags",
+      "//device/vr/buildflags",
       "//media",
       "//net",
       "//skia",
@@ -203,7 +203,7 @@
       "//content/public/browser",
       "//device/base",
       "//device/vr:vr_util",
-      "//device/vr/buildflags:buildflags",
+      "//device/vr/buildflags",
       "//device/vr/public/mojom:isolated_xr_service",
       "//media",
       "//net",
@@ -465,9 +465,9 @@
         ":vr_common",
         "//chrome/common:constants",
         "//chrome/test:xr_browser_tests_common",
-        "//device/vr:vr",
+        "//device/vr",
         "//device/vr:vr_test_hook",
-        "//device/vr/buildflags:buildflags",
+        "//device/vr/buildflags",
         "//device/vr/orientation",
         "//device/vr/public/mojom:isolated_xr_service",
         "//device/vr/public/mojom:test_mojom",
diff --git a/chrome/browser/wallet/android/BUILD.gn b/chrome/browser/wallet/android/BUILD.gn
index 678dcc9..40ca0f0 100644
--- a/chrome/browser/wallet/android/BUILD.gn
+++ b/chrome/browser/wallet/android/BUILD.gn
@@ -40,7 +40,7 @@
     "//content/public/android:content_java",
     "//third_party/android_deps:guava_android_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//url:url_java",
   ]
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn
index 22ce681..65f76bd6 100644
--- a/chrome/browser/web_applications/BUILD.gn
+++ b/chrome/browser/web_applications/BUILD.gn
@@ -116,8 +116,6 @@
     "isolated_web_apps/commands/isolated_web_app_install_command_helper.h",
     "isolated_web_apps/commands/isolated_web_app_prepare_and_store_update_command.cc",
     "isolated_web_apps/commands/isolated_web_app_prepare_and_store_update_command.h",
-    "isolated_web_apps/isolated_web_app_downloader.cc",
-    "isolated_web_apps/isolated_web_app_downloader.h",
     "isolated_web_apps/isolated_web_app_error_page.cc",
     "isolated_web_apps/isolated_web_app_error_page.h",
     "isolated_web_apps/isolated_web_app_features.cc",
@@ -876,7 +874,6 @@
     "isolated_web_apps/commands/isolated_web_app_apply_update_command_unittest.cc",
     "isolated_web_apps/commands/isolated_web_app_install_command_helper_unittest.cc",
     "isolated_web_apps/commands/isolated_web_app_prepare_and_store_update_command_unittest.cc",
-    "isolated_web_apps/isolated_web_app_downloader_unittest.cc",
     "isolated_web_apps/isolated_web_app_features_unittest.cc",
     "isolated_web_apps/isolated_web_app_install_source_unittest.cc",
     "isolated_web_apps/isolated_web_app_installation_manager_unittest.cc",
diff --git a/chrome/browser/web_applications/extensions/BUILD.gn b/chrome/browser/web_applications/extensions/BUILD.gn
index 2f8ba88..e18df45 100644
--- a/chrome/browser/web_applications/extensions/BUILD.gn
+++ b/chrome/browser/web_applications/extensions/BUILD.gn
@@ -36,7 +36,7 @@
     "//components/pref_registry",
     "//components/services/app_service",
     "//components/sync/model",
-    "//components/webapps/browser:browser",
+    "//components/webapps/browser",
     "//components/webapps/common",
     "//content/public/browser",
     "//extensions/browser",
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_browsertest.cc b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_browsertest.cc
index 94637482..6171902 100644
--- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_browsertest.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_browsertest.cc
@@ -15,6 +15,7 @@
 #include "base/strings/string_util.h"
 #include "base/test/gmock_expected_support.h"
 #include "base/test/metrics/histogram_tester.h"
+#include "base/test/run_until.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/test_future.h"
 #include "base/threading/thread_restrictions.h"
@@ -1024,7 +1025,8 @@
 class IsolatedWebAppBrowserServiceWorkerTest
     : public IsolatedWebAppBrowserTest {
  protected:
-  int64_t InstallIsolatedWebAppAndWaitForServiceWorker() {
+  int64_t InstallIsolatedWebAppAndWaitForServiceWorker(
+      const std::string& service_worker_path) {
     std::unique_ptr<ScopedBundledIsolatedWebApp> app =
         IsolatedWebAppBuilder(ManifestBuilder())
             .AddHtml("/register_service_worker.html", "ABA")
@@ -1034,8 +1036,7 @@
             .AddFileFromDisk(
                 "/register_service_worker.js",
                 "web_apps/simple_isolated_app/register_service_worker.js")
-            .AddFileFromDisk("/service_worker.js",
-                             "web_apps/simple_isolated_app/service_worker.js")
+            .AddFileFromDisk("/service_worker.js", service_worker_path)
             .BuildBundle();
     app->TrustSigningKey();
     IsolatedWebAppUrlInfo url_info = app->InstallChecked(profile());
@@ -1077,12 +1078,22 @@
 
 IN_PROC_BROWSER_TEST_F(IsolatedWebAppBrowserServiceWorkerTest,
                        ServiceWorkerPartitioned) {
-  InstallIsolatedWebAppAndWaitForServiceWorker();
+  InstallIsolatedWebAppAndWaitForServiceWorker(
+      /*service_worker_path=*/"web_apps/simple_isolated_app/service_worker.js");
   test::CheckServiceWorkerStatus(
       app_url(), storage_partition_,
       content::ServiceWorkerCapability::SERVICE_WORKER_WITH_FETCH_HANDLER);
 }
 
+IN_PROC_BROWSER_TEST_F(IsolatedWebAppBrowserServiceWorkerTest, CacheTest) {
+  InstallIsolatedWebAppAndWaitForServiceWorker(
+      /*service_worker_path=*/
+      "web_apps/simple_isolated_app/cached_service_worker.js");
+  test::CheckServiceWorkerStatus(
+      app_url(), storage_partition_,
+      content::ServiceWorkerCapability::SERVICE_WORKER_NO_FETCH_HANDLER);
+}
+
 class IsolatedWebAppBrowserServiceWorkerPushTest
     : public IsolatedWebAppBrowserServiceWorkerTest {
  public:
@@ -1146,7 +1157,9 @@
     IsolatedWebAppBrowserServiceWorkerPushTest,
     ServiceWorkerPartitionedWhenWakingUpDueToPushNotification) {
   int64_t service_worker_version_id =
-      InstallIsolatedWebAppAndWaitForServiceWorker();
+      InstallIsolatedWebAppAndWaitForServiceWorker(
+          /*service_worker_path=*/
+          "web_apps/simple_isolated_app/service_worker.js");
 
   // Request and confirm permission to show notifications.
   auto* permission_request_manager =
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_installation_manager.cc b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_installation_manager.cc
index d4b7b8ae..5220f4e 100644
--- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_installation_manager.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_installation_manager.cc
@@ -28,7 +28,6 @@
 #include "chrome/browser/web_applications/extensions_manager.h"
 #include "chrome/browser/web_applications/isolated_web_apps/commands/garbage_collect_storage_partitions_command.h"
 #include "chrome/browser/web_applications/isolated_web_apps/commands/install_isolated_web_app_command.h"
-#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader.h"
 #include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_features.h"
 #include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_install_source.h"
 #include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h"
@@ -42,6 +41,7 @@
 #include "components/keep_alive_registry/keep_alive_types.h"
 #include "components/prefs/pref_service.h"
 #include "components/web_package/signed_web_bundles/signed_web_bundle_id.h"
+#include "components/webapps/isolated_web_apps/download/bundle_downloader.h"
 #include "components/webapps/isolated_web_apps/types/source.h"
 #include "content/public/browser/browser_thread.h"
 #include "services/network/public/cpp/is_potentially_trustworthy.h"
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_installation_manager.h b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_installation_manager.h
index 8e1dfa1d4..ad49f34 100644
--- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_installation_manager.h
+++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_installation_manager.h
@@ -17,9 +17,9 @@
 #include "base/one_shot_event.h"
 #include "base/types/expected.h"
 #include "chrome/browser/web_applications/isolated_web_apps/commands/install_isolated_web_app_command.h"
-#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader.h"
 #include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_install_source.h"
 #include "components/keep_alive_registry/scoped_keep_alive.h"
+#include "components/webapps/isolated_web_apps/download/bundle_downloader.h"
 
 namespace base {
 class CommandLine;
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_update_discovery_task.cc b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_update_discovery_task.cc
index 2c7705ae..65701b8 100644
--- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_update_discovery_task.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_update_discovery_task.cc
@@ -32,7 +32,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/web_applications/isolated_web_apps/commands/isolated_web_app_install_command_helper.h"
 #include "chrome/browser/web_applications/isolated_web_apps/commands/isolated_web_app_prepare_and_store_update_command.h"
-#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader.h"
 #include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h"
 #include "chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest.h"
 #include "chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest_fetcher.h"
@@ -42,6 +41,7 @@
 #include "components/keep_alive_registry/keep_alive_registry.h"
 #include "components/keep_alive_registry/keep_alive_types.h"
 #include "components/webapps/common/web_app_id.h"
+#include "components/webapps/isolated_web_apps/download/bundle_downloader.h"
 #include "components/webapps/isolated_web_apps/types/source.h"
 #include "components/webapps/isolated_web_apps/types/update_channel.h"
 #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_update_discovery_task.h b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_update_discovery_task.h
index a49c17a3..5650c72 100644
--- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_update_discovery_task.h
+++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_update_discovery_task.h
@@ -15,11 +15,11 @@
 #include "base/types/expected.h"
 #include "base/version.h"
 #include "chrome/browser/web_applications/isolated_web_apps/commands/isolated_web_app_prepare_and_store_update_command.h"
-#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader.h"
 #include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h"
 #include "chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest.h"
 #include "chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest_fetcher.h"
 #include "components/webapps/common/web_app_id.h"
+#include "components/webapps/isolated_web_apps/download/bundle_downloader.h"
 #include "components/webapps/isolated_web_apps/types/update_channel.h"
 #include "net/base/net_errors.h"
 
diff --git a/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_cache_client.h b/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_cache_client.h
index 573930d..3fa26b6 100644
--- a/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_cache_client.h
+++ b/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_cache_client.h
@@ -13,8 +13,8 @@
 #include "base/path_service.h"
 #include "base/types/expected.h"
 #include "base/version.h"
-#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader.h"
 #include "components/web_package/signed_web_bundles/signed_web_bundle_id.h"
+#include "components/webapps/isolated_web_apps/download/bundle_downloader.h"
 
 namespace web_app {
 
diff --git a/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_installer.cc b/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_installer.cc
index 294867c..9717e4b 100644
--- a/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_installer.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_installer.cc
@@ -14,12 +14,12 @@
 #include "base/version.h"
 #include "chrome/browser/web_applications/callback_utils.h"
 #include "chrome/browser/web_applications/isolated_web_apps/commands/install_isolated_web_app_command.h"
-#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader.h"
 #include "chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_external_install_options.h"
 #include "chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest.h"
 #include "chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest_fetcher.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/common/chrome_features.h"
+#include "components/webapps/isolated_web_apps/download/bundle_downloader.h"
 #include "components/webapps/isolated_web_apps/iwa_key_distribution_info_provider.h"
 #include "components/webapps/isolated_web_apps/types/source.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
diff --git a/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_installer.h b/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_installer.h
index 691d403..6cb2824 100644
--- a/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_installer.h
+++ b/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_installer.h
@@ -13,12 +13,12 @@
 #include "base/memory/raw_ptr.h"
 #include "base/values.h"
 #include "base/version.h"
-#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader.h"
 #include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_install_source.h"
 #include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h"
 #include "chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_external_install_options.h"
 #include "chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest_fetcher.h"
 #include "chrome/browser/web_applications/web_app_command_scheduler.h"
+#include "components/webapps/isolated_web_apps/download/bundle_downloader.h"
 
 #if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/web_applications/isolated_web_apps/commands/copy_bundle_to_cache_command.h"
diff --git a/chrome/browser/web_applications/os_integration/mac/BUILD.gn b/chrome/browser/web_applications/os_integration/mac/BUILD.gn
index a76bf301..d3bb4fa9 100644
--- a/chrome/browser/web_applications/os_integration/mac/BUILD.gn
+++ b/chrome/browser/web_applications/os_integration/mac/BUILD.gn
@@ -11,7 +11,7 @@
 
   deps = [
     "//base",
-    "//chrome/browser/apps/app_shim:app_shim",
+    "//chrome/browser/apps/app_shim",
     "//chrome/browser/web_applications/mojom:web_app_shortcut_copier_mojom",
     "//chrome/common:version_header",
     "//content/public/common:main_function_params",
diff --git a/chrome/browser/webauthn/BUILD.gn b/chrome/browser/webauthn/BUILD.gn
index 8cda3581..bc81676 100644
--- a/chrome/browser/webauthn/BUILD.gn
+++ b/chrome/browser/webauthn/BUILD.gn
@@ -69,14 +69,14 @@
       "//components/sync:test_support",
       "//components/trusted_vault",
       "//components/trusted_vault:test_support",
-      "//components/trusted_vault/proto:proto",
+      "//components/trusted_vault/proto",
       "//components/webauthn/core/browser",
       "//components/webauthn/core/browser:passkey_model",
       "//crypto:test_support",
-      "//device/fido:fido",
+      "//device/fido",
       "//device/fido:test_support",
       "//google_apis",
-      "//net:net",
+      "//net",
       "//testing/gmock",
       "//testing/gtest",
       "//url",
diff --git a/chrome/browser/webid/BUILD.gn b/chrome/browser/webid/BUILD.gn
index a04e1bdc..6b9274d 100644
--- a/chrome/browser/webid/BUILD.gn
+++ b/chrome/browser/webid/BUILD.gn
@@ -47,7 +47,7 @@
       "$google_play_services_package:google_play_services_identity_credentials_java",
       "//base:base_junit_test_support",
       "//content/public/android:content_java",
-      "//third_party/junit:junit",
+      "//third_party/junit",
       "//third_party/mockito:mockito_java",
     ]
   }
diff --git a/chrome/browser/win/installer_downloader/BUILD.gn b/chrome/browser/win/installer_downloader/BUILD.gn
index 06f3999..cc521bf 100644
--- a/chrome/browser/win/installer_downloader/BUILD.gn
+++ b/chrome/browser/win/installer_downloader/BUILD.gn
@@ -137,8 +137,8 @@
     ":prefs",
     "//chrome/browser:browser_process",
     "//chrome/browser:global_features",
+    "//chrome/browser/ui",
     "//chrome/browser/ui:browser_element_identifiers",
-    "//chrome/browser/ui:ui",
     "//chrome/browser/ui/views/infobars",
     "//chrome/test:test_support_ui",
     "//content/test:test_support",
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt
index 3d84b971..e18530a 100644
--- a/chrome/build/android-arm32.pgo.txt
+++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@
-chrome-android32-main-1753725509-296829b5e1f88c249e884e0c3eb03de3662863eb-678e35b06ff74f481a526cc9285c0d94d472eae1.profdata
+chrome-android32-main-1753768535-92ac2a764f8f91dd65aafa15514fe64a3f60b23c-6520cd593d02c2f408281c056adc3338a55ddd6a.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt
index 63b11310..3f223e2 100644
--- a/chrome/build/android-arm64.pgo.txt
+++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@
-chrome-android64-main-1753735281-d8463cc1f387d461310bf89a6515a2ec7d6f4275-056aa4137ec627a6d936f4c8dd5f8f924283a1d0.profdata
+chrome-android64-main-1753773563-52c992c801ad5265603c1ef6fe9523cce939613f-eb4f935510d008d2aff4c2529bf2e31d613c760c.profdata
diff --git a/chrome/build/android-desktop-x64.pgo.txt b/chrome/build/android-desktop-x64.pgo.txt
index 279dd9b..f9a0f3c 100644
--- a/chrome/build/android-desktop-x64.pgo.txt
+++ b/chrome/build/android-desktop-x64.pgo.txt
@@ -1 +1 @@
-chrome-android-desktop-x64-main-1753725509-e71bcaa545a56de548946dc010ce0905fe72ff3e-678e35b06ff74f481a526cc9285c0d94d472eae1.profdata
+chrome-android-desktop-x64-main-1753768535-7a9cabe86d7230909455aa333ba2b5d73eb6a643-6520cd593d02c2f408281c056adc3338a55ddd6a.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index b580836..f6501fab 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1753718100-d9d213ba985fb4b1e29be09058b5977f4cbe8621-a6fbb461fbe3f28e30ffc7fdaac36fd57d27047d.profdata
+chrome-mac-arm-main-1753760156-015c9712aa1880ac30a3976c7b3f848840ab390e-0f943dfb4b6a633b068fa2da607bfb9c6c9ff9de.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 57cbf230..8ab316b 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1753725509-0dd45913ac86e079b9f62f131a6964236c117e0d-678e35b06ff74f481a526cc9285c0d94d472eae1.profdata
+chrome-mac-main-1753768535-fdc8957b5f2ced56315fb252e6df8a318a30c2ae-6520cd593d02c2f408281c056adc3338a55ddd6a.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt
index ef4d1d7..7a162eb 100644
--- a/chrome/build/win-arm64.pgo.txt
+++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@
-chrome-win-arm64-main-1753725509-c5a1dd0506bb5dd15be2379572c3135c62fda59e-678e35b06ff74f481a526cc9285c0d94d472eae1.profdata
+chrome-win-arm64-main-1753768535-374b090ad1f93de889070329e94fc1fa1c2659c0-6520cd593d02c2f408281c056adc3338a55ddd6a.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index dcdce01..6bef7aa 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1753714784-6d800008452c6c246d1b7bb312352792c70c3c8c-ceedd8a3c64d996d6841322a94b09f4968d5999a.profdata
+chrome-win32-main-1753746939-07fd653f8ee96cd237063cd0662b84a8d182cd02-2dbdcd90ae4d18047e13ea1a2c7b8696f39d0642.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 10477e7b..0ed1b97 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1753714784-b13e0f69be83ed71087a61c59e5fc32dbe752475-ceedd8a3c64d996d6841322a94b09f4968d5999a.profdata
+chrome-win64-main-1753746939-24dcb829bf4b3ecd3f3f2475c316f12fe61736ab-2dbdcd90ae4d18047e13ea1a2c7b8696f39d0642.profdata
diff --git a/chrome/common/actor.mojom b/chrome/common/actor.mojom
index 64ad1de..dbf40d03e 100644
--- a/chrome/common/actor.mojom
+++ b/chrome/common/actor.mojom
@@ -351,6 +351,12 @@
   kInstant,
 };
 
+// The track to log the journal entry on.
+enum JournalTrack {
+  kFrontEnd,
+  kActor,
+};
+
 // Represents a journal entry. This should only be used for logging and
 // debugging. It should not be used to make logic decisions since a
 // compromised renderer could lie about events (such as mismatched
@@ -362,9 +368,8 @@
   // The task ID associated with this entry.
   int32 task_id;
 
-  // Unique identifier for entry. Begin/End types
-  // should use the same id.
-  uint64 id;
+  // The track the event should occur on.
+  JournalTrack track;
 
   // The time the event occurred at.
   mojo_base.mojom.Time timestamp;
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index da8fa0e..c0098c3 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -1900,6 +1900,10 @@
              "WebAppManifestPolicyAppIdentityUpdate",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
+#if !BUILDFLAG(IS_ANDROID)
+BASE_FEATURE(kWebium, "Webium", base::FEATURE_DISABLED_BY_DEFAULT);
+#endif  // !BUILDFLAG(IS_ANDROID)
+
 // Restricts the WebUI scripts able to use the generated code cache according to
 // embedder-specified heuristics.
 BASE_FEATURE(kRestrictedWebUICodeCache,
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index 3e2a4cd..19a850f 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -1181,6 +1181,11 @@
 COMPONENT_EXPORT(CHROME_FEATURES)
 BASE_DECLARE_FEATURE(kWebAppManifestPolicyAppIdentityUpdate);
 
+#if !BUILDFLAG(IS_ANDROID)
+COMPONENT_EXPORT(CHROME_FEATURES)
+BASE_DECLARE_FEATURE(kWebium);
+#endif  // !BUILDFLAG(IS_ANDROID)
+
 COMPONENT_EXPORT(CHROME_FEATURES)
 BASE_DECLARE_FEATURE(kRestrictedWebUICodeCache);
 COMPONENT_EXPORT(CHROME_FEATURES)
diff --git a/chrome/renderer/actor/journal.cc b/chrome/renderer/actor/journal.cc
index 63e4b7e..9a32935 100644
--- a/chrome/renderer/actor/journal.cc
+++ b/chrome/renderer/actor/journal.cc
@@ -18,12 +18,10 @@
 Journal::PendingAsyncEntry::PendingAsyncEntry(base::PassKey<Journal> pass_key,
                                               base::SafeRef<Journal> journal,
                                               TaskId task_id,
-                                              uint64_t trace_id,
                                               std::string_view event_name)
     : pass_key_(pass_key),
       journal_(journal),
       task_id_(task_id),
-      trace_id_(trace_id),
       event_name_(event_name) {}
 
 Journal::PendingAsyncEntry::~PendingAsyncEntry() {
@@ -36,7 +34,7 @@
   CHECK(!terminated_);
   terminated_ = true;
   ACTOR_LOG() << "End " << event_name_ << ": " << details;
-  journal_->AddEndEvent(pass_key_, task_id_, trace_id_, event_name_, details);
+  journal_->AddEndEvent(pass_key_, task_id_, event_name_, details);
 }
 
 void Journal::PendingAsyncEntry::Log(std::string_view event_name) {
@@ -48,7 +46,7 @@
   journal_->Log(task_id_, event_name, details);
 }
 
-Journal::Journal() : current_id_(base::RandUint64()) {}
+Journal::Journal() = default;
 Journal::~Journal() {
   if (log_buffer_.size() > 0) {
     SendLogBuffer();
@@ -70,7 +68,7 @@
   }
 
   auto journal_entry = mojom::JournalEntry::New(
-      mojom::JournalEntryType::kInstant, task_id, current_id_++,
+      mojom::JournalEntryType::kInstant, task_id, mojom::JournalTrack::kActor,
       base::Time::Now(), std::string(event), std::string(details));
 
   AddJournalEntry(std::move(journal_entry));
@@ -82,13 +80,12 @@
     std::string_view details) {
   ACTOR_LOG() << "Begin " << event_name << ": " << details;
 
-  uint64_t trace_id = current_id_++;
   AddJournalEntry(mojom::JournalEntry::New(
-      mojom::JournalEntryType::kBegin, task_id, trace_id, base::Time::Now(),
-      std::string(event_name), std::string(details)));
+      mojom::JournalEntryType::kBegin, task_id, mojom::JournalTrack::kActor,
+      base::Time::Now(), std::string(event_name), std::string(details)));
   return base::WrapUnique(new PendingAsyncEntry(base::PassKey<Journal>(),
                                                 weak_factory_.GetSafeRef(),
-                                                task_id, trace_id, event_name));
+                                                task_id, event_name));
 }
 
 void Journal::AddJournalEntry(mojom::JournalEntryPtr journal_entry) {
@@ -111,12 +108,11 @@
 
 void Journal::AddEndEvent(base::PassKey<Journal> pass_key,
                           TaskId task_id,
-                          uint64_t trace_id,
                           const std::string& event_name,
                           std::string_view details) {
-  AddJournalEntry(mojom::JournalEntry::New(mojom::JournalEntryType::kEnd,
-                                           task_id, trace_id, base::Time::Now(),
-                                           event_name, std::string(details)));
+  AddJournalEntry(mojom::JournalEntry::New(
+      mojom::JournalEntryType::kEnd, task_id, mojom::JournalTrack::kActor,
+      base::Time::Now(), event_name, std::string(details)));
 }
 
 void Journal::SendLogBuffer() {
diff --git a/chrome/renderer/actor/journal.h b/chrome/renderer/actor/journal.h
index a4f869a..468368e8 100644
--- a/chrome/renderer/actor/journal.h
+++ b/chrome/renderer/actor/journal.h
@@ -38,7 +38,6 @@
     PendingAsyncEntry(base::PassKey<Journal>,
                       base::SafeRef<Journal> journal,
                       TaskId task_id,
-                      uint64_t trace_id,
                       std::string_view event_name);
     ~PendingAsyncEntry();
 
@@ -56,7 +55,6 @@
     bool terminated_ = false;
     base::SafeRef<Journal> journal_;
     TaskId task_id_;
-    uint64_t trace_id_;
     std::string event_name_;
   };
 
@@ -72,7 +70,6 @@
 
   void AddEndEvent(base::PassKey<Journal>,
                    TaskId task_id,
-                   uint64_t trace_id,
                    const std::string& event_name,
                    std::string_view details);
 
@@ -83,7 +80,6 @@
   mojo::AssociatedRemote<mojom::JournalClient> client_;
   std::vector<mojom::JournalEntryPtr> log_buffer_;
   base::TimeTicks last_log_buffer_send_;
-  uint64_t current_id_;
 
   base::WeakPtrFactory<Journal> weak_factory_{this};
 };
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 6fa7105..ca34ff2 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -7246,7 +7246,6 @@
     "//components/visited_url_ranking/public",
     "//components/visited_url_ranking/public:test_support",
     "//components/webapps/common",
-    "//components/webapps/isolated_web_apps",
     "//components/webauthn/core/browser",
     "//components/webauthn/core/browser:passkey_model",
     "//components/webrtc",
@@ -7764,7 +7763,6 @@
       "../browser/page_image_service/android/image_service_bridge_unittest.cc",
       "../browser/page_load_metrics/observers/android_page_load_metrics_observer_unittest.cc",
       "../browser/partnerbookmarks/partner_bookmarks_shim_unittest.cc",
-      "../browser/password_manager/android/password_ui_view_android_unittest.cc",
       "../browser/performance_manager/policies/process_rank_policy_android_unittest.cc",
       "../browser/policy/browser_dm_token_storage_android_unittest.cc",
       "../browser/policy/chrome_browser_cloud_management_controller_android_unittest.cc",
@@ -8332,6 +8330,7 @@
       "//components/data_sharing:test_support",
       "//components/passage_embeddings",
       "//components/passage_embeddings:test_support",
+      "//components/webapps/isolated_web_apps",
     ]
 
     # TODO(416215722): Remove when # send_tab_to_self_client_service_unittest.cc
@@ -8854,6 +8853,7 @@
       "//chrome/browser/ash/arc/vmm",
       "//chrome/browser/ash/attestation",
       "//chrome/browser/ash/attestation:test_support",
+      "//chrome/browser/ash/browser_delegate:impl",
       "//chrome/browser/ash/cert_provisioning",
       "//chrome/browser/ash/crosapi",
       "//chrome/browser/ash/crosapi:test_support",
diff --git a/chrome/test/base/browser_with_test_window_test.cc b/chrome/test/base/browser_with_test_window_test.cc
index 42c8d191..a5e19a0 100644
--- a/chrome/test/base/browser_with_test_window_test.cc
+++ b/chrome/test/base/browser_with_test_window_test.cc
@@ -76,10 +76,18 @@
     ash::disks::DiskMountManager::InitializeForTesting(
         new ash::disks::FakeDiskMountManager());
   }
+
+  // Construct AshTestHelper here so that SessionManager gets created before
+  // UserManager (as in production).
+  ash_test_helper_.emplace();
+
   if (!user_manager::UserManager::IsInitialized()) {
     user_manager_.Reset(std::make_unique<user_manager::FakeUserManager>(
         g_browser_process->local_state()));
   }
+  session_manager::SessionManager::Get()->OnUserManagerCreated(
+      user_manager::UserManager::Get());
+
   {
     ash::AshTestHelper::InitParams ash_init;
     ash_init.local_state = g_browser_process->local_state();
@@ -89,7 +97,7 @@
     // TestingProfile.
     ash_init.auto_create_prefs_services = false;
 
-    ash_test_helper_.SetUp(std::move(ash_init));
+    ash_test_helper_->SetUp(std::move(ash_init));
   }
 #endif
 
@@ -157,7 +165,7 @@
   user_performance_tuning_manager_environment_.TearDown();
 
 #if BUILDFLAG(IS_CHROMEOS)
-  ash_test_helper_.TearDown();
+  ash_test_helper_->TearDown();
 #endif
 
   // Calling DeleteAllTestingProfiles() first can cause issues in some tests, if
@@ -166,6 +174,10 @@
   profile_manager_.reset();
 
 #if BUILDFLAG(IS_CHROMEOS)
+  // To match production behavior, AshTestHelper (containing e.g.
+  // SessionManager) must be destroyed before UserManager even though it got
+  // created first.
+  ash_test_helper_.reset();
   test_views_delegate_.reset();
   user_manager_.Reset();
   ash::disks::DiskMountManager::Shutdown();
@@ -198,7 +210,7 @@
 
 gfx::NativeWindow BrowserWithTestWindowTest::GetContext() {
 #if BUILDFLAG(IS_CHROMEOS)
-  return ash_test_helper_.GetContext();
+  return ash_test_helper_->GetContext();
 #elif defined(TOOLKIT_VIEWS)
   return views_test_helper_->GetContext();
 #else
@@ -311,8 +323,10 @@
                                       const GaiaId& gaia_id) {
   const AccountId account_id = AccountId::FromUserEmailGaiaId(email, gaia_id);
   user_manager_->AddGaiaUser(account_id, user_manager::UserType::kRegular);
-  user_manager_->UserLoggedIn(
-      account_id, user_manager::TestHelper::GetFakeUsernameHash(account_id));
+  session_manager::SessionManager::Get()->CreateSession(
+      account_id, user_manager::TestHelper::GetFakeUsernameHash(account_id),
+      /*new_user=*/false,
+      /*has_active_session=*/false);
 }
 
 void BrowserWithTestWindowTest::OnUserProfileCreated(const std::string& email,
diff --git a/chrome/test/base/browser_with_test_window_test.h b/chrome/test/base/browser_with_test_window_test.h
index 527a7f9..85fbf7e 100644
--- a/chrome/test/base/browser_with_test_window_test.h
+++ b/chrome/test/base/browser_with_test_window_test.h
@@ -170,7 +170,7 @@
   }
 
 #if BUILDFLAG(IS_CHROMEOS)
-  ash::AshTestHelper* ash_test_helper() { return &ash_test_helper_; }
+  ash::AshTestHelper* ash_test_helper() { return &ash_test_helper_.value(); }
   user_manager::FakeUserManager* user_manager() { return user_manager_.Get(); }
 #endif
 
@@ -304,7 +304,7 @@
   std::unique_ptr<Browser> browser_;
 
 #if BUILDFLAG(IS_CHROMEOS)
-  ash::AshTestHelper ash_test_helper_;
+  std::optional<ash::AshTestHelper> ash_test_helper_;
   std::unique_ptr<views::TestViewsDelegate> test_views_delegate_ =
       std::make_unique<ChromeTestViewsDelegate<ash::AshTestViewsDelegate>>();
 #elif defined(TOOLKIT_VIEWS)
diff --git a/chrome/test/data/chromeos/app_mode/apps_and_extensions/input_extension/elhlgakmbkdkoajdlnfkhjbpgmbpjdig.pem b/chrome/test/data/chromeos/app_mode/apps_and_extensions/input_extension/elhlgakmbkdkoajdlnfkhjbpgmbpjdig.pem
deleted file mode 100644
index 0ea431e..0000000
--- a/chrome/test/data/chromeos/app_mode/apps_and_extensions/input_extension/elhlgakmbkdkoajdlnfkhjbpgmbpjdig.pem
+++ /dev/null
@@ -1,28 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCvfkz/kZMLFvJ5
-4lHJykMujn/JgHjBDXgQg1Ya0D/PUwQWc66nnL9Z1k+fQTJBmzK7l0fMwocandrM
-9SMmAJ11OtEYO/G/nFBaHx7N5jl9WE+3Kna351qIlKT3GpkyGWJ7uBOeRWdD38o4
-dS3QvEaHdOC3v5xOAKDEOKH7iWS0mQa/Qy9NNU5Ck+QK2MBQ4QhrUgyJrIzins8Y
-Ls1b7vqKBarJuaPnBOrCie34ZlnG5SIuPI1DFg6LLDfF7CX7BYhi+OM8sWqsyx/4
-Swee1Yueileiuw66qpPRzgKrv3MGJIKZsAXmB8ytCHHRHU8yt2tCC6BH7kkU7x3t
-eqp8AE6vAgMBAAECggEASuOr+hfmVwIo4Wh6HJGqz7BRyeyAG2ojBXD2iqS5xkCX
-6vjc3HwgkDbLbZuF1cdkA/eP1UpiGzKnz3UA1dPHXeKGnj/ebzVGeN7050rK17ma
-8wA0/0/EK6q7JxP7sgxxIXixLoZRhf53LlabAYuG0YFH8EHdctADyxibz1qXVhWN
-SjhiPhB6pSiqtLb+l2hKLJLQYeHfApswTaBzHeoOzXpQNoVI+Tq9t1yNt7oSWCQt
-8+06vr/kW+SxmoiAfSrw7edeWnE5O6+ut8K3M9zBovt1+nsDf7D63XfDyPLxHWCE
-6k7a+DCWrzeo72AglJYD77GqOqtFM7wmLbqqgOlSqQKBgQDublm+IE2Yz6bISUOn
-09od/AxujApK3xZGykEFyXGkinI5DHnJ/FTIVAjvSKrHd6Z2O5FTaWSmv/d2CRMX
-mr+r1tvxodZxlwuxaXwipHlUt/uShm5d5WbNe3b5N1zWrKpSWKx2PCPlFJnRfxqj
-UFKBQTg25vZz/q9eXdz1wlOnnQKBgQC8bLlAyP7hGyF38GWajtmp+dcF8TzKasQt
-rQTnbseVb/aeIs33WaRYWH79T5NZiWSj35miu6dvpkn4a2N8jWfUbfCelUQwHhQQ
-EeJpDPX2swfrN7uty/grcb/YBw56n+P3IK0aOymjZw3hRjhP65jpQVqAeGpIFYgl
-L5YpRfuruwKBgQDdlE3wZALZFXlQvs2SJU6Z+QfwoFJcXFBOf13IK/phyIv4OoDg
-VpDQD1CyV1zmvGpFjHw1AUgZs2MdHbfRgu3Hm4iRWS56J74lJPvJEgLz2XuBI09k
-EXHlWm0pk+rCUnqCxoeX5bISDYAZcj7mMRpLprnARAobqD9/uklDV1H4/QKBgHsS
-MLYmEoSJqgSjGlonb/hb3ZxeAyzbK6QB3LAlZWswJE8JwKoM/RFPTDK8JSxYV0nK
-JJlsJGMCpFIEIokZ+3V/EakjKdSb8NLGO7IN6yHlsghq8MUF8uS9eWbqxQRHJykl
-SKtXdUzrZN99dA6PfeLs8uXywMiwd6qCOHxg3489AoGAA2xJn33YJamYR+DY3DSy
-HACFee8FoicBN0T+WWZGIo9yxSfqW5qr8oaBQ8xPbaz1k9FA+Dps7mfN1CkxMNNd
-FXqc+bCpNTchvCx05BuT2lYPm6ziVHXiOsRi6cfoP5QU4tTSnGE2apPkqxyRcNSi
-8P7FuZcC2F3CjtqQJvUNGBs=
------END PRIVATE KEY-----
diff --git a/chrome/test/data/chromeos/app_mode/apps_and_extensions/input_extension/src/icon-128.png b/chrome/test/data/chromeos/app_mode/apps_and_extensions/input_extension/src/icon-128.png
deleted file mode 100644
index 5c226f3..0000000
--- a/chrome/test/data/chromeos/app_mode/apps_and_extensions/input_extension/src/icon-128.png
+++ /dev/null
Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/apps_and_extensions/input_extension/src/icon-16.png b/chrome/test/data/chromeos/app_mode/apps_and_extensions/input_extension/src/icon-16.png
deleted file mode 100644
index c7510d38..0000000
--- a/chrome/test/data/chromeos/app_mode/apps_and_extensions/input_extension/src/icon-16.png
+++ /dev/null
Binary files differ
diff --git a/chrome/test/data/chromeos/app_mode/apps_and_extensions/input_extension/src/manifest.json b/chrome/test/data/chromeos/app_mode/apps_and_extensions/input_extension/src/manifest.json
deleted file mode 100644
index 6ba851e..0000000
--- a/chrome/test/data/chromeos/app_mode/apps_and_extensions/input_extension/src/manifest.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "manifest_version": 3,
-  "name": "Kiosk Input API Test Extension",
-  "description": "Companion Extension for KioskEnterpriseInputApiBrowserTest",
-  "version": "1.0",
-  "icons": {
-    "128": "icon-128.png",
-    "16": "icon-16.png"
-  },
-  "permissions": [
-    "enterprise.kioskInput"
-  ],
-  "background": {
-    "service_worker": "service_worker.js"
-  },
-  "externally_connectable": {
-    "matches": [
-      "<all_urls>"
-    ]
-  }
-}
diff --git a/chrome/test/data/chromeos/app_mode/webstore/downloads/elhlgakmbkdkoajdlnfkhjbpgmbpjdig-1.0.0.crx b/chrome/test/data/chromeos/app_mode/webstore/downloads/elhlgakmbkdkoajdlnfkhjbpgmbpjdig-1.0.0.crx
deleted file mode 100644
index dfb9f34..0000000
--- a/chrome/test/data/chromeos/app_mode/webstore/downloads/elhlgakmbkdkoajdlnfkhjbpgmbpjdig-1.0.0.crx
+++ /dev/null
Binary files differ
diff --git a/chrome/test/data/extensions/api_test/enterprise_kiosk_input.pem b/chrome/test/data/extensions/api_test/enterprise_kiosk_input.pem
new file mode 100644
index 0000000..5905702
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/enterprise_kiosk_input.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC6gaLSBi7T3p7J
+wE73/FEavkOzLWDeom/eZhY/dDp+Bh4SdBYytFfwqPyA591GdG+nuYutot0/7Tug
+OQt4MiYo2Jxlx+UAdmQQoGR8BA0kWN2nbhx2I6b/dZXnCjJ1KxOIcQY1j+ESv5B0
+1n9mY95TtRBCsXV+X3NgEHO6Skn0pF52AI8A8/PAxN8H/4r+gPfn96G7iI6GK9Km
+/mP8uBz80R8SJuiHkY/I9b1VmHsjTv9naU+o4tybAsLw8hzw/S1hkHx6JEgFB0CQ
+UCCwPDC3FuUyVfDTM/K7PVZlpkg9bfnTrvcLUzZ6N66y8sl8skRXUDe3ItPGHG6U
+PDU0QM7TAgMBAAECggEAEle8mTZVda3v5Py+Z4JPwbcTtnQQkmTcZr2Yk44NUKau
+X3c+VadJ/NfJ2a20JAFAl/jWJXIem3JsClKB78TS3vKK0zHJMnXyWnZD27SUTE5X
+ImfgcbgI7Rf18b6dfsuJRMKE71CivLLNdMhByGKrE4V7v2tvmEmv8bM8hoZW5rH2
+rqFr1qKCXsVDdNy9jyCaP/9MnZU1L7ENHRFFMdzGrGG7DqXU99vkUTYGiLcHYe8C
+II1iHc37OQp5/eR20LZ5ZEtMYSeNeqUvPsZSYBHyxW+slYJH9yYwUOOprSgUVH3Y
+bhlY3joYGK1kYzubMinffwfvSJ8vJaDtsY3H+/V/+QKBgQDoUGW2Zd1LOkN33Eh0
+73KlxC9ceHyDG9ez+7FCX8Ja4jUTqVLPtYZudiVuRadsjb7I8lPaEnle8gyGhYDV
+MFsqZGA1surqBK+jYejknoG/AZDoS/bjeD0hSZnFu8FXhW2Z/Dkx/630I5pOZ5oy
+wJdwHUxO6jd+gAuKRLUb9le+ewKBgQDNhZ4+QshLkzW2SIXCjsgLnf3TRugb+0nc
+S9g2R+flNUOOXQRUVGwS6/iczMvlskiUXgb+0wmDGbZZUclitrY5Ss8j3khqNObr
+aCFTXjEWSJ6r7aAH/wgTq4Ij3UdcczQcFeeuYjYtCfXODI1+2pDDoOL9pmT6P5G0
+A8Rw45ztiQKBgQCY1ivUb/fCwjYY6QeSRuX6QLOX9nyUFQE4G+JmdHF9MU0R/lfI
+5vfmPDwr7A9Vz3sw4Jxh372RxVSQO8yidQnFPfw919PM2gBjUMrTfaSGcRVQfomS
+5UvyVmWgPQHZ/qI4qENIrZlYAQRHiMldkm8PB3dog5a21q7A7KrqFotreQKBgQC+
+QYytPGtpMvzNIzPYWQ8tWfPIq2JhzO2iJwAft88fq4A/gTJp0sE9fv7mQNwcZj+0
+QZseOUUb/SiGZSUV4eis/ujk3niRASooEHyRTagJZe6lYFP+MwRKGUJfaxANsIQz
+379a+oYGiaroNUyjezf6Ma0QfQILe9+pEre+facfaQKBgQDETrBre2t4M7oHfgHj
+apGgmr/RKZzc9ANDzjHL6dr8YehF2+dZDLkwJn1H91wdqwI3xOqH/DagwLUvrXiY
+7M8neBDbKh4uo6ukpC6ZnS2TLBgzwTf5L7vUOP7Pa2D5Au0Cht5uWAqHckajA+2a
+0g2dRiZbbwqiCygMiIU0AINRvA==
+-----END PRIVATE KEY-----
diff --git a/chrome/test/data/extensions/api_test/enterprise_kiosk_input/DIR_METADATA b/chrome/test/data/extensions/api_test/enterprise_kiosk_input/DIR_METADATA
new file mode 100644
index 0000000..d4effef
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/enterprise_kiosk_input/DIR_METADATA
@@ -0,0 +1 @@
+mixins: "//chrome/browser/ash/app_mode/COMMON_METADATA"
diff --git a/chrome/test/data/extensions/api_test/enterprise_kiosk_input/OWNERS b/chrome/test/data/extensions/api_test/enterprise_kiosk_input/OWNERS
new file mode 100644
index 0000000..f782149
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/enterprise_kiosk_input/OWNERS
@@ -0,0 +1 @@
+file://chromeos/components/kiosk/OWNERS
diff --git a/chrome/test/data/extensions/api_test/enterprise_kiosk_input/manifest.json b/chrome/test/data/extensions/api_test/enterprise_kiosk_input/manifest.json
new file mode 100644
index 0000000..73a197c
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/enterprise_kiosk_input/manifest.json
@@ -0,0 +1,17 @@
+{
+    "name": "Kiosk Input API Test Extension",
+    "description": "Companion Extension for KioskEnterpriseInputApiBrowserTest",
+    "version": "1.3",
+    "manifest_version": 3,
+    "permissions": [
+        "enterprise.kioskInput"
+    ],
+    "background": {
+        "service_worker": "service_worker.js"
+    },
+    "externally_connectable": {
+        "matches": [
+            "<all_urls>"
+        ]
+    }
+}
diff --git a/chrome/test/data/chromeos/app_mode/apps_and_extensions/input_extension/src/service_worker.js b/chrome/test/data/extensions/api_test/enterprise_kiosk_input/service_worker.js
similarity index 85%
rename from chrome/test/data/chromeos/app_mode/apps_and_extensions/input_extension/src/service_worker.js
rename to chrome/test/data/extensions/api_test/enterprise_kiosk_input/service_worker.js
index 8f9184b05..55d7220 100644
--- a/chrome/test/data/chromeos/app_mode/apps_and_extensions/input_extension/src/service_worker.js
+++ b/chrome/test/data/extensions/api_test/enterprise_kiosk_input/service_worker.js
@@ -11,6 +11,9 @@
       case "set_input_method":
         runSetInputMethod(data, sendResponse);
         return true;
+      case "version":
+        sendResponse("1.3");
+        return false;
     }
     sendResponse('unknown message "' + message + '"');
     return false;
@@ -28,5 +31,5 @@
   );
 }
 
-// Report back to the browsertest that the extension is ready.
+// Trigger `kReadyMessageReceived` in `extension_force_install_mixin.cc`.
 chrome.test?.sendMessage && chrome.test.sendMessage('ready')
diff --git a/chrome/test/data/web_apps/simple_isolated_app/cached_service_worker.js b/chrome/test/data/web_apps/simple_isolated_app/cached_service_worker.js
new file mode 100644
index 0000000..43c005c
--- /dev/null
+++ b/chrome/test/data/web_apps/simple_isolated_app/cached_service_worker.js
@@ -0,0 +1,19 @@
+// Copyright 2025 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+const CACHE_NAME = 'request-cache-v1';
+
+self.addEventListener('install', evt => {
+  evt.waitUntil(async function() {
+    const url = '/test.js'
+    const cache = await caches.open(CACHE_NAME);
+    const customHeaders = new Headers();
+    customHeaders.append('Content-Type', 'text/html');
+    const responseBody = 'test successful';
+    const response = new Response(responseBody, {
+      headers: customHeaders
+    });
+    await cache.put(url, response);
+  }());
+});
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 3a16511e..7db5966f 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-16364.0.0-1070576
\ No newline at end of file
+16364.0.0-1070586
\ No newline at end of file
diff --git a/clank b/clank
index 0e2e94e0..ab634f9 160000
--- a/clank
+++ b/clank
@@ -1 +1 @@
-Subproject commit 0e2e94e036bdbd47b362c54b645e6da30ad2c932
+Subproject commit ab634f9586da5bb34ba75ca89615831c01b594a3
diff --git a/components/android_autofill/browser/android_autofill_features.cc b/components/android_autofill/browser/android_autofill_features.cc
index c96ab6a..30dc630 100644
--- a/components/android_autofill/browser/android_autofill_features.cc
+++ b/components/android_autofill/browser/android_autofill_features.cc
@@ -39,7 +39,7 @@
 // passkey request with a long-press action on webauthn-annotated fields.
 BASE_FEATURE(kAutofillVirtualViewStructureAndroidPasskeyLongPress,
              "AutofillVirtualViewStructureAndroidPasskeyLongPress",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 // If enabled, the AutofillManagerWrapper class will not be initialized when the
 // AutofillProvider Java class is initialized. Some apps do not use Autofill at
diff --git a/components/android_autofill/browser/android_autofill_provider_test_api.h b/components/android_autofill/browser/android_autofill_provider_test_api.h
index 8fa3005..daf658b 100644
--- a/components/android_autofill/browser/android_autofill_provider_test_api.h
+++ b/components/android_autofill/browser/android_autofill_provider_test_api.h
@@ -23,6 +23,8 @@
     return *provider_->keyboard_suppressor_;
   }
 
+  void OnTriggerPasskeyRequest() { provider_->OnTriggerPasskeyRequest(); }
+
  private:
   const raw_ref<AndroidAutofillProvider> provider_;
 };
diff --git a/components/android_autofill/browser/android_autofill_provider_unittest.cc b/components/android_autofill/browser/android_autofill_provider_unittest.cc
index 0235fc5..91a4efa 100644
--- a/components/android_autofill/browser/android_autofill_provider_unittest.cc
+++ b/components/android_autofill/browser/android_autofill_provider_unittest.cc
@@ -939,35 +939,25 @@
 }
 
 TEST_F(AndroidAutofillProviderWithCredManTest,
-       LogConditionalPasskeysFlowPasskeysAvailableMetricWithoutPasskeys) {
-  base::HistogramTester histogram_tester;
+       LogConditionalPasskeysFlowPasskeysAvailableOnLongPress) {
   ON_CALL(cred_man_delegate(), HasPasskeys())
       .WillByDefault(
           Return(webauthn::WebAuthnCredManDelegate::State::kNoPasskeys));
 
-  // Focus the form field.
-  base::RepeatingCallback<void(bool)> completed_callback;
-  EXPECT_CALL(cred_man_delegate(), SetRequestCompletionCallback)
-      .WillOnce(SaveArg<0>(&completed_callback));
+  // Focus the form field which has no immediate passkey effect.
   FocusFormField(webauthn_email_field());
+  EXPECT_FALSE(keyboard_suppressor().is_suppressing());
 
-  // Keyboard is suppressed while CredMan is showing.
-  EXPECT_TRUE(keyboard_suppressor().is_suppressing());
-  Mock::VerifyAndClearExpectations(&cred_man_delegate());
-
-  // Hide CredMan.
-  completed_callback.Run(/*success=*/true);
-
-  histogram_tester.ExpectUniqueSample(
-      "Autofill.ConditionalPasskeysFlow.PasskeysState",
-      webauthn::WebAuthnCredManDelegate::State::kNoPasskeys, 1);
+  // Simulate the long-press suggestion was accepted.
+  EXPECT_CALL(cred_man_delegate(),
+              TriggerCredManUi(Eq(
+                  webauthn::WebAuthnCredManDelegate::RequestPasswords(false))));
+  test_api(autofill_provider()).OnTriggerPasskeyRequest();
 }
 
 TEST_F(AndroidAutofillProviderWithCredManTest,
        LogConditionalPasskeysFlowPasskeysUnavailableWithoutPasskeys) {
   base::HistogramTester histogram_tester;
-  base::test::ScopedFeatureList scoped_feature_list{
-      features::kAutofillVirtualViewStructureAndroidPasskeyLongPress};
   ON_CALL(cred_man_delegate(), HasPasskeys())
       .WillByDefault(
           Return(webauthn::WebAuthnCredManDelegate::State::kNoPasskeys));
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn
index c73eff21..ee0f854 100644
--- a/components/autofill/core/browser/BUILD.gn
+++ b/components/autofill/core/browser/BUILD.gn
@@ -620,6 +620,8 @@
     "studies/autofill_experiments.h",
     "suggestions/addresses/address_suggestion_generator.cc",
     "suggestions/addresses/address_suggestion_generator.h",
+    "suggestions/autofill_ai_suggestion_generator.cc",
+    "suggestions/autofill_ai_suggestion_generator.h",
     "suggestions/one_time_passwords/otp_suggestion_generator.cc",
     "suggestions/one_time_passwords/otp_suggestion_generator.h",
     "suggestions/payments/iban_suggestion_generator.cc",
@@ -1505,6 +1507,7 @@
     "studies/autofill_ablation_study_unittest.cc",
     "studies/autofill_experiments_unittest.cc",
     "suggestions/addresses/address_suggestion_generator_unittest.cc",
+    "suggestions/autofill_ai_suggestion_generator_unittests.cc",
     "suggestions/one_time_passwords/otp_suggestion_generator_unittest.cc",
     "suggestions/payments/iban_suggestion_generator_unittest.cc",
     "suggestions/payments/merchant_promo_code_suggestion_generator_unittest.cc",
diff --git a/components/autofill/core/browser/data_manager/payments/payments_data_manager.cc b/components/autofill/core/browser/data_manager/payments/payments_data_manager.cc
index 988aff7..7b53a2a3 100644
--- a/components/autofill/core/browser/data_manager/payments/payments_data_manager.cc
+++ b/components/autofill/core/browser/data_manager/payments/payments_data_manager.cc
@@ -1009,10 +1009,6 @@
         // BUILDFLAG(IS_CHROMEOS)
 }
 
-bool PaymentsDataManager::IsAutofillBnplPrefEnabled() const {
-  return prefs::IsAutofillBnplEnabled(pref_service_);
-}
-
 void PaymentsDataManager::NotifyObservers() {
   if (!HasPendingPaymentQueries()) {
     for (Observer& o : observers_) {
@@ -1061,6 +1057,10 @@
       features::kAutofillEnableCardBenefitsSync);
 }
 
+bool PaymentsDataManager::IsAutofillBnplPrefEnabled() const {
+  return prefs::IsAutofillBnplEnabled(pref_service_);
+}
+
 bool PaymentsDataManager::IsAutofillPaymentMethodsEnabled() const {
   return prefs::IsAutofillPaymentMethodsEnabled(pref_service_);
 }
@@ -2258,29 +2258,6 @@
     return;
   }
 
-  DenseSet<PaymentInstrument::ActionRequired> action_required =
-      DenseSet<PaymentInstrument::ActionRequired>();
-
-  // Sets values for `BnplIssuer::action_required` when the list is not empty
-  // and flag 'kAutofillEnableBuyNowPayLaterForExternallyLinkedKlarna` is
-  // enabled.
-  // Note: `action_required_size()` is checked first so that the experiment
-  // groups only contain users having nonempty`action_required` info.
-  if (payment_instrument.action_required_size() > 0 &&
-      base::FeatureList::IsEnabled(
-          features::kAutofillEnableBuyNowPayLaterForExternallyLinkedKlarna)) {
-    for (int action_required_sync : payment_instrument.action_required()) {
-      switch (action_required_sync) {
-        case sync_pb::PaymentInstrument_ActionRequired_ACTION_REQUIRED_UNKNOWN:
-          action_required.insert(PaymentInstrument::ActionRequired::kUnknown);
-          break;
-        case sync_pb::PaymentInstrument_ActionRequired_ACCEPT_TOS:
-          action_required.insert(PaymentInstrument::ActionRequired::kAcceptTos);
-          break;
-      }
-    }
-  }
-
   // `IsBnplIssuerSupported` is already called to filter out any unknown
   // issuer IDs that might be returned by the payment server. This ensures that
   // only issuer IDs with a corresponding BnplIssuer::IssuerId enum value are
@@ -2289,7 +2266,7 @@
   linked_bnpl_issuers_.emplace_back(
       payment_instrument.instrument_id(),
       ConvertToBnplIssuerIdEnum(bnpl_issuer_details.issuer_id()),
-      std::move(eligible_price_ranges), std::move(action_required));
+      std::move(eligible_price_ranges));
 }
 
 void PaymentsDataManager::CacheIfEwalletPaymentInstrument(
diff --git a/components/autofill/core/browser/data_manager/payments/payments_data_manager.h b/components/autofill/core/browser/data_manager/payments/payments_data_manager.h
index 78336ed..54aa250 100644
--- a/components/autofill/core/browser/data_manager/payments/payments_data_manager.h
+++ b/components/autofill/core/browser/data_manager/payments/payments_data_manager.h
@@ -571,9 +571,6 @@
 
   void SetPrefService(PrefService* pref_service);
 
-  // Returns the value of the AutofillBnplEnabled pref.
-  virtual bool IsAutofillBnplPrefEnabled() const;
-
   void NotifyObservers();
 
   CreditCard* GetMutableCreditCardByGUID(const std::string& guid);
@@ -649,6 +646,9 @@
   // Returns whether Autofill card benefit suggestion labels should be blocked.
   bool ShouldBlockCardBenefitSuggestionLabels() const;
 
+  // Returns the value of the AutofillBnplEnabled pref.
+  virtual bool IsAutofillBnplPrefEnabled() const;
+
   // Checks whether any new card art url is synced. If so, attempt to fetch the
   // image based on the url.
   void ProcessCardArtUrlChanges();
diff --git a/components/autofill/core/browser/data_manager/payments/payments_data_manager_unittest.cc b/components/autofill/core/browser/data_manager/payments/payments_data_manager_unittest.cc
index 5ea4d4d..562fbe8b 100644
--- a/components/autofill/core/browser/data_manager/payments/payments_data_manager_unittest.cc
+++ b/components/autofill/core/browser/data_manager/payments/payments_data_manager_unittest.cc
@@ -2381,7 +2381,7 @@
       test::CreatePaymentInstrumentWithLinkedBnplIssuer(
           1234L, std::string(kBnplAffirmIssuerId), "USD",
           /*min_price_in_micros=*/0,
-          /*max_price_in_micros=*/35'000'000);
+          /*max_price_in_micros=*/35000000);
   ASSERT_TRUE(
       GetServerDataTable()->SetPaymentInstruments({payment_instrument}));
 
@@ -2411,12 +2411,12 @@
       test::CreatePaymentInstrumentWithLinkedBnplIssuer(
           1234L, std::string(kBnplAffirmIssuerId), "USD",
           /*min_price_in_micros=*/0,
-          /*max_price_in_micros=*/35'000'000);
+          /*max_price_in_micros=*/35000000);
   sync_pb::PaymentInstrument payment_instrument_2 =
       test::CreatePaymentInstrumentWithLinkedBnplIssuer(
           2345L, std::string(kBnplZipIssuerId), "USD",
           /*min_price_in_micros=*/0,
-          /*max_price_in_micros=*/35'000'000);
+          /*max_price_in_micros=*/35000000);
   ASSERT_TRUE(GetServerDataTable()->SetPaymentInstruments(
       {payment_instrument_1, payment_instrument_2}));
 
@@ -2442,7 +2442,7 @@
       test::CreatePaymentInstrumentWithLinkedBnplIssuer(
           1234L, "unsupported_issuer_id", "USD",
           /*min_price_in_micros=*/0,
-          /*max_price_in_micros=*/35'000'000);
+          /*max_price_in_micros=*/35000000);
   ASSERT_TRUE(
       GetServerDataTable()->SetPaymentInstruments({payment_instrument_1}));
 
@@ -2464,8 +2464,8 @@
   int64_t instrument_id = 1234L;
   std::string issuer_id = std::string(kBnplAffirmIssuerId);
   std::string currency = "USD";
-  uint64_t min_price_in_micros = 5'000'000;
-  uint64_t max_price_in_micros = 35'000'000;
+  uint64_t min_price_in_micros = 5000000;
+  uint64_t max_price_in_micros = 35000000;
   sync_pb::PaymentInstrument payment_instrument =
       test::CreatePaymentInstrumentWithLinkedBnplIssuer(
           instrument_id, issuer_id, currency, min_price_in_micros,
@@ -2504,8 +2504,8 @@
   int64_t instrument_id = 1234L;
   std::string issuer_id = std::string(kBnplAffirmIssuerId);
   std::string currency = "USD";
-  uint64_t min_price_in_micros = 50'000'000;
-  uint64_t max_price_in_micros = 35'000'000;
+  uint64_t min_price_in_micros = 50000000;
+  uint64_t max_price_in_micros = 35000000;
   sync_pb::PaymentInstrument payment_instrument =
       test::CreatePaymentInstrumentWithLinkedBnplIssuer(
           instrument_id, issuer_id, currency, min_price_in_micros,
@@ -2542,8 +2542,7 @@
       {test::CreatePaymentInstrumentWithLinkedBnplIssuer(
           /*instrument_id=*/1234L,
           /*issuer_id=*/std::string(kBnplAffirmIssuerId), /*currency=*/"CAD",
-          /*min_price_in_micros=*/5'000'000,
-          /*max_price_in_micros=*/35'000'000)}));
+          /*min_price_in_micros=*/5000000, /*max_price_in_micros=*/35000000)}));
 
   // `Refresh()` must be called to ensure that the linked BNPL issuer payment
   // instruments are loaded again from the WebDatabase.
@@ -2555,79 +2554,6 @@
   EXPECT_TRUE(payments_data_manager().GetLinkedBnplIssuers().empty());
 }
 
-// Tests that `action_required` is not set for BNPL issuers if flag
-// `AutofillEnableBuyNowPayLaterForExternallyLinkedKlarna` is disabled.
-TEST_F(PaymentsDataManagerTest,
-       GetLinkedBnplIssuers_IssuerLinkedExternally_FlagDisabled) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitWithFeatures(
-      /*enabled_features=*/{features::kAutofillEnableBuyNowPayLaterSyncing,
-                            features::kAutofillEnableBuyNowPayLaterForKlarna},
-      /*disabled_features=*/{
-          features::kAutofillEnableBuyNowPayLaterForExternallyLinkedKlarna});
-  sync_pb::PaymentInstrument payment_instrument =
-      test::CreatePaymentInstrumentWithLinkedBnplIssuer(
-          /*instrument_id=*/1234L, std::string(kBnplKlarnaIssuerId), "USD",
-          /*min_price_in_micros=*/0,
-          /*max_price_in_micros=*/35'000'000,
-          /*actions_required=*/
-          {sync_pb::PaymentInstrument_ActionRequired_ACCEPT_TOS});
-  ASSERT_TRUE(
-      GetServerDataTable()->SetPaymentInstruments({payment_instrument}));
-  payments_data_manager().Refresh();
-  WaitForOnPaymentsDataChanged();
-
-  base::span<const BnplIssuer> linked_bnpl_issuers =
-      payments_data_manager().GetLinkedBnplIssuers();
-
-  ASSERT_EQ(linked_bnpl_issuers.size(), 1U);
-  EXPECT_EQ(
-      linked_bnpl_issuers[0],
-      BnplIssuer(
-          /*instrument_id=*/1234L, BnplIssuer::IssuerId::kBnplKlarna,
-          /*eligible_price_ranges=*/
-          {BnplIssuer::EligiblePriceRange("USD", /*price_lower_bound=*/0,
-                                          /*price_upper_bound=*/35'000'000)},
-          /*action_required=*/DenseSet<PaymentInstrument::ActionRequired>()));
-}
-
-// Tests that `action_required` is set for BNPL issuers if flag
-// `AutofillEnableBuyNowPayLaterForExternallyLinkedKlarna` is enabled.
-TEST_F(PaymentsDataManagerTest, GetLinkedBnplIssuers_IssuerLinkedExternally) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitWithFeatures(
-      /*enabled_features=*/
-      {features::kAutofillEnableBuyNowPayLaterSyncing,
-       features::kAutofillEnableBuyNowPayLaterForKlarna,
-       features::kAutofillEnableBuyNowPayLaterForExternallyLinkedKlarna},
-      /*disabled_features=*/{});
-  sync_pb::PaymentInstrument payment_instrument =
-      test::CreatePaymentInstrumentWithLinkedBnplIssuer(
-          /*instrument_id=*/1234L, std::string(kBnplKlarnaIssuerId), "USD",
-          /*min_price_in_micros=*/0,
-          /*max_price_in_micros=*/35'000'000,
-          /*actions_required=*/
-          {sync_pb::PaymentInstrument_ActionRequired_ACCEPT_TOS});
-  ASSERT_TRUE(
-      GetServerDataTable()->SetPaymentInstruments({payment_instrument}));
-  payments_data_manager().Refresh();
-  WaitForOnPaymentsDataChanged();
-
-  base::span<const BnplIssuer> linked_bnpl_issuers =
-      payments_data_manager().GetLinkedBnplIssuers();
-
-  ASSERT_EQ(linked_bnpl_issuers.size(), 1U);
-  EXPECT_EQ(
-      linked_bnpl_issuers[0],
-      BnplIssuer(
-          /*instrument_id=*/1234L, BnplIssuer::IssuerId::kBnplKlarna,
-          /*eligible_price_ranges=*/
-          {BnplIssuer::EligiblePriceRange("USD", /*price_lower_bound=*/0,
-                                          /*price_upper_bound=*/35'000'000)},
-          /*action_required=*/
-          DenseSet({PaymentInstrument::ActionRequired::kAcceptTos})));
-}
-
 #endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) ||
         // BUILDFLAG(IS_CHROMEOS)
 
diff --git a/components/autofill/core/browser/data_manager/payments/test_payments_data_manager.cc b/components/autofill/core/browser/data_manager/payments/test_payments_data_manager.cc
index ca60924..8f6cf49 100644
--- a/components/autofill/core/browser/data_manager/payments/test_payments_data_manager.cc
+++ b/components/autofill/core/browser/data_manager/payments/test_payments_data_manager.cc
@@ -256,13 +256,6 @@
   return false;
 }
 
-bool TestPaymentsDataManager::IsAutofillBnplPrefEnabled() const {
-  if (autofill_bnpl_enabled_.has_value()) {
-    return autofill_bnpl_enabled_.value();
-  }
-  return PaymentsDataManager::IsAutofillBnplPrefEnabled();
-}
-
 CoreAccountInfo TestPaymentsDataManager::GetAccountInfoForPaymentsServer()
     const {
   return account_info_;
diff --git a/components/autofill/core/browser/data_manager/payments/test_payments_data_manager.h b/components/autofill/core/browser/data_manager/payments/test_payments_data_manager.h
index 224bef9..0e3488e 100644
--- a/components/autofill/core/browser/data_manager/payments/test_payments_data_manager.h
+++ b/components/autofill/core/browser/data_manager/payments/test_payments_data_manager.h
@@ -61,7 +61,6 @@
       const CreditCard& imported_credit_card) override;
   bool IsPaymentCvcStorageEnabled() override;
   bool IsSyncFeatureEnabledForPaymentsServerMetrics() const override;
-  bool IsAutofillBnplPrefEnabled() const override;
   CoreAccountInfo GetAccountInfoForPaymentsServer() const override;
 
   // Clears |local_credit_cards_| and |server_credit_cards_|.
@@ -89,10 +88,6 @@
     payments_cvc_storage_enabled_ = enabled;
   }
 
-  void SetIsAutofillBnplPrefEnabled(bool enabled) {
-    autofill_bnpl_enabled_ = enabled;
-  }
-
   // Adds a card to `server_credit_cards_`. This test class treats masked and
   // full server cards equally, relying on their preset RecordType to
   // differentiate them.
@@ -147,7 +142,6 @@
   std::optional<bool> payments_wallet_sync_transport_enabled_;
   std::optional<bool> payment_methods_mandatory_reauth_enabled_;
   std::optional<bool> payments_cvc_storage_enabled_;
-  std::optional<bool> autofill_bnpl_enabled_;
   CoreAccountInfo account_info_;
   std::unique_ptr<TestAutofillImageFetcher> owned_image_fetcher_;
 };
diff --git a/components/autofill/core/browser/data_model/autofill_ai/entity_type.cc b/components/autofill/core/browser/data_model/autofill_ai/entity_type.cc
index 2d157cc..53c63d9 100644
--- a/components/autofill/core/browser/data_model/autofill_ai/entity_type.cc
+++ b/components/autofill/core/browser/data_model/autofill_ai/entity_type.cc
@@ -107,6 +107,7 @@
   return rank(lhs) < rank(rhs);
 }
 
+// LINT.IfChange(EntityType)
 std::u16string EntityType::GetNameForI18n() const {
   switch (name()) {
     case EntityTypeName::kDriversLicense:
@@ -122,6 +123,7 @@
   }
   NOTREACHED();
 }
+// LINT.ThenChange(/tools/metrics/histograms/metadata/autofill/enums.xml:AutofillAiEntityType)
 
 std::optional<EntityTypeName> ToSafeEntityTypeName(
     std::underlying_type_t<EntityTypeName> raw_value) {
diff --git a/components/autofill/core/browser/data_model/payments/bnpl_issuer.cc b/components/autofill/core/browser/data_model/payments/bnpl_issuer.cc
index f29cba0..ed0b9877 100644
--- a/components/autofill/core/browser/data_model/payments/bnpl_issuer.cc
+++ b/components/autofill/core/browser/data_model/payments/bnpl_issuer.cc
@@ -37,22 +37,17 @@
 
 bool operator==(const BnplIssuer& a, const BnplIssuer& b) = default;
 
-BnplIssuer::BnplIssuer(
-    std::optional<int64_t> instrument_id,
-    BnplIssuer::IssuerId issuer_id,
-    std::vector<EligiblePriceRange> eligible_price_ranges,
-    DenseSet<PaymentInstrument::ActionRequired> action_required)
+BnplIssuer::BnplIssuer(std::optional<int64_t> instrument_id,
+                       BnplIssuer::IssuerId issuer_id,
+                       std::vector<EligiblePriceRange> eligible_price_ranges)
     : issuer_id_(std::move(issuer_id)),
       payment_instrument_(
           instrument_id.has_value()
               ? std::make_optional<PaymentInstrument>(
                     instrument_id.value(),
-                    /*nickname=*/u"",
-                    /*display_icon_url=*/GURL(),
-                    /*supported_rails=*/
-                    DenseSet({PaymentInstrument::PaymentRail::kCardNumber}),
-                    /*is_fido_enrolled=*/false,
-                    std::move(action_required))
+                    u"",
+                    GURL(),
+                    DenseSet({PaymentInstrument::PaymentRail::kCardNumber}))
               : std::nullopt),
       eligible_price_ranges_(std::move(eligible_price_ranges)) {}
 
diff --git a/components/autofill/core/browser/data_model/payments/bnpl_issuer.h b/components/autofill/core/browser/data_model/payments/bnpl_issuer.h
index 0575642..e000485 100644
--- a/components/autofill/core/browser/data_model/payments/bnpl_issuer.h
+++ b/components/autofill/core/browser/data_model/payments/bnpl_issuer.h
@@ -73,13 +73,10 @@
   // `instrument_id` is present for linked issuers, and nullopt for unlinked
   // issuers. `issuer_id` is the unique identifier of this specfiic issuer.
   // `eligible_price_ranges` is a list of currencies mapped to their price
-  // ranges, in micros. 'action_required' is the additional steps needed to
-  // use this issuer.
+  // ranges, in micros.
   BnplIssuer(std::optional<int64_t> instrument_id,
              IssuerId issuer_id,
-             std::vector<EligiblePriceRange> eligible_price_ranges,
-             DenseSet<PaymentInstrument::ActionRequired> action_required =
-                 DenseSet<PaymentInstrument::ActionRequired>());
+             std::vector<EligiblePriceRange> eligible_price_ranges);
   BnplIssuer(const BnplIssuer&);
   BnplIssuer& operator=(const BnplIssuer&);
   BnplIssuer(BnplIssuer&&);
diff --git a/components/autofill/core/browser/form_processing/autofill_ai/determine_attribute_types.cc b/components/autofill/core/browser/form_processing/autofill_ai/determine_attribute_types.cc
index a0e45ae..5b29267 100644
--- a/components/autofill/core/browser/form_processing/autofill_ai/determine_attribute_types.cc
+++ b/components/autofill/core/browser/form_processing/autofill_ai/determine_attribute_types.cc
@@ -298,10 +298,15 @@
   return r;
 }
 
-bool AreFieldsRelevantForAutofillAi(
+DenseSet<EntityType> GetRelevantEntityTypesForFields(
     base::span<const std::unique_ptr<AutofillField>> fields) {
-  return !std::ranges::all_of(GetAttributeTypes(fields),
-                              &DenseSet<AttributeType>::empty);
+  DenseSet<EntityType> entity_types;
+  for (const DenseSet<AttributeType>& attributes : GetAttributeTypes(fields)) {
+    for (AttributeType attribute : attributes) {
+      entity_types.insert(attribute.entity_type());
+    }
+  }
+  return entity_types;
 }
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/form_processing/autofill_ai/determine_attribute_types.h b/components/autofill/core/browser/form_processing/autofill_ai/determine_attribute_types.h
index 621d713..5f10671 100644
--- a/components/autofill/core/browser/form_processing/autofill_ai/determine_attribute_types.h
+++ b/components/autofill/core/browser/form_processing/autofill_ai/determine_attribute_types.h
@@ -12,6 +12,7 @@
 #include "base/containers/flat_map.h"
 #include "base/containers/span.h"
 #include "components/autofill/core/browser/data_model/autofill_ai/entity_type.h"
+#include "components/autofill/core/common/dense_set.h"
 
 namespace autofill {
 
@@ -70,9 +71,9 @@
 DetermineAttributeTypes(
     base::span<const std::unique_ptr<AutofillField>> fields LIFETIME_BOUND);
 
-// Returns whether any of the `fields` have a non-empty AutofillAI
-// AttributeType.
-[[nodiscard]] bool AreFieldsRelevantForAutofillAi(
+// Returns the entity types for which at least one of `fields` have a
+// corresponding AttributeType.
+[[nodiscard]] DenseSet<EntityType> GetRelevantEntityTypesForFields(
     base::span<const std::unique_ptr<AutofillField>> fields);
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/form_processing/autofill_ai/determine_attribute_types_unittest.cc b/components/autofill/core/browser/form_processing/autofill_ai/determine_attribute_types_unittest.cc
index a454016..b395040 100644
--- a/components/autofill/core/browser/form_processing/autofill_ai/determine_attribute_types_unittest.cc
+++ b/components/autofill/core/browser/form_processing/autofill_ai/determine_attribute_types_unittest.cc
@@ -10,6 +10,8 @@
 #include "base/containers/to_vector.h"
 #include "base/test/scoped_feature_list.h"
 #include "components/autofill/core/browser/autofill_field.h"
+#include "components/autofill/core/browser/data_model/autofill_ai/entity_type.h"
+#include "components/autofill/core/browser/data_model/autofill_ai/entity_type_names.h"
 #include "components/autofill/core/browser/form_structure.h"
 #include "components/autofill/core/browser/form_structure_sectioning_util.h"
 #include "components/autofill/core/browser/test_utils/autofill_form_test_utils.h"
@@ -102,7 +104,7 @@
   EXPECT_THAT(DetermineAttributeTypes(fields), IsEmpty());
   EXPECT_THAT(DetermineAttributeTypes(fields, Section()), IsEmpty());
   EXPECT_THAT(DetermineAttributeTypes(fields, Section(), kPassport), IsEmpty());
-  EXPECT_FALSE(AreFieldsRelevantForAutofillAi(fields));
+  EXPECT_TRUE(GetRelevantEntityTypesForFields(fields).empty());
 }
 
 // Tests that DetermineAttributeTypes() processes `*_TAG` correctly if
@@ -151,7 +153,8 @@
                             Pair(kVehicle, vehicle_matcher),
                             Pair(kDriversLicense, drivers_license_matcher)))));
 
-  EXPECT_TRUE(AreFieldsRelevantForAutofillAi(fields));
+  EXPECT_EQ(GetRelevantEntityTypesForFields(fields),
+            (DenseSet<EntityType>{kVehicle, kDriversLicense}));
 }
 
 // Tests that DetermineAttributeTypes() assigns static types correctly.
diff --git a/components/autofill/core/browser/foundations/browser_autofill_manager.cc b/components/autofill/core/browser/foundations/browser_autofill_manager.cc
index ae8fcfca..996c8e6 100644
--- a/components/autofill/core/browser/foundations/browser_autofill_manager.cc
+++ b/components/autofill/core/browser/foundations/browser_autofill_manager.cc
@@ -68,6 +68,7 @@
 #include "components/autofill/core/browser/crowdsourcing/determine_possible_field_types.h"
 #include "components/autofill/core/browser/crowdsourcing/votes_uploader.h"
 #include "components/autofill/core/browser/data_manager/addresses/address_data_manager.h"
+#include "components/autofill/core/browser/data_manager/autofill_ai/entity_data_manager.h"
 #include "components/autofill/core/browser/data_manager/payments/payments_data_manager.h"
 #include "components/autofill/core/browser/data_manager/personal_data_manager.h"
 #include "components/autofill/core/browser/data_manager/valuables/valuables_data_manager.h"
@@ -2172,9 +2173,20 @@
                             return GetFillingProductFromSuggestionType(type) ==
                                    FillingProduct::kAutofillAi;
                           })) {
-    ai_manager->OnSuggestionsShown(CHECK_DEREF(form_structure),
-                                   CHECK_DEREF(autofill_field),
-                                   driver().GetPageUkmSourceId());
+    DenseSet<EntityType> suggested_entity_types;
+    for (const Suggestion& suggestion : suggestions) {
+      if (const auto* payload =
+              std::get_if<Suggestion::AutofillAiPayload>(&suggestion.payload)) {
+        if (base::optional_ref<const EntityInstance> entity =
+                client().GetEntityDataManager()->GetEntityInstance(
+                    payload->guid)) {
+          suggested_entity_types.insert(entity->type());
+        }
+      }
+    }
+    ai_manager->OnSuggestionsShown(
+        CHECK_DEREF(form_structure), CHECK_DEREF(autofill_field),
+        suggested_entity_types, driver().GetPageUkmSourceId());
   }
 
   // Notify the BNPL manager about suggestion shown if the current shown
@@ -2623,8 +2635,8 @@
           [&](const EntityInstance* entity) {
             if (AutofillAiManager* ai_manager =
                     client().GetAutofillAiManager()) {
-              ai_manager->OnDidFillSuggestion(entity->guid(), form,
-                                              trigger_field, safe_filled_fields,
+              ai_manager->OnDidFillSuggestion(*entity, form, trigger_field,
+                                              safe_filled_fields,
                                               driver().GetPageUkmSourceId());
             }
           },
diff --git a/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_manager.cc b/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_manager.cc
index d2b33043..b2e2e4a 100644
--- a/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_manager.cc
+++ b/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_manager.cc
@@ -55,6 +55,7 @@
 #include "components/autofill/core/browser/strike_databases/autofill_ai/autofill_ai_save_strike_database_by_host.h"
 #include "components/autofill/core/browser/strike_databases/autofill_ai/autofill_ai_update_strike_database.h"
 #include "components/autofill/core/browser/strike_databases/strike_database.h"
+#include "components/autofill/core/browser/suggestions/autofill_ai_suggestion_generator.h"
 #include "components/autofill/core/browser/suggestions/suggestion.h"
 #include "components/autofill/core/browser/suggestions/suggestion_type.h"
 #include "components/autofill/core/common/autofill_features.h"
@@ -191,16 +192,20 @@
 
 AutofillAiManager::~AutofillAiManager() = default;
 
-void AutofillAiManager::OnSuggestionsShown(const FormStructure& form,
-                                           const AutofillField& field,
-                                           ukm::SourceId ukm_source_id) {
-  logger_.OnSuggestionsShown(form, field, ukm_source_id);
+void AutofillAiManager::OnSuggestionsShown(
+    const FormStructure& form,
+    const AutofillField& field,
+    DenseSet<EntityType> suggested_entity_types,
+    ukm::SourceId ukm_source_id) {
+  logger_.OnSuggestionsShown(form, field, suggested_entity_types,
+                             ukm_source_id);
 }
 
 void AutofillAiManager::OnFormSeen(const FormStructure& form) {
-  bool is_eligible = AreFieldsRelevantForAutofillAi(form.fields());
-  logger_.OnFormEligibilityAvailable(form.global_id(), is_eligible);
-  if (!is_eligible) {
+  const DenseSet<EntityType> relevant_entities =
+      GetRelevantEntityTypesForFields(form.fields());
+  logger_.OnFormEligibilityAvailable(form.global_id(), relevant_entities);
+  if (relevant_entities.empty()) {
     return;
   }
 
@@ -208,30 +213,34 @@
   if (!entity_manager) {
     return;
   }
-  if (entity_manager->GetEntityInstances().empty()) {
+
+  auto entities_to_fill = DenseSet<EntityType>(
+      entity_manager->GetEntityInstances(), &EntityInstance::type);
+  entities_to_fill.intersect(relevant_entities);
+  if (entities_to_fill.empty()) {
     return;
   }
-  // TODO(crbug.com/389629573): We should check whether any of `entities`
-  // can actually fill a field in the `form`, not only whether entities
-  // exist.
-  logger_.OnFormHasDataToFill(form.global_id());
+
+  logger_.OnFormHasDataToFill(form.global_id(), entities_to_fill);
 }
 
 void AutofillAiManager::OnDidFillSuggestion(
-    const base::Uuid& guid,
+    const EntityInstance& entity,
     const FormStructure& form,
     const AutofillField& trigger_field,
     base::span<const AutofillField* const> filled_fields,
     ukm::SourceId ukm_source_id) {
-  logger_.OnDidFillSuggestion(form, trigger_field, ukm_source_id);
+  logger_.OnDidFillSuggestion(form, trigger_field, entity.type(),
+                              ukm_source_id);
   for (const AutofillField* const field : filled_fields) {
-    logger_.OnDidFillField(form, CHECK_DEREF(field), ukm_source_id);
+    logger_.OnDidFillField(form, CHECK_DEREF(field), entity.type(),
+                           ukm_source_id);
   }
   EntityDataManager* entity_manager = client_->GetEntityDataManager();
   if (!entity_manager) {
     return;
   }
-  entity_manager->RecordEntityUsed(guid, base::Time::Now());
+  entity_manager->RecordEntityUsed(entity.guid(), base::Time::Now());
 }
 
 void AutofillAiManager::OnEditedAutofilledField(const FormStructure& form,
@@ -242,10 +251,8 @@
 
 bool AutofillAiManager::OnFormSubmitted(const FormStructure& form,
                                         ukm::SourceId ukm_source_id) {
-  if (AreFieldsRelevantForAutofillAi(form.fields())) {
-    logger_.RecordFormMetrics(form, ukm_source_id, /*submission_state=*/true,
-                              GetAutofillAiOptInStatus(*client_));
-  }
+  logger_.RecordFormMetrics(form, ukm_source_id, /*submission_state=*/true,
+                            GetAutofillAiOptInStatus(*client_));
   return MaybeImportForm(form);
 }
 
@@ -345,29 +352,32 @@
 std::vector<Suggestion> AutofillAiManager::GetSuggestions(
     const FormStructure& form,
     const FormFieldData& trigger_field) {
-  if (!MayPerformAutofillAiAction(*client_, AutofillAiAction::kFilling)) {
-    return {};
-  }
-
-  EntityDataManager* entity_manager = client_->GetEntityDataManager();
-  if (!entity_manager) {
-    return {};
-  }
-
-  base::span<const EntityInstance> entities =
-      entity_manager->GetEntityInstances();
-  if (entities.empty()) {
-    return {};
-  }
-
+  AutofillAiSuggestionGenerator suggestion_generator;
+  std::vector<Suggestion> suggestions;
   const AutofillField* autofill_field =
       form.GetFieldById(trigger_field.global_id());
-  if (!autofill_field) {
-    return {};
-  }
 
-  return CreateAutofillAiFillingSuggestions(form, trigger_field, entities,
-                                  client_->GetAppLocale());
+  auto on_suggestion_data_returned =
+      [&form, &autofill_field, &trigger_field, &suggestions,
+       &suggestion_generator](
+          std::pair<FillingProduct,
+                    std::vector<SuggestionGenerator::SuggestionData>>
+              suggestion_data) {
+        suggestion_generator.GenerateSuggestions(
+            form.ToFormData(), trigger_field, &form, autofill_field,
+            {std::move(suggestion_data)},
+            [&suggestions](
+                SuggestionGenerator::ReturnedSuggestions returned_suggestions) {
+              suggestions = std::move(returned_suggestions.second);
+            });
+      };
+
+  // Since the `on_suggestion_data_returned` callback is called synchronously,
+  // we can assume that `suggestions_generated` will hold correct value.
+  suggestion_generator.FetchSuggestionData(form.ToFormData(), trigger_field,
+                                           &form, autofill_field, *client_,
+                                           on_suggestion_data_returned);
+  return suggestions;
 }
 
 bool AutofillAiManager::ShouldDisplayIph(const FormStructure& form,
diff --git a/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_manager.h b/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_manager.h
index 3ca18c0..99d3f0a 100644
--- a/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_manager.h
+++ b/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_manager.h
@@ -67,10 +67,11 @@
 
   virtual void OnSuggestionsShown(const FormStructure& form,
                                   const AutofillField& field,
+                                  DenseSet<EntityType> suggested_entity_types,
                                   ukm::SourceId ukm_source_id);
   virtual void OnFormSeen(const FormStructure& form);
   virtual void OnDidFillSuggestion(
-      const base::Uuid& guid,
+      const EntityInstance& entity,
       const FormStructure& form,
       const AutofillField& field,
       base::span<const AutofillField* const> filled_fields,
diff --git a/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_suggestions.cc b/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_suggestions.cc
index ec10582..af0625c4 100644
--- a/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_suggestions.cc
+++ b/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_suggestions.cc
@@ -372,29 +372,20 @@
   AttributeTypeAssignment assignment =
       AttributeTypeAssignment(form.fields(), trigger_field->section());
 
-  // Sort entities based on their frecency.
-  std::vector<const EntityInstance*> sorted_entities = base::ToVector(
-      entities, [](const EntityInstance& entity) { return &entity; });
-  std::ranges::sort(sorted_entities,
-                    [comp = EntityInstance::FrecencyOrder(base::Time::Now())](
-                        const EntityInstance* lhs, const EntityInstance* rhs) {
-                      return comp(*lhs, *rhs);
-                    });
-
   std::vector<SuggestionWithMetadata> suggestions_with_metadata;
-  for (const EntityInstance* entity : sorted_entities) {
+  for (const EntityInstance& entity : entities) {
     base::span<const AutofillFieldWithAttributeType> fields_with_types =
-        assignment.Find(entity->type());
+        assignment.Find(entity.type());
     base::optional_ref<const AutofillFieldWithAttributeType>
         trigger_field_with_type =
             FindField(fields_with_types, trigger_field->global_id());
     if (!trigger_field_with_type ||
-        !EntityShouldProduceSuggestion(*entity, *trigger_field_with_type,
+        !EntityShouldProduceSuggestion(entity, *trigger_field_with_type,
                                        app_locale)) {
       continue;
     }
     suggestions_with_metadata.push_back(GetSuggestionForEntity(
-        *entity, fields_with_types, *trigger_field_with_type, app_locale));
+        entity, fields_with_types, *trigger_field_with_type, app_locale));
   }
 
   if (suggestions_with_metadata.empty()) {
@@ -412,11 +403,10 @@
   // generate suggestions on a certain triggering field still affect label
   // generation and should be taken into account.
   std::vector<const EntityInstance*> other_entities_that_can_fill_section;
-  for (const EntityInstance* entity : sorted_entities) {
-    if (!entities_used_to_build_suggestions.contains(entity->guid()) &&
-        CanFillSomeField(*entity, assignment.Find(entity->type()),
-                         app_locale)) {
-      other_entities_that_can_fill_section.push_back(entity);
+  for (const EntityInstance& entity : entities) {
+    if (!entities_used_to_build_suggestions.contains(entity.guid()) &&
+        CanFillSomeField(entity, assignment.Find(entity.type()), app_locale)) {
+      other_entities_that_can_fill_section.push_back(&entity);
     }
   }
 
diff --git a/components/autofill/core/browser/integrators/autofill_ai/metrics/autofill_ai_logger.cc b/components/autofill/core/browser/integrators/autofill_ai/metrics/autofill_ai_logger.cc
index 33d92ba..804f80f 100644
--- a/components/autofill/core/browser/integrators/autofill_ai/metrics/autofill_ai_logger.cc
+++ b/components/autofill/core/browser/integrators/autofill_ai/metrics/autofill_ai_logger.cc
@@ -4,6 +4,7 @@
 
 #include "components/autofill/core/browser/integrators/autofill_ai/metrics/autofill_ai_logger.h"
 
+#include <algorithm>
 #include <memory>
 #include <optional>
 #include <string_view>
@@ -28,6 +29,22 @@
 constexpr std::string_view key_metric_histogram_prefix =
     "Autofill.Ai.KeyMetrics.";
 
+// LINT.IfChange(HistogramSuffixForEntityType)
+std::string_view HistogramSuffixForEntityType(EntityType type) {
+  switch (type.name()) {
+    case EntityTypeName::kDriversLicense:
+      return "DriversLicense";
+    case EntityTypeName::kNationalIdCard:
+      return "NationalIdCard";
+    case EntityTypeName::kPassport:
+      return "Passport";
+    case EntityTypeName::kVehicle:
+      return "Vehicle";
+  }
+  NOTREACHED();
+}
+// LINT.ThenChange(//tools/metrics/histograms/metadata/autofill/enums.xml:AutofillAiEntityType)
+
 void LogFunnelMetric(std::string_view funnel_metric_name,
                      bool submission_state,
                      bool metric_value) {
@@ -43,14 +60,9 @@
 void LogKeyMetric(std::string_view key_metric_name,
                   std::string_view entity_type,
                   bool metric_value) {
-  const std::string generic_histogram_name =
-      base::StrCat({key_metric_histogram_prefix, key_metric_name});
-  base::UmaHistogramBoolean(generic_histogram_name, metric_value);
-  if (!entity_type.empty()) {
-    const std::string entity_specific_histogram =
-        base::StrCat({generic_histogram_name, ".", entity_type});
-    base::UmaHistogramBoolean(entity_specific_histogram, metric_value);
-  }
+  const std::string histogram_name = base::StrCat(
+      {key_metric_histogram_prefix, key_metric_name, ".", entity_type});
+  base::UmaHistogramBoolean(histogram_name, metric_value);
 }
 
 }  // namespace
@@ -59,27 +71,39 @@
     : ukm_logger_(client) {}
 AutofillAiLogger::~AutofillAiLogger() = default;
 
-void AutofillAiLogger::OnFormEligibilityAvailable(FormGlobalId form_id,
-                                                  bool is_eligible) {
-  form_states_[form_id].is_eligible = is_eligible;
+void AutofillAiLogger::OnFormEligibilityAvailable(
+    FormGlobalId form_id,
+    DenseSet<EntityType> relevant_entities) {
+  for (EntityType entity_type : relevant_entities) {
+    form_states_[form_id][entity_type].is_eligible = true;
+  }
 }
 
-void AutofillAiLogger::OnFormHasDataToFill(FormGlobalId form_id) {
-  form_states_[form_id].has_data_to_fill = true;
+void AutofillAiLogger::OnFormHasDataToFill(
+    FormGlobalId form_id,
+    DenseSet<EntityType> entities_to_fill) {
+  for (EntityType entity_type : entities_to_fill) {
+    form_states_[form_id][entity_type].has_data_to_fill = true;
+  }
 }
 
-void AutofillAiLogger::OnSuggestionsShown(const FormStructure& form,
-                                          const AutofillField& field,
-                                          ukm::SourceId ukm_source_id) {
-  form_states_[form.global_id()].suggestions_shown = true;
+void AutofillAiLogger::OnSuggestionsShown(
+    const FormStructure& form,
+    const AutofillField& field,
+    DenseSet<EntityType> suggested_entity_types,
+    ukm::SourceId ukm_source_id) {
+  for (EntityType type : suggested_entity_types) {
+    form_states_[form.global_id()][type].suggestions_shown = true;
+  }
   ukm_logger_.LogFieldEvent(ukm_source_id, form, field,
                             AutofillAiUkmLogger::EventType::kSuggestionShown);
 }
 
 void AutofillAiLogger::OnDidFillSuggestion(const FormStructure& form,
                                            const AutofillField& field,
+                                           EntityType entity_type,
                                            ukm::SourceId ukm_source_id) {
-  form_states_[form.global_id()].did_fill_suggestions = true;
+  form_states_[form.global_id()][entity_type].did_fill_suggestions = true;
   ukm_logger_.LogFieldEvent(ukm_source_id, form, field,
                             AutofillAiUkmLogger::EventType::kSuggestionFilled);
 }
@@ -87,7 +111,11 @@
 void AutofillAiLogger::OnEditedAutofilledField(const FormStructure& form,
                                                const AutofillField& field,
                                                ukm::SourceId ukm_source_id) {
-  form_states_[form.global_id()].edited_autofilled_field = true;
+  if (auto it = last_filled_entity_.find(field.global_id());
+      it != last_filled_entity_.end()) {
+    EntityType entity_type = it->second;
+    form_states_[form.global_id()][entity_type].edited_autofilled_field = true;
+  }
   ukm_logger_.LogFieldEvent(
       ukm_source_id, form, field,
       AutofillAiUkmLogger::EventType::kEditedAutofilledValue);
@@ -95,7 +123,9 @@
 
 void AutofillAiLogger::OnDidFillField(const FormStructure& form,
                                       const AutofillField& field,
+                                      EntityType entity_type,
                                       ukm::SourceId ukm_source_id) {
+  last_filled_entity_.insert({field.global_id(), entity_type});
   ukm_logger_.LogFieldEvent(ukm_source_id, form, field,
                             AutofillAiUkmLogger::EventType::kFieldFilled);
 }
@@ -104,84 +134,119 @@
                                          ukm::SourceId ukm_source_id,
                                          bool submission_state,
                                          bool opt_in_status) {
-  FunnelState state = form_states_[form.global_id()];
+  const DenseSet<EntityType> relevant_entities =
+      GetRelevantEntityTypesForFields(form.fields());
+  if (relevant_entities.empty()) {
+    return;
+  }
+  std::map<EntityType, FunnelState> states = form_states_[form.global_id()];
   if (submission_state) {
     using enum AutofillAiOptInStatus;
     base::UmaHistogramEnumeration("Autofill.Ai.OptIn.Status",
                                   opt_in_status ? kOptedIn : kOptedOut);
     // TODO(crbug.com/408380915): Remove after M141.
     base::UmaHistogramBoolean("Autofill.Ai.OptInStatus", opt_in_status);
-    ukm_logger_.LogKeyMetrics(
-        ukm_source_id, form, /*data_to_fill_available=*/state.has_data_to_fill,
-        /*suggestions_shown=*/state.suggestions_shown,
-        /*suggestion_filled=*/state.did_fill_suggestions,
-        /*edited_autofilled_field=*/state.edited_autofilled_field,
-        /*opt_in_status=*/opt_in_status);
+
+    const bool has_data_to_fill =
+        std::ranges::any_of(states, [&](const auto& type_and_state) {
+          const auto& [type, state] = type_and_state;
+          return state.has_data_to_fill;
+        });
+    const bool suggestions_shown =
+        std::ranges::any_of(states, [&](const auto& type_and_state) {
+          const auto& [type, state] = type_and_state;
+          return state.suggestions_shown;
+        });
+    const bool did_fill_suggestions =
+        std::ranges::any_of(states, [&](const auto& type_and_state) {
+          const auto& [type, state] = type_and_state;
+          return state.did_fill_suggestions;
+        });
+    const bool edited_autofilled_field =
+        std::ranges::any_of(states, [&](const auto& type_and_state) {
+          const auto& [type, state] = type_and_state;
+          return state.edited_autofilled_field;
+        });
+    ukm_logger_.LogKeyMetrics(ukm_source_id, form, has_data_to_fill,
+                              suggestions_shown, did_fill_suggestions,
+                              edited_autofilled_field, opt_in_status);
     if (opt_in_status) {
-      RecordKeyMetrics(form, state);
+      RecordKeyMetrics(relevant_entities, states);
     }
   }
-  RecordFunnelMetrics(state, submission_state);
-  RecordNumberOfFieldsFilled(form, state, opt_in_status);
+  RecordFunnelMetrics(states, relevant_entities, submission_state);
+  RecordNumberOfFieldsFilled(form, states, opt_in_status);
 }
 
-void AutofillAiLogger::RecordFunnelMetrics(const FunnelState& funnel_state,
-                                           bool submission_state) const {
-  LogFunnelMetric("Eligibility", submission_state, funnel_state.is_eligible);
-  if (!funnel_state.is_eligible) {
-    return;
-  }
-  LogFunnelMetric("ReadinessAfterEligibility", submission_state,
-                  funnel_state.has_data_to_fill);
-  if (!funnel_state.has_data_to_fill) {
-    return;
-  }
-  LogFunnelMetric("FillAfterSuggestion", submission_state,
-                  funnel_state.did_fill_suggestions);
-  if (!funnel_state.did_fill_suggestions) {
-    return;
-  }
-  LogFunnelMetric("CorrectionAfterFill", submission_state,
-                  funnel_state.edited_autofilled_field);
-}
-
-void AutofillAiLogger::RecordKeyMetrics(const FormStructure& form,
-                                        const FunnelState& funnel_state) const {
-  const std::string_view entity_type = [&] {
-    for (const auto& [section, entities_and_fields] :
-         DetermineAttributeTypes(form.fields())) {
-      for (const auto& [entity, fields_and_types] : entities_and_fields) {
-        switch (entity.name()) {
-          case EntityTypeName::kDriversLicense:
-            return "DriversLicense";
-          case EntityTypeName::kNationalIdCard:
-            return "NationalIdCard";
-          case EntityTypeName::kPassport:
-            return "Passport";
-          case EntityTypeName::kVehicle:
-            return "Vehicle";
-        }
-      }
+void AutofillAiLogger::RecordFunnelMetrics(
+    const std::map<EntityType, FunnelState>& states,
+    DenseSet<EntityType> relevant_entities,
+    bool submission_state) const {
+  for (EntityType entity_type : relevant_entities) {
+    const std::string_view type_str = HistogramSuffixForEntityType(entity_type);
+    base::UmaHistogramEnumeration(
+        base::StrCat({"Autofill.Ai.Funnel.",
+                      submission_state ? "Submitted" : "Abandoned",
+                      ".Eligibility2"}),
+        entity_type.name());
+    base::UmaHistogramEnumeration("Autofill.Ai.Funnel.Aggregate.Eligibility2",
+                                  entity_type.name());
+    auto it = states.find(entity_type);
+    if (it == states.end()) {
+      continue;
     }
-    return "";
-  }();
+    const FunnelState& funnel_state = it->second;
+    LogFunnelMetric(base::StrCat({"ReadinessAfterEligibility.", type_str}),
+                    submission_state, funnel_state.has_data_to_fill);
+    if (!funnel_state.has_data_to_fill) {
+      continue;
+    }
+    LogFunnelMetric(base::StrCat({"SuggestionAfterReadiness.", type_str}),
+                    submission_state, funnel_state.suggestions_shown);
+    if (!funnel_state.suggestions_shown) {
+      continue;
+    }
+    LogFunnelMetric(base::StrCat({"FillAfterSuggestion.", type_str}),
+                    submission_state, funnel_state.did_fill_suggestions);
+    if (!funnel_state.did_fill_suggestions) {
+      continue;
+    }
+    LogFunnelMetric(base::StrCat({"CorrectionAfterFill.", type_str}),
+                    submission_state, funnel_state.edited_autofilled_field);
+  }
+}
 
-  LogKeyMetric("FillingReadiness", entity_type, funnel_state.has_data_to_fill);
-  LogKeyMetric("FillingAssistance", entity_type,
-               funnel_state.did_fill_suggestions);
-  if (funnel_state.suggestions_shown) {
-    LogKeyMetric("FillingAcceptance", entity_type,
+void AutofillAiLogger::RecordKeyMetrics(
+    DenseSet<EntityType> relevant_entities,
+    const std::map<EntityType, FunnelState>& states) const {
+  for (EntityType entity_type : relevant_entities) {
+    auto it = states.find(entity_type);
+    if (it == states.end()) {
+      // This means that the form mutated in a way such that it used to have
+      // fields fillable with a certain `EntityType` and it now does not. Those
+      // cases are gracefully ignored and not logged.
+      continue;
+    }
+    const FunnelState& funnel_state = it->second;
+    const std::string_view type_str = HistogramSuffixForEntityType(entity_type);
+    LogKeyMetric("FillingReadiness", type_str, funnel_state.has_data_to_fill);
+    LogKeyMetric("FillingAssistance", type_str,
                  funnel_state.did_fill_suggestions);
-  }
-  if (funnel_state.did_fill_suggestions) {
-    LogKeyMetric("FillingCorrectness", entity_type,
-                 !funnel_state.edited_autofilled_field);
+    if (funnel_state.suggestions_shown) {
+      LogKeyMetric("FillingAcceptance", type_str,
+                   funnel_state.did_fill_suggestions);
+    }
+    if (funnel_state.did_fill_suggestions) {
+      LogKeyMetric("FillingCorrectness", type_str,
+                   !funnel_state.edited_autofilled_field);
+    }
   }
 }
 
-void AutofillAiLogger::RecordNumberOfFieldsFilled(const FormStructure& form,
-                                                  const FunnelState& state,
-                                                  bool opt_in_status) const {
+void AutofillAiLogger::RecordNumberOfFieldsFilled(
+    const FormStructure& form,
+    const std::map<EntityType, FunnelState>& states,
+    bool opt_in_status) const {
   const int num_filled_fields = std::ranges::count_if(
       form, [&](const std::unique_ptr<AutofillField>& field) {
         switch (field->filling_product()) {
@@ -203,6 +268,11 @@
             return false;
         }
       });
+  const bool has_data_to_fill =
+      std::ranges::any_of(states, [&](const auto& type_and_state) {
+        const auto& [type, state] = type_and_state;
+        return state.has_data_to_fill;
+      });
   const int num_autofill_ai_filled_fields = std::ranges::count(
       form, FillingProduct::kAutofillAi, &AutofillField::filling_product);
   const std::string total_opt_in_histogram_name =
@@ -210,7 +280,7 @@
                     opt_in_status ? "OptedIn" : "OptedOut"});
   const std::string total_readiness_histogram_name =
       base::StrCat({"Autofill.Ai.NumberOfFilledFields.Total.",
-                    state.has_data_to_fill ? "HasDataToFill" : "NoDataToFill"});
+                    has_data_to_fill ? "HasDataToFill" : "NoDataToFill"});
   base::UmaHistogramCounts100(total_opt_in_histogram_name, num_filled_fields);
   base::UmaHistogramCounts100(total_readiness_histogram_name,
                               num_filled_fields);
@@ -220,7 +290,7 @@
         "Autofill.Ai.NumberOfFilledFields.AutofillAi.OptedIn",
         num_autofill_ai_filled_fields);
   }
-  if (state.has_data_to_fill) {
+  if (has_data_to_fill) {
     base::UmaHistogramCounts100(
         "Autofill.Ai.NumberOfFilledFields.AutofillAi.HasDataToFill",
         num_autofill_ai_filled_fields);
diff --git a/components/autofill/core/browser/integrators/autofill_ai/metrics/autofill_ai_logger.h b/components/autofill/core/browser/integrators/autofill_ai/metrics/autofill_ai_logger.h
index 24f34096..1d1d4d2 100644
--- a/components/autofill/core/browser/integrators/autofill_ai/metrics/autofill_ai_logger.h
+++ b/components/autofill/core/browser/integrators/autofill_ai/metrics/autofill_ai_logger.h
@@ -8,6 +8,7 @@
 #include <map>
 
 #include "base/memory/raw_ref.h"
+#include "components/autofill/core/browser/data_model/autofill_ai/entity_type.h"
 #include "components/autofill/core/browser/form_structure.h"
 #include "components/autofill/core/browser/integrators/autofill_ai/metrics/autofill_ai_ukm_logger.h"
 #include "components/autofill/core/common/unique_ids.h"
@@ -24,19 +25,24 @@
   AutofillAiLogger& operator=(const AutofillAiLogger&) = delete;
   ~AutofillAiLogger();
 
-  void OnFormEligibilityAvailable(FormGlobalId form_id, bool is_eligible);
-  void OnFormHasDataToFill(FormGlobalId form_id);
+  void OnFormEligibilityAvailable(FormGlobalId form_id,
+                                  DenseSet<EntityType> relevant_entities);
+  void OnFormHasDataToFill(FormGlobalId form_id,
+                           DenseSet<EntityType> entities_to_fill);
   void OnSuggestionsShown(const FormStructure& form,
                           const AutofillField& field,
+                          DenseSet<EntityType> suggested_entity_types,
                           ukm::SourceId ukm_source_id);
   void OnDidFillSuggestion(const FormStructure& form,
                            const AutofillField& field,
+                           EntityType entity_type,
                            ukm::SourceId ukm_source_id);
   void OnEditedAutofilledField(const FormStructure& form,
                                const AutofillField& field,
                                ukm::SourceId ukm_source_id);
   void OnDidFillField(const FormStructure& form,
                       const AutofillField& field,
+                      EntityType entity_type,
                       ukm::SourceId ukm_source_id);
 
   // Function that records the contents of `form_states` for `form` into
@@ -70,17 +76,27 @@
     bool edited_autofilled_field = false;
   };
 
-  void RecordFunnelMetrics(const FunnelState& funnel_state,
+  void RecordFunnelMetrics(const std::map<EntityType, FunnelState>& states,
+                           DenseSet<EntityType> relevant_entities,
                            bool submission_state) const;
-  void RecordKeyMetrics(const FormStructure& form,
-                        const FunnelState& funnel_state) const;
-  void RecordNumberOfFieldsFilled(const FormStructure& form,
-                                  const FunnelState& state,
-                                  bool opt_in_status) const;
+  void RecordKeyMetrics(DenseSet<EntityType> relevant_entities,
+                        const std::map<EntityType, FunnelState>& states) const;
+  void RecordNumberOfFieldsFilled(
+      const FormStructure& form,
+      const std::map<EntityType, FunnelState>& states,
+      bool opt_in_status) const;
 
-  // Records the funnel state of each form. See the documentation of
-  // `FunnelState` for more information about what is recorded.
-  std::map<FormGlobalId, FunnelState> form_states_;
+  // Records the funnel state for each form and entity type separately. See the
+  // documentation of `FunnelState` for more information about what is recorded.
+  std::map<FormGlobalId, std::map<EntityType, FunnelState>> form_states_;
+
+  // Records the last filled `EntityType` for each field. This information is
+  // currently unavailable in `AutofillField`, because
+  // `AutofillField::filling_product_` isn't accurate enough when it comes to
+  // AutofillAi entities, which are all aggregated into
+  // `FillingProduct::kAutofillAi`.
+  // TODO(crbug.com/432650464): Update this state on Undo operations.
+  std::map<FieldGlobalId, EntityType> last_filled_entity_;
 
   AutofillAiUkmLogger ukm_logger_;
 };
diff --git a/components/autofill/core/browser/integrators/autofill_ai/metrics/autofill_ai_logger_unittest.cc b/components/autofill/core/browser/integrators/autofill_ai/metrics/autofill_ai_logger_unittest.cc
index b3da2e05..d92a2c140 100644
--- a/components/autofill/core/browser/integrators/autofill_ai/metrics/autofill_ai_logger_unittest.cc
+++ b/components/autofill/core/browser/integrators/autofill_ai/metrics/autofill_ai_logger_unittest.cc
@@ -5,8 +5,10 @@
 #include "components/autofill/core/browser/integrators/autofill_ai/metrics/autofill_ai_logger.h"
 
 #include <memory>
+#include <optional>
 #include <tuple>
 
+#include "base/notreached.h"
 #include "base/strings/stringprintf.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
@@ -15,6 +17,7 @@
 #include "components/autofill/core/browser/autofill_field.h"
 #include "components/autofill/core/browser/data_manager/autofill_ai/entity_data_manager.h"
 #include "components/autofill/core/browser/data_model/autofill_ai/entity_instance.h"
+#include "components/autofill/core/browser/data_model/autofill_ai/entity_type_names.h"
 #include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/browser/filling/filling_product.h"
 #include "components/autofill/core/browser/form_structure.h"
@@ -48,51 +51,11 @@
 using ::testing::Return;
 using ::testing::ReturnRef;
 
+constexpr auto kVehicle = EntityType(EntityTypeName::kVehicle);
+constexpr auto kDriversLicense = EntityType(EntityTypeName::kDriversLicense);
+constexpr auto kPassport = EntityType(EntityTypeName::kPassport);
+constexpr auto kNationalIdCard = EntityType(EntityTypeName::kNationalIdCard);
 constexpr char kDefaultUrl[] = "https://example.com";
-constexpr char16_t kDefaultPassportNumber[] = u"123";
-constexpr char16_t kDefaultLicensePlate[] = u"XC-12-34";
-
-constexpr char submitted_str[] = "Submitted";
-constexpr char abandoned_str[] = "Abandoned";
-constexpr char eligibility[] = "Autofill.Ai.Funnel.%s.Eligibility";
-constexpr char readiness_after_eligibility[] =
-    "Autofill.Ai.Funnel.%s.ReadinessAfterEligibility";
-constexpr char fill_after_suggestion[] =
-    "Autofill.Ai.Funnel.%s.FillAfterSuggestion";
-constexpr char correction_after_fill[] =
-    "Autofill.Ai.Funnel.%s.CorrectionAfterFill";
-
-std::string GetEligibilityHistogram() {
-  return base::StringPrintf(eligibility, "Aggregate");
-}
-std::string GetEligibilityHistogram(bool submitted) {
-  return base::StringPrintf(eligibility,
-                            submitted ? submitted_str : abandoned_str);
-}
-
-std::string GetReadinessAfterEligibilityHistogram() {
-  return base::StringPrintf(readiness_after_eligibility, "Aggregate");
-}
-std::string GetReadinessAfterEligibilityHistogram(bool submitted) {
-  return base::StringPrintf(readiness_after_eligibility,
-                            submitted ? submitted_str : abandoned_str);
-}
-
-std::string GetFillAfterSuggestionHistogram() {
-  return base::StringPrintf(fill_after_suggestion, "Aggregate");
-}
-std::string GetFillAfterSuggestionHistogram(bool submitted) {
-  return base::StringPrintf(fill_after_suggestion,
-                            submitted ? submitted_str : abandoned_str);
-}
-
-std::string GetCorrectionAfterFillHistogram() {
-  return base::StringPrintf(correction_after_fill, "Aggregate");
-}
-std::string GetCorrectionAfterFillHistogram(bool submitted) {
-  return base::StringPrintf(correction_after_fill,
-                            submitted ? submitted_str : abandoned_str);
-}
 
 class MockAutofillClient : public TestAutofillClient {
  public:
@@ -110,6 +73,10 @@
 class BaseAutofillAiTest : public testing::Test {
  public:
   BaseAutofillAiTest() {
+    scoped_feature_list_.InitWithFeatures(
+        /*enabled_features=*/{features::kAutofillAiWithDataSchema,
+                              features::kAutofillAiNationalIdCard},
+        /*disabled_features=*/{});
     autofill_client().set_entity_data_manager(
         std::make_unique<EntityDataManager>(
             webdata_helper_.autofill_webdata_service(),
@@ -150,51 +117,36 @@
   }
 
   [[nodiscard]] std::unique_ptr<FormStructure> CreatePassportForm(
-      std::u16string passport_number = std::u16string(kDefaultPassportNumber),
       std::string url = std::string(kDefaultUrl)) {
     std::unique_ptr<FormStructure> form = CreateFormStructure(
         {PASSPORT_NAME_TAG, PASSPORT_NUMBER, PHONE_HOME_WHOLE_NUMBER},
         std::move(url));
-    form->field(0)->set_value(u"Jon Doe");
-    form->field(1)->set_value(std::move(passport_number));
     return form;
   }
 
   [[nodiscard]] std::unique_ptr<FormStructure> CreateVehicleForm(
-      std::u16string license_plate = std::u16string(kDefaultLicensePlate),
       std::string url = std::string(kDefaultUrl)) {
     std::unique_ptr<FormStructure> form = CreateFormStructure(
         {VEHICLE_OWNER_TAG, VEHICLE_LICENSE_PLATE}, std::move(url));
-    form->field(0)->set_value(u"Jane Doe");
-    form->field(1)->set_value(std::move(license_plate));
     return form;
   }
 
   [[nodiscard]] std::unique_ptr<FormStructure> CreateDriversLicenseForm(
-      std::u16string passport_number = std::u16string(kDefaultPassportNumber),
       std::string url = std::string(kDefaultUrl)) {
     std::unique_ptr<FormStructure> form =
         CreateFormStructure({DRIVERS_LICENSE_NAME_TAG, DRIVERS_LICENSE_NUMBER,
                              DRIVERS_LICENSE_REGION, DRIVERS_LICENSE_ISSUE_DATE,
                              DRIVERS_LICENSE_EXPIRATION_DATE},
                             std::move(url));
-    form->field(0)->set_value(u"Jon Doe");
-    form->field(1)->set_value(std::move(passport_number));
     return form;
   }
 
-  // A form is made eligible by adding an AutofillAi type prediction.
-  std::unique_ptr<FormStructure> CreateEligibleForm() {
-    FormData form_data;
-    form_data.set_main_frame_origin(
-        url::Origin::Create(GURL("https://myform_root.com/form.html")));
-    auto form = std::make_unique<FormStructure>(form_data);
-    AutofillField& autofill_ai_field = test_api(*form).PushField();
-    AutofillQueryResponse::FormSuggestion::FieldSuggestion::FieldPrediction
-        prediction;
-    prediction.set_type(PASSPORT_NUMBER);
-    autofill_ai_field.set_server_predictions({prediction});
-
+  [[nodiscard]] std::unique_ptr<FormStructure> CreateNationalIdCardForm(
+      std::string url = std::string(kDefaultUrl)) {
+    std::unique_ptr<FormStructure> form = CreateFormStructure(
+        {NATIONAL_ID_CARD_NUMBER, NATIONAL_ID_CARD_ISSUING_COUNTRY,
+         NATIONAL_ID_CARD_ISSUE_DATE, NATIONAL_ID_CARD_EXPIRATION_DATE},
+        std::move(url));
     return form;
   }
 
@@ -211,8 +163,7 @@
   MockAutofillClient& autofill_client() { return autofill_client_; }
 
  private:
-  base::test::ScopedFeatureList scoped_feature_list_{
-      features::kAutofillAiWithDataSchema};
+  base::test::ScopedFeatureList scoped_feature_list_;
   test::AutofillUnitTestEnvironment autofill_test_env_;
   base::test::SingleThreadTaskEnvironment task_environment_;
   NiceMock<MockAutofillClient> autofill_client_;
@@ -262,8 +213,9 @@
 
 // Test that the funnel metrics are logged correctly given different scenarios.
 // This test is parameterized by a boolean representing whether the form was
-// submitted or abandoned, and an integer representing the last stage of the
-// funnel that was reached:
+// submitted or abandoned, an `EntityType` representing the type of funnel we're
+// testing, and an integer representing the last stage of the funnel that was
+// reached:
 //
 // 0) A form was loaded
 // 1) The form was detected eligible for AutofillAi.
@@ -273,16 +225,47 @@
 // 5) The user corrected the filled suggestion.
 class AutofillAiFunnelMetricsTest
     : public BaseAutofillAiTest,
-      public testing::WithParamInterface<std::tuple<bool, int>> {
+      public testing::WithParamInterface<std::tuple<bool, EntityType, int>> {
+  static constexpr char kFunnelUmaMask[] = "Autofill.Ai.Funnel.%s.%s%s";
+
  public:
   AutofillAiFunnelMetricsTest() = default;
 
   bool submitted() { return std::get<0>(GetParam()); }
-  bool is_form_eligible() { return std::get<1>(GetParam()) > 0; }
-  bool user_has_data() { return std::get<1>(GetParam()) > 1; }
-  bool user_saw_suggestions() { return std::get<1>(GetParam()) > 2; }
-  bool user_filled_suggestion() { return std::get<1>(GetParam()) > 3; }
-  bool user_corrected_filling() { return std::get<1>(GetParam()) > 4; }
+  EntityType entity_type() { return std::get<1>(GetParam()); }
+  bool is_form_eligible() { return std::get<2>(GetParam()) > 0; }
+  bool user_has_data() { return std::get<2>(GetParam()) > 1; }
+  bool user_saw_suggestions() { return std::get<2>(GetParam()) > 2; }
+  bool user_filled_suggestion() { return std::get<2>(GetParam()) > 3; }
+  bool user_corrected_filling() { return std::get<2>(GetParam()) > 4; }
+
+  std::unique_ptr<FormStructure> CreateForm() {
+    switch (entity_type().name()) {
+      case EntityTypeName::kPassport:
+        return CreatePassportForm();
+      case EntityTypeName::kDriversLicense:
+        return CreateDriversLicenseForm();
+      case EntityTypeName::kVehicle:
+        return CreateVehicleForm();
+      case EntityTypeName::kNationalIdCard:
+        return CreateNationalIdCardForm();
+    }
+    NOTREACHED();
+  }
+
+  EntityInstance CreateEntity() {
+    switch (entity_type().name()) {
+      case EntityTypeName::kPassport:
+        return test::GetPassportEntityInstance();
+      case EntityTypeName::kDriversLicense:
+        return test::GetDriversLicenseEntityInstance();
+      case EntityTypeName::kVehicle:
+        return test::GetVehicleEntityInstance();
+      case EntityTypeName::kNationalIdCard:
+        return test::GetNationalIdCardEntityInstance();
+    }
+    NOTREACHED();
+  }
 
   void ExpectCorrectFunnelRecording(
       const base::HistogramTester& histogram_tester) {
@@ -298,10 +281,16 @@
 
     // Expect that the aggregate and appropriate submission-specific histograms
     // record the correct values.
-    histogram_tester.ExpectUniqueSample(GetEligibilityHistogram(),
-                                        is_form_eligible(), 1);
-    histogram_tester.ExpectUniqueSample(GetEligibilityHistogram(submitted()),
-                                        is_form_eligible(), 1);
+    if (is_form_eligible()) {
+      histogram_tester.ExpectUniqueSample(GetEligibilityHistogram(),
+                                          entity_type().name(), 1);
+      histogram_tester.ExpectUniqueSample(GetEligibilityHistogram(submitted()),
+                                          entity_type().name(), 1);
+    } else {
+      histogram_tester.ExpectTotalCount(GetEligibilityHistogram(), 0);
+      histogram_tester.ExpectTotalCount(GetEligibilityHistogram(submitted()),
+                                        0);
+    }
 
     if (is_form_eligible()) {
       histogram_tester.ExpectUniqueSample(
@@ -317,6 +306,19 @@
     }
 
     if (user_has_data()) {
+      histogram_tester.ExpectUniqueSample(
+          GetSuggestionAfterReadinessHistogram(), user_saw_suggestions(), 1);
+      histogram_tester.ExpectUniqueSample(
+          GetSuggestionAfterReadinessHistogram(submitted()),
+          user_saw_suggestions(), 1);
+    } else {
+      histogram_tester.ExpectTotalCount(GetSuggestionAfterReadinessHistogram(),
+                                        0);
+      histogram_tester.ExpectTotalCount(
+          GetSuggestionAfterReadinessHistogram(submitted()), 0);
+    }
+
+    if (user_saw_suggestions()) {
       histogram_tester.ExpectUniqueSample(GetFillAfterSuggestionHistogram(),
                                           user_filled_suggestion(), 1);
       histogram_tester.ExpectUniqueSample(
@@ -340,61 +342,93 @@
           GetCorrectionAfterFillHistogram(submitted()), 0);
     }
   }
+
+ private:
+  std::string_view GetEntityTypeAsString() {
+    switch (entity_type().name()) {
+      case EntityTypeName::kPassport:
+        return "Passport";
+      case EntityTypeName::kDriversLicense:
+        return "DriversLicense";
+      case EntityTypeName::kVehicle:
+        return "Vehicle";
+      case EntityTypeName::kNationalIdCard:
+        return "NationalIdCard";
+    }
+    NOTREACHED();
+  }
+
+  std::string GetFunnelHistogram(std::string_view funnel_state,
+                                 std::optional<bool> submitted,
+                                 std::optional<std::string_view> entity_type) {
+    std::string_view submission_state = "Aggregate";
+    if (submitted) {
+      submission_state = *submitted ? "Submitted" : "Abandoned";
+    }
+    return base::StringPrintf(
+        kFunnelUmaMask, submission_state, funnel_state,
+        entity_type ? std::string(".") + std::string(*entity_type) : "");
+  }
+
+  std::string GetEligibilityHistogram(
+      std::optional<bool> submitted = std::nullopt) {
+    return GetFunnelHistogram("Eligibility2", submitted,
+                              /*entity_type=*/std::nullopt);
+  }
+
+  std::string GetReadinessAfterEligibilityHistogram(
+      std::optional<bool> submitted = std::nullopt) {
+    return GetFunnelHistogram("ReadinessAfterEligibility", submitted,
+                              GetEntityTypeAsString());
+  }
+
+  std::string GetSuggestionAfterReadinessHistogram(
+      std::optional<bool> submitted = std::nullopt) {
+    return GetFunnelHistogram("SuggestionAfterReadiness", submitted,
+                              GetEntityTypeAsString());
+  }
+
+  std::string GetFillAfterSuggestionHistogram(
+      std::optional<bool> submitted = std::nullopt) {
+    return GetFunnelHistogram("FillAfterSuggestion", submitted,
+                              GetEntityTypeAsString());
+  }
+
+  std::string GetCorrectionAfterFillHistogram(
+      std::optional<bool> submitted = std::nullopt) {
+    return GetFunnelHistogram("CorrectionAfterFill", submitted,
+                              GetEntityTypeAsString());
+  }
 };
 
 INSTANTIATE_TEST_SUITE_P(AutofillAiTest,
                          AutofillAiFunnelMetricsTest,
                          testing::Combine(testing::Bool(),
+                                          testing::Values(kPassport,
+                                                          kDriversLicense,
+                                                          kVehicle,
+                                                          kNationalIdCard),
                                           testing::Values(0, 1, 2, 3, 4, 5)));
 
-// Tests that appropriate calls in `AutofillAiLogger`
-// result in correct metric logging.
-TEST_P(AutofillAiFunnelMetricsTest, Logger) {
-  std::unique_ptr<FormStructure> form = CreateEligibleForm();
-
-  test_api(manager()).logger().OnFormEligibilityAvailable(form->global_id(),
-                                                          is_form_eligible());
-
-  if (user_has_data()) {
-    test_api(manager()).logger().OnFormHasDataToFill(form->global_id());
-  }
-  if (user_saw_suggestions()) {
-    test_api(manager()).logger().OnSuggestionsShown(*form, *form->field(0),
-                                                    /*ukm_source_id=*/{});
-  }
-  if (user_filled_suggestion()) {
-    test_api(manager()).logger().OnDidFillSuggestion(*form, *form->field(0),
-                                                     /*ukm_source_id=*/{});
-  }
-  if (user_corrected_filling()) {
-    test_api(manager()).logger().OnEditedAutofilledField(*form, *form->field(0),
-                                                         /*ukm_source_id=*/{});
-  }
-
-  base::HistogramTester histogram_tester;
-  test_api(manager()).logger().RecordFormMetrics(
-      *form, /*ukm_source_id=*/{}, submitted(), /*opt_in_status=*/true);
-  ExpectCorrectFunnelRecording(histogram_tester);
-}
-
 // Tests that appropriate calls in `AutofillAiManager`
 // result in correct metric logging.
 TEST_P(AutofillAiFunnelMetricsTest, Manager) {
   // This will dictate whether the form will be eligible for filling or not.
   std::unique_ptr<FormStructure> form =
-      is_form_eligible() ? CreateEligibleForm() : CreateIneligibleForm();
+      is_form_eligible() ? CreateForm() : CreateIneligibleForm();
   // This will dictate whether we consider the form ready to be filled or not.
-  EntityInstance passport = test::GetPassportEntityInstance();
+  EntityInstance entity = CreateEntity();
   if (user_has_data()) {
-    AddOrUpdateEntityInstance(passport);
+    AddOrUpdateEntityInstance(entity);
   }
   manager().OnFormSeen(*form);
 
   if (user_saw_suggestions()) {
-    manager().OnSuggestionsShown(*form, *form->field(0), /*ukm_source_id=*/{});
+    manager().OnSuggestionsShown(*form, *form->field(0), {entity_type()},
+                                 /*ukm_source_id=*/{});
   }
   if (user_filled_suggestion()) {
-    manager().OnDidFillSuggestion(passport.guid(), *form, *form->field(0),
+    manager().OnDidFillSuggestion(entity, *form, *form->field(0),
                                   {form->field(0)},
                                   /*ukm_source_id=*/{});
   }
@@ -417,9 +451,6 @@
     manager().OnFormSeen(*passport_form);
     base::HistogramTester histogram_tester;
     manager().OnFormSubmitted(*passport_form, /*ukm_source_id=*/{});
-
-    histogram_tester.ExpectUniqueSample(
-        "Autofill.Ai.KeyMetrics.FillingReadiness", 0, 1);
     histogram_tester.ExpectUniqueSample(
         "Autofill.Ai.KeyMetrics.FillingReadiness.Passport", 0, 1);
   }
@@ -429,9 +460,6 @@
     manager().OnFormSeen(*passport_form);
     base::HistogramTester histogram_tester;
     manager().OnFormSubmitted(*passport_form, /*ukm_source_id=*/{});
-
-    histogram_tester.ExpectUniqueSample(
-        "Autofill.Ai.KeyMetrics.FillingReadiness", 1, 1);
     histogram_tester.ExpectUniqueSample(
         "Autofill.Ai.KeyMetrics.FillingReadiness.Passport", 1, 1);
   }
@@ -443,23 +471,19 @@
   {
     base::HistogramTester histogram_tester;
     manager().OnFormSubmitted(*vehicle_form, /*ukm_source_id=*/{});
-
-    histogram_tester.ExpectUniqueSample(
-        "Autofill.Ai.KeyMetrics.FillingAssistance", 0, 1);
     histogram_tester.ExpectUniqueSample(
         "Autofill.Ai.KeyMetrics.FillingAssistance.Vehicle", 0, 1);
   }
   {
     manager().OnSuggestionsShown(*vehicle_form, *vehicle_form->field(0),
+                                 {kVehicle},
                                  /*ukm_source_id=*/{});
-    manager().OnDidFillSuggestion(/*guid=*/{}, *vehicle_form,
-                                  *vehicle_form->field(0), /*filled_fields=*/{},
+    manager().OnDidFillSuggestion(test::GetVehicleEntityInstance(),
+                                  *vehicle_form, *vehicle_form->field(0),
+                                  /*filled_fields=*/{},
                                   /*ukm_source_id=*/{});
     base::HistogramTester histogram_tester;
     manager().OnFormSubmitted(*vehicle_form, /*ukm_source_id=*/{});
-
-    histogram_tester.ExpectUniqueSample(
-        "Autofill.Ai.KeyMetrics.FillingAssistance", 1, 1);
     histogram_tester.ExpectUniqueSample(
         "Autofill.Ai.KeyMetrics.FillingAssistance.Vehicle", 1, 1);
   }
@@ -469,28 +493,23 @@
   std::unique_ptr<FormStructure> drivers_license_form =
       CreateDriversLicenseForm();
   manager().OnFormSeen(*drivers_license_form);
-  manager().OnSuggestionsShown(*drivers_license_form,
-                               *drivers_license_form->field(0),
-                               /*ukm_source_id=*/{});
+  manager().OnSuggestionsShown(
+      *drivers_license_form, *drivers_license_form->field(0), {kDriversLicense},
+      /*ukm_source_id=*/{});
   {
     base::HistogramTester histogram_tester;
     manager().OnFormSubmitted(*drivers_license_form, /*ukm_source_id=*/{});
-
-    histogram_tester.ExpectUniqueSample(
-        "Autofill.Ai.KeyMetrics.FillingAcceptance", 0, 1);
     histogram_tester.ExpectUniqueSample(
         "Autofill.Ai.KeyMetrics.FillingAcceptance.DriversLicense", 0, 1);
   }
   {
-    manager().OnDidFillSuggestion(/*guid=*/{}, *drivers_license_form,
+    manager().OnDidFillSuggestion(test::GetDriversLicenseEntityInstance(),
+                                  *drivers_license_form,
                                   *drivers_license_form->field(0),
                                   /*filled_fields=*/{},
                                   /*ukm_source_id=*/{});
     base::HistogramTester histogram_tester;
     manager().OnFormSubmitted(*drivers_license_form, /*ukm_source_id=*/{});
-
-    histogram_tester.ExpectUniqueSample(
-        "Autofill.Ai.KeyMetrics.FillingAcceptance", 1, 1);
     histogram_tester.ExpectUniqueSample(
         "Autofill.Ai.KeyMetrics.FillingAcceptance.DriversLicense", 1, 1);
   }
@@ -500,16 +519,15 @@
   std::unique_ptr<FormStructure> passport_form = CreatePassportForm();
   manager().OnFormSeen(*passport_form);
   manager().OnSuggestionsShown(*passport_form, *passport_form->field(0),
+                               {kPassport},
                                /*ukm_source_id=*/{});
-  manager().OnDidFillSuggestion(/*guid=*/{}, *passport_form,
-                                *passport_form->field(0), /*filled_fields=*/{},
+  manager().OnDidFillSuggestion(test::GetPassportEntityInstance(),
+                                *passport_form, *passport_form->field(0),
+                                /*filled_fields=*/{passport_form->field(0)},
                                 /*ukm_source_id=*/{});
   {
     base::HistogramTester histogram_tester;
     manager().OnFormSubmitted(*passport_form, /*ukm_source_id=*/{});
-
-    histogram_tester.ExpectUniqueSample(
-        "Autofill.Ai.KeyMetrics.FillingCorrectness", 1, 1);
     histogram_tester.ExpectUniqueSample(
         "Autofill.Ai.KeyMetrics.FillingCorrectness.Passport", 1, 1);
   }
@@ -518,9 +536,6 @@
                                       /*ukm_source_id=*/{});
     base::HistogramTester histogram_tester;
     manager().OnFormSubmitted(*passport_form, /*ukm_source_id=*/{});
-
-    histogram_tester.ExpectUniqueSample(
-        "Autofill.Ai.KeyMetrics.FillingCorrectness", 0, 1);
     histogram_tester.ExpectUniqueSample(
         "Autofill.Ai.KeyMetrics.FillingCorrectness.Passport", 0, 1);
   }
@@ -626,9 +641,10 @@
 };
 
 TEST_F(AutofillAiMqlsMetricsTest, FieldEvent) {
-  std::unique_ptr<FormStructure> form = CreateEligibleForm();
+  std::unique_ptr<FormStructure> form = CreatePassportForm();
 
   test_api(manager()).logger().OnSuggestionsShown(*form, *form->field(0),
+                                                  {kPassport},
                                                   /*ukm_source_id=*/{});
   ASSERT_EQ(mqls_logs().size(), 1u);
   ExpectCorrectMqlsFieldEventLogging(
@@ -636,14 +652,16 @@
       AutofillAiUkmLogger::EventType::kSuggestionShown, /*event_order=*/0);
 
   test_api(manager()).logger().OnDidFillSuggestion(*form, *form->field(0),
+                                                   kPassport,
                                                    /*ukm_source_id=*/{});
   ASSERT_EQ(mqls_logs().size(), 2u);
   ExpectCorrectMqlsFieldEventLogging(
       GetLastFieldEventLogs(), *form, *form->field(0),
       AutofillAiUkmLogger::EventType::kSuggestionFilled, /*event_order=*/1);
 
-  test_api(manager()).logger().OnDidFillField(*form, *form->field(0),
-                                              /*ukm_source_id=*/{});
+  test_api(manager()).logger().OnDidFillField(
+      *form, *form->field(0), EntityType(EntityTypeName::kPassport),
+      /*ukm_source_id=*/{});
   ASSERT_EQ(mqls_logs().size(), 3u);
   ExpectCorrectMqlsFieldEventLogging(
       GetLastFieldEventLogs(), *form, *form->field(0),
@@ -661,8 +679,10 @@
 TEST_F(AutofillAiMqlsMetricsTest, KeyMetrics) {
   std::unique_ptr<FormStructure> form = CreatePassportForm();
 
-  test_api(manager()).logger().OnFormHasDataToFill(form->global_id());
-  test_api(manager()).logger().OnSuggestionsShown(*form, *form->field(0),
+  test_api(manager()).logger().OnFormHasDataToFill(form->global_id(),
+                                                   {kPassport});
+  test_api(manager()).logger().OnSuggestionsShown(*form, *form->field(1),
+                                                  {kPassport},
                                                   /*ukm_source_id=*/{});
   form->field(0)->set_is_autofilled(true);
   form->field(0)->set_filling_product(FillingProduct::kAddress);
@@ -671,16 +691,19 @@
   form->field(2)->set_is_autofilled(true);
   form->field(2)->set_filling_product(FillingProduct::kAutocomplete);
 
-  test_api(manager()).logger().OnDidFillSuggestion(*form, *form->field(0),
+  test_api(manager()).logger().OnDidFillSuggestion(*form, *form->field(1),
+                                                   kPassport,
                                                    /*ukm_source_id=*/{});
+  test_api(manager()).logger().OnDidFillField(*form, *form->field(1), kPassport,
+                                              /*ukm_source_id=*/{});
 
-  test_api(manager()).logger().OnEditedAutofilledField(*form, *form->field(0),
+  test_api(manager()).logger().OnEditedAutofilledField(*form, *form->field(1),
                                                        /*ukm_source_id=*/{});
 
   test_api(manager()).logger().RecordFormMetrics(*form, /*ukm_source_id=*/{},
                                                  /*submission_state=*/true,
                                                  /*opt_in_status=*/true);
-  ASSERT_EQ(mqls_logs().size(), 4u);
+  ASSERT_EQ(mqls_logs().size(), 5u);
   const optimization_guide::proto::AutofillAiKeyMetrics& mqls_key_metrics =
       GetKeyMetricsLogs();
 
@@ -700,7 +723,7 @@
 // in for Autofill AI.
 TEST_F(AutofillAiMqlsMetricsTest, KeyMetrics_OptOut) {
   SetAutofillAiOptInStatus(autofill_client(), AutofillAiOptInStatus::kOptedOut);
-  std::unique_ptr<FormStructure> form = CreateEligibleForm();
+  std::unique_ptr<FormStructure> form = CreatePassportForm();
   test_api(manager()).logger().RecordFormMetrics(*form, /*ukm_source_id=*/{},
                                                  /*submission_state=*/true,
                                                  /*opt_in_status=*/false);
@@ -710,7 +733,7 @@
 // Tests that KeyMetrics MQLS metrics aren't recorded if the form was abandoned
 // and not submitted.
 TEST_F(AutofillAiMqlsMetricsTest, KeyMetrics_FormAbandoned) {
-  std::unique_ptr<FormStructure> form = CreateEligibleForm();
+  std::unique_ptr<FormStructure> form = CreatePassportForm();
 
   test_api(manager()).logger().RecordFormMetrics(*form, /*ukm_source_id=*/{},
                                                  /*submission_state=*/false,
@@ -727,8 +750,9 @@
       base::to_underlying(optimization_guide::model_execution::prefs::
                               ModelExecutionEnterprisePolicyValue::kDisable));
 
-  std::unique_ptr<FormStructure> form = CreateEligibleForm();
+  std::unique_ptr<FormStructure> form = CreatePassportForm();
   test_api(manager()).logger().OnSuggestionsShown(*form, *form->field(0),
+                                                  {kPassport},
                                                   /*ukm_source_id=*/{});
   test_api(manager()).logger().RecordFormMetrics(*form, /*ukm_source_id=*/{},
                                                  /*submitted_state=*/true,
@@ -740,8 +764,9 @@
 TEST_F(AutofillAiMqlsMetricsTest, NoMqlsMetricsWhenOffTheRecord) {
   autofill_client().set_is_off_the_record(true);
 
-  std::unique_ptr<FormStructure> form = CreateEligibleForm();
+  std::unique_ptr<FormStructure> form = CreatePassportForm();
   test_api(manager()).logger().OnSuggestionsShown(*form, *form->field(0),
+                                                  {kPassport},
                                                   /*ukm_source_id=*/{});
   test_api(manager()).logger().RecordFormMetrics(*form, /*ukm_source_id=*/{},
                                                  /*submitted_state=*/true,
diff --git a/components/autofill/core/browser/integrators/autofill_ai/mock_autofill_ai_manager.h b/components/autofill/core/browser/integrators/autofill_ai/mock_autofill_ai_manager.h
index 97f179f..65e8c7a 100644
--- a/components/autofill/core/browser/integrators/autofill_ai/mock_autofill_ai_manager.h
+++ b/components/autofill/core/browser/integrators/autofill_ai/mock_autofill_ai_manager.h
@@ -36,12 +36,15 @@
               (const override));
   MOCK_METHOD(void,
               OnSuggestionsShown,
-              (const FormStructure&, const AutofillField&, ukm::SourceId),
+              (const FormStructure&,
+               const AutofillField&,
+               DenseSet<EntityType> suggested_entity_types,
+               ukm::SourceId),
               (override));
   MOCK_METHOD(void, OnFormSeen, (const FormStructure&), (override));
   MOCK_METHOD(void,
               OnDidFillSuggestion,
-              (const base::Uuid& guid,
+              (const EntityInstance&,
                const FormStructure&,
                const AutofillField&,
                base::span<const autofill::AutofillField* const>,
diff --git a/components/autofill/core/browser/payments/bnpl_manager.cc b/components/autofill/core/browser/payments/bnpl_manager.cc
index ada0771b..81960bf2 100644
--- a/components/autofill/core/browser/payments/bnpl_manager.cc
+++ b/components/autofill/core/browser/payments/bnpl_manager.cc
@@ -237,21 +237,12 @@
 void BnplManager::OnIssuerSelected(BnplIssuer selected_issuer) {
   ongoing_flow_state_->issuer = std::move(selected_issuer);
 
-  if (ongoing_flow_state_->issuer.payment_instrument().has_value() &&
-      !AcceptTosActionRequired()) {
+  if (ongoing_flow_state_->issuer.payment_instrument().has_value()) {
     ongoing_flow_state_->instrument_id = base::NumberToString(
         ongoing_flow_state_->issuer.payment_instrument()->instrument_id());
 
     LoadRiskDataForFetchingRedirectUrl();
   } else {
-    GetLegalMessageFromServer();
-  }
-}
-
-void BnplManager::GetLegalMessageFromServer() {
-  if (AcceptTosActionRequired()) {
-    GetDetailsForUpdateBnplPaymentInstrument();
-  } else {
     GetDetailsForCreateBnplPaymentInstrument();
   }
 }
@@ -364,14 +355,13 @@
 void BnplManager::OnRedirectUrlFetched(
     PaymentsAutofillClient::PaymentsRpcResult result,
     const BnplFetchUrlResponseDetails& response) {
-  if (ongoing_flow_state_->issuer.payment_instrument().has_value() &&
-      !AcceptTosActionRequired()) {
-    // If the BNPL issuer selected is linked and doesn't require ToS acceptance,
-    // then the issuer selection dialog must be showing, so close it.
+  if (ongoing_flow_state_->issuer.payment_instrument().has_value()) {
+    // If the BNPL issuer selected is linked, the issuer selection dialog must
+    // be showing, so close it.
     payments_autofill_client().DismissSelectBnplIssuerDialog();
   } else {
-    // If the BNPL issuer selected is not linked, or is linked but requires ToS
-    // acceptance, then the ToS dialog must be showing, so close it.
+    // If the BNPL issuer selected is not linked, the ToS dialog must be
+    // showing, so close it.
     payments_autofill_client().CloseBnplTos();
   }
 
@@ -505,11 +495,7 @@
 
 void BnplManager::OnTosDialogAccepted() {
   if (!ongoing_flow_state_->risk_data.empty()) {
-    if (AcceptTosActionRequired()) {
-      UpdateBnplPaymentInstrument();
-    } else {
-      CreateBnplPaymentInstrument();
-    }
+    CreateBnplPaymentInstrument();
     return;
   }
 
@@ -525,11 +511,7 @@
 void BnplManager::OnRiskDataLoadedAfterTosDialogAcceptance(
     const std::string& risk_data) {
   ongoing_flow_state_->risk_data = risk_data;
-  if (AcceptTosActionRequired()) {
-    UpdateBnplPaymentInstrument();
-  } else {
-    CreateBnplPaymentInstrument();
-  }
+  CreateBnplPaymentInstrument();
 }
 
 void BnplManager::CreateBnplPaymentInstrument() {
@@ -685,11 +667,4 @@
       });
 }
 
-bool BnplManager::AcceptTosActionRequired() const {
-  return ongoing_flow_state_->issuer.payment_instrument().has_value() &&
-         base::Contains(ongoing_flow_state_->issuer.payment_instrument()
-                            ->action_required(),
-                        PaymentInstrument::ActionRequired::kAcceptTos);
-}
-
 }  // namespace autofill::payments
diff --git a/components/autofill/core/browser/payments/bnpl_manager.h b/components/autofill/core/browser/payments/bnpl_manager.h
index 4b524b4..c971e81 100644
--- a/components/autofill/core/browser/payments/bnpl_manager.h
+++ b/components/autofill/core/browser/payments/bnpl_manager.h
@@ -87,10 +87,6 @@
   // 3. The URL being visited is within the BNPL issuer allowlist.
   bool IsEligibleForBnpl() const;
 
-  // Returns true if the issuer for the ongoing flow contains the required
-  // action `PaymentInstrument::ActionRequired::kAcceptTos`.
-  bool AcceptTosActionRequired() const;
-
  private:
   friend class BnplManagerTestApi;
   friend class BnplManagerTest;
@@ -165,10 +161,6 @@
   // or terms of services depending on the issuer.
   void OnIssuerSelected(BnplIssuer selected_issuer);
 
-  // This function makes the appropriate server call to retrieve the ToS legal
-  // message for the issuer.
-  void GetLegalMessageFromServer();
-
   // This function makes the appropriate call to the payments server to get info
   // from the server for creating an instrument for the selected issuer.
   void GetDetailsForCreateBnplPaymentInstrument();
diff --git a/components/autofill/core/browser/payments/bnpl_manager_unittest.cc b/components/autofill/core/browser/payments/bnpl_manager_unittest.cc
index 2c72d53..40299f0 100644
--- a/components/autofill/core/browser/payments/bnpl_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/bnpl_manager_unittest.cc
@@ -151,11 +151,6 @@
 
 class BnplManagerTest : public Test {
  public:
-  using GetDetailsForUpdateBnplPaymentInstrumentRequestDetails::
-      GetDetailsForUpdateBnplPaymentInstrumentType::kGetDetailsForAcceptTos;
-  using UpdateBnplPaymentInstrumentRequestDetails::
-      UpdateBnplPaymentInstrumentType::kAcceptTos;
-
   const int64_t kBillingCustomerNumber = 1234;
   const std::string kRiskData = "RISK_DATA";
   const std::string kInstrumentId = "INSTRUMENT_ID";
@@ -426,94 +421,6 @@
       autofill_client_->GetPaymentsAutofillClient()->risk_data_loaded());
 }
 
-// Tests that the user accepting the ToS dialog for a linked issuer where ToS
-// acceptance is required triggers an UpdatePaymentInstrument request with the
-// loaded risk data, if it is present.
-TEST_F(BnplManagerTest,
-       TosDialogAccepted_PrefetchedRiskDataLoaded_TosAcceptanceRequired) {
-  bnpl_manager_->OnDidAcceptBnplSuggestion(/*final_checkout_amount=*/kAmount,
-                                           base::DoNothing());
-  auto* ongoing_flow_state = test_api(*bnpl_manager_).GetOngoingFlowState();
-  const std::string test_context_token = "test_context_token";
-  BnplIssuer issuer = test::GetTestLinkedBnplIssuer(
-      IssuerId::kBnplKlarna,
-      DenseSet<PaymentInstrument::ActionRequired>{
-          PaymentInstrument::ActionRequired::kAcceptTos});
-  ongoing_flow_state->context_token = test_context_token;
-  ongoing_flow_state->issuer = issuer;
-
-  ASSERT_FALSE(ongoing_flow_state->risk_data.empty());
-
-  autofill_client_->GetPaymentsAutofillClient()->set_risk_data_loaded(false);
-
-  EXPECT_CALL(
-      *payments_network_interface_,
-      UpdateBnplPaymentInstrument(/*request_details=*/
-                                  FieldsAre(
-                                      autofill_client_->GetAppLocale(),
-                                      GetBillingCustomerId(
-                                          autofill_client_
-                                              ->GetPaymentsAutofillClient()
-                                              ->GetPaymentsDataManager()),
-                                      autofill::ConvertToBnplIssuerIdString(
-                                          issuer.issuer_id()),
-                                      /*instrument_id=*/12345,
-                                      test_context_token, /*risk_data=*/_,
-                                      /*type=*/kAcceptTos),
-                                  /*callback=*/_));
-
-  test_api(*bnpl_manager_).OnTosDialogAccepted();
-
-  EXPECT_FALSE(ongoing_flow_state->risk_data.empty());
-
-  // Since risk data was cached, it was directly used, thus loading risk data
-  // was skipped.
-  EXPECT_FALSE(
-      autofill_client_->GetPaymentsAutofillClient()->risk_data_loaded());
-}
-
-// Tests that the the user accepting the ToS dialog for a linked issuer where
-// ToS acceptance is required triggers an UpdatePaymentInstrument request and
-// loads risk data after ToS dialog acceptance if it was not already loaded.
-TEST_F(BnplManagerTest,
-       TosDialogAccepted_PrefetchedRiskDataNotLoaded_TosAcceptanceRequired) {
-  bnpl_manager_->OnDidAcceptBnplSuggestion(/*final_checkout_amount=*/1000000,
-                                           base::DoNothing());
-  auto* ongoing_flow_state = test_api(*bnpl_manager_).GetOngoingFlowState();
-  const std::string test_context_token = "test_context_token";
-  BnplIssuer issuer = test::GetTestLinkedBnplIssuer(
-      IssuerId::kBnplKlarna,
-      DenseSet<PaymentInstrument::ActionRequired>{
-          PaymentInstrument::ActionRequired::kAcceptTos});
-  ongoing_flow_state->context_token = test_context_token;
-  ongoing_flow_state->issuer = issuer;
-  ongoing_flow_state->risk_data.clear();
-
-  ASSERT_TRUE(ongoing_flow_state->risk_data.empty());
-
-  EXPECT_CALL(
-      *payments_network_interface_,
-      UpdateBnplPaymentInstrument(/*request_details=*/
-                                  FieldsAre(
-                                      autofill_client_->GetAppLocale(),
-                                      GetBillingCustomerId(
-                                          autofill_client_
-                                              ->GetPaymentsAutofillClient()
-                                              ->GetPaymentsDataManager()),
-                                      autofill::ConvertToBnplIssuerIdString(
-                                          issuer.issuer_id()),
-                                      issuer.payment_instrument()
-                                          ->instrument_id(),
-                                      test_context_token,
-                                      /*risk_data=*/_, /*type=*/kAcceptTos),
-                                  /*callback=*/_));
-  test_api(*bnpl_manager_).OnTosDialogAccepted();
-
-  EXPECT_FALSE(ongoing_flow_state->risk_data.empty());
-  EXPECT_TRUE(
-      autofill_client_->GetPaymentsAutofillClient()->risk_data_loaded());
-}
-
 // Tests that FetchVcnDetails calls the payments network interface with the
 // request details filled out correctly, and verifies that the VCN is correctly
 // filled and the state of BnplManager is reset.
@@ -963,39 +870,6 @@
             unlinked_issuer);
 }
 
-// Tests that `OnIssuerSelected()` calls with a linked issuer where ToS
-// acceptance is required will call the payments network interface with the
-// request details filled out correctly.
-TEST_F(
-    BnplManagerTest,
-    OnIssuerSelected_CallsGetDetailsForUpdateBnplPaymentInstrument_TosAcceptanceRequired) {
-  bnpl_manager_->OnDidAcceptBnplSuggestion(kAmount, base::DoNothing());
-
-  ASSERT_EQ(test_api(*bnpl_manager_).GetOngoingFlowState()->app_locale,
-            kAppLocale);
-  ASSERT_EQ(
-      test_api(*bnpl_manager_).GetOngoingFlowState()->billing_customer_number,
-      kBillingCustomerNumber);
-
-  BnplIssuer issuer = test::GetTestLinkedBnplIssuer(
-      IssuerId::kBnplKlarna,
-      DenseSet<PaymentInstrument::ActionRequired>{
-          PaymentInstrument::ActionRequired::kAcceptTos});
-
-  EXPECT_CALL(*payments_network_interface_,
-              GetDetailsForUpdateBnplPaymentInstrument(
-                  /*request_details=*/
-                  FieldsAre(kAppLocale, kBillingCustomerNumber,
-                            issuer.payment_instrument()->instrument_id(),
-                            /*type=*/kGetDetailsForAcceptTos),
-                  /*callback=*/_))
-      .Times(1);
-
-  OnIssuerSelected(issuer);
-
-  EXPECT_EQ(test_api(*bnpl_manager_).GetOngoingFlowState()->issuer, issuer);
-}
-
 // Tests that `OnDidGetLegalMessageFromServer` set the BNPL manager state if the
 // request has completed successfully, and shows the ToS dialog. This test also
 // ensures the ToS dialog is closed after receiving a redirect URL for an
@@ -1134,13 +1008,16 @@
   BnplIssuer issuer = test::GetTestLinkedBnplIssuer();
   test_api(*bnpl_manager_).GetOngoingFlowState()->issuer = issuer;
 
-  EXPECT_CALL(*payments_network_interface_,
-              GetDetailsForUpdateBnplPaymentInstrument(
-                  /*request_details=*/
-                  FieldsAre(kAppLocale, kBillingCustomerNumber,
-                            issuer.payment_instrument()->instrument_id(),
-                            /*type=*/kGetDetailsForAcceptTos),
-                  /*callback=*/_));
+  EXPECT_CALL(
+      *payments_network_interface_,
+      GetDetailsForUpdateBnplPaymentInstrument(
+          /*request_details=*/
+          FieldsAre(kAppLocale, kBillingCustomerNumber,
+                    issuer.payment_instrument()->instrument_id(),
+                    GetDetailsForUpdateBnplPaymentInstrumentRequestDetails::
+                        GetDetailsForUpdateBnplPaymentInstrumentType::
+                            kGetDetailsForAcceptTos),
+          /*callback=*/_));
 
   test_api(*bnpl_manager_).GetDetailsForUpdateBnplPaymentInstrument();
 }
@@ -1161,7 +1038,9 @@
           FieldsAre(kAppLocale, kBillingCustomerNumber,
                     autofill::ConvertToBnplIssuerIdString(issuer.issuer_id()),
                     issuer.payment_instrument()->instrument_id(), kContextToken,
-                    kRiskData, /*type=*/kAcceptTos),
+                    kRiskData,
+                    UpdateBnplPaymentInstrumentRequestDetails::
+                        UpdateBnplPaymentInstrumentType::kAcceptTos),
           /*callback=*/_));
 
   test_api(*bnpl_manager_).UpdateBnplPaymentInstrument();
@@ -1724,43 +1603,6 @@
   EXPECT_EQ(test_api(*bnpl_manager_).GetOngoingFlowState(), nullptr);
 }
 
-// Tests that when UpdateBnplPaymentInstrument fails with an error the error
-// dialog is shown and the flow is reset.
-TEST_F(BnplManagerTest, UpdateBnplPaymentInstrument_Failure) {
-  bnpl_manager_->OnDidAcceptBnplSuggestion(kAmount, base::DoNothing());
-  auto* ongoing_flow_state = test_api(*bnpl_manager_).GetOngoingFlowState();
-  ongoing_flow_state->app_locale = kAppLocale;
-  ongoing_flow_state->billing_customer_number = kBillingCustomerNumber;
-  ongoing_flow_state->context_token = kContextToken;
-  ongoing_flow_state->issuer = test::GetTestLinkedBnplIssuer(
-      IssuerId::kBnplKlarna,
-      DenseSet<PaymentInstrument::ActionRequired>{
-          PaymentInstrument::ActionRequired::kAcceptTos});
-  ongoing_flow_state->risk_data = kRiskData;
-
-  EXPECT_CALL(
-      *payments_network_interface_,
-      UpdateBnplPaymentInstrument(
-          FieldsAre(
-              kAppLocale, kBillingCustomerNumber,
-              autofill::ConvertToBnplIssuerIdString(
-                  ongoing_flow_state->issuer.issuer_id()),
-              ongoing_flow_state->issuer.payment_instrument()->instrument_id(),
-              kContextToken, kRiskData,
-              /*type=*/kAcceptTos),
-          _))
-      .WillOnce(base::test::RunOnceCallback<1>(
-          PaymentsAutofillClient::PaymentsRpcResult::kPermanentFailure));
-  EXPECT_CALL(GetPaymentsAutofillClient(), CloseBnplTos);
-
-  test_api(*bnpl_manager_).UpdateBnplPaymentInstrument();
-
-  EXPECT_TRUE(autofill_client_->GetPaymentsAutofillClient()
-                  ->autofill_error_dialog_shown());
-
-  EXPECT_EQ(test_api(*bnpl_manager_).GetOngoingFlowState(), nullptr);
-}
-
 // Tests the sorting logic of `GetSortedBnplIssuerContext` for BNPL Issuers
 // based on their linked status and eligibility. The expected order is:
 // 1. Linked & Eligible
diff --git a/components/autofill/core/browser/suggestions/autofill_ai_suggestion_generator.cc b/components/autofill/core/browser/suggestions/autofill_ai_suggestion_generator.cc
new file mode 100644
index 0000000..d09e698
--- /dev/null
+++ b/components/autofill/core/browser/suggestions/autofill_ai_suggestion_generator.cc
@@ -0,0 +1,130 @@
+// Copyright 2025 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/suggestions/autofill_ai_suggestion_generator.h"
+
+#include "base/containers/to_vector.h"
+#include "components/autofill/core/browser/data_manager/autofill_ai/entity_data_manager.h"
+#include "components/autofill/core/browser/form_structure.h"
+#include "components/autofill/core/browser/integrators/autofill_ai/autofill_ai_suggestions.h"
+#include "components/autofill/core/browser/permissions/autofill_ai/autofill_ai_permission_utils.h"
+
+namespace autofill {
+
+AutofillAiSuggestionGenerator::AutofillAiSuggestionGenerator() = default;
+AutofillAiSuggestionGenerator::~AutofillAiSuggestionGenerator() = default;
+
+void AutofillAiSuggestionGenerator::FetchSuggestionData(
+    const FormData& form_data,
+    const FormFieldData& field_data,
+    const FormStructure* form,
+    const AutofillField* field,
+    const AutofillClient& client,
+    base::OnceCallback<
+        void(std::pair<FillingProduct,
+                       std::vector<SuggestionGenerator::SuggestionData>>)>
+        callback) {
+  FetchSuggestionData(
+      form_data, field_data, form, field, client,
+      [&callback](std::pair<FillingProduct,
+                            std::vector<SuggestionGenerator::SuggestionData>>
+                      suggestion_data) {
+        std::move(callback).Run(std::move(suggestion_data));
+      });
+}
+
+void AutofillAiSuggestionGenerator::GenerateSuggestions(
+    const FormData& form_data,
+    const FormFieldData& field_data,
+    const FormStructure* form,
+    const AutofillField* field,
+    const std::vector<std::pair<FillingProduct, std::vector<SuggestionData>>>&
+        all_suggestion_data,
+    base::OnceCallback<void(ReturnedSuggestions)> callback) {
+  GenerateSuggestions(
+      form_data, field_data, form, field, all_suggestion_data,
+      [&callback](ReturnedSuggestions returned_suggestions) {
+        std::move(callback).Run(std::move(returned_suggestions));
+      });
+}
+
+void AutofillAiSuggestionGenerator::FetchSuggestionData(
+    const FormData& form_data,
+    const FormFieldData& field_data,
+    const FormStructure* form,
+    const AutofillField* field,
+    const AutofillClient& client,
+    base::FunctionRef<
+        void(std::pair<FillingProduct,
+                       std::vector<SuggestionGenerator::SuggestionData>>)>
+        callback) {
+  if (!MayPerformAutofillAiAction(client, AutofillAiAction::kFilling)) {
+    callback({FillingProduct::kAutofillAi, {}});
+    return;
+  }
+
+  const EntityDataManager* entity_manager = client.GetEntityDataManager();
+  if (!entity_manager) {
+    callback({FillingProduct::kAutofillAi, {}});
+    return;
+  }
+  if (!field) {
+    callback({FillingProduct::kAutofillAi, {}});
+    return;
+  }
+
+  base::span<const EntityInstance> entities =
+      entity_manager->GetEntityInstances();
+  if (entities.empty()) {
+    callback({FillingProduct::kAutofillAi, {}});
+    return;
+  }
+  app_locale_ = client.GetAppLocale();
+
+  // Sort entities based on their frecency.
+  std::vector<const EntityInstance*> sorted_entities = base::ToVector(
+      entities, [](const EntityInstance& entity) { return &entity; });
+  std::ranges::sort(sorted_entities,
+                    [comp = EntityInstance::FrecencyOrder(base::Time::Now())](
+                        const EntityInstance* lhs, const EntityInstance* rhs) {
+                      return comp(*lhs, *rhs);
+                    });
+
+  std::vector<SuggestionData> suggestion_data = base::ToVector(
+      std::move(sorted_entities), [](const EntityInstance* entity) {
+        return SuggestionData(std::move(*entity));
+      });
+
+  callback({FillingProduct::kAutofillAi, std::move(suggestion_data)});
+}
+
+void AutofillAiSuggestionGenerator::GenerateSuggestions(
+    const FormData& form_data,
+    const FormFieldData& field_data,
+    const FormStructure* form,
+    const AutofillField* field,
+    const std::vector<std::pair<FillingProduct, std::vector<SuggestionData>>>&
+        all_suggestion_data,
+    base::FunctionRef<void(ReturnedSuggestions)> callback) {
+  if (!form || !field) {
+    callback({FillingProduct::kAutofillAi, {}});
+    return;
+  }
+
+  std::vector<SuggestionData> autofill_ai_suggestion_data =
+      ExtractSuggestionDataForFillingProduct(all_suggestion_data,
+                                             FillingProduct::kAutofillAi);
+
+  std::vector<EntityInstance> entities = base::ToVector(
+      std::move(autofill_ai_suggestion_data),
+      [](SuggestionData& suggestion_data) {
+        return std::get<autofill::EntityInstance>(std::move(suggestion_data));
+      });
+
+  std::vector<Suggestion> suggestions =
+      CreateAutofillAiFillingSuggestions(*form, *field, entities, app_locale_);
+  callback({FillingProduct::kAutofillAi, std::move(suggestions)});
+}
+
+}  // namespace autofill
diff --git a/components/autofill/core/browser/suggestions/autofill_ai_suggestion_generator.h b/components/autofill/core/browser/suggestions/autofill_ai_suggestion_generator.h
new file mode 100644
index 0000000..182b95f
--- /dev/null
+++ b/components/autofill/core/browser/suggestions/autofill_ai_suggestion_generator.h
@@ -0,0 +1,73 @@
+// Copyright 2025 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_SUGGESTIONS_AUTOFILL_AI_SUGGESTION_GENERATOR_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_SUGGESTIONS_AUTOFILL_AI_SUGGESTION_GENERATOR_H_
+
+#include "components/autofill/core/browser/suggestions/suggestion_generator.h"
+
+namespace autofill {
+
+class AutofillAiSuggestionGenerator : public SuggestionGenerator {
+ public:
+  AutofillAiSuggestionGenerator();
+  ~AutofillAiSuggestionGenerator() override;
+
+  void FetchSuggestionData(
+      const FormData& form_data,
+      const FormFieldData& field_data,
+      const FormStructure* form,
+      const AutofillField* field,
+      const AutofillClient& client,
+      base::OnceCallback<
+          void(std::pair<FillingProduct,
+                         std::vector<SuggestionGenerator::SuggestionData>>)>
+          callback) override;
+
+  void GenerateSuggestions(
+      const FormData& form_data,
+      const FormFieldData& field_data,
+      const FormStructure* form,
+      const AutofillField* field,
+      const std::vector<std::pair<FillingProduct, std::vector<SuggestionData>>>&
+          all_suggestion_data,
+      base::OnceCallback<void(ReturnedSuggestions)> callback) override;
+
+  // Like SuggestionGenerator override, but takes a base::FunctionRef instead of
+  // a base::OnceCallback. Calls that callback exactly once.
+  void FetchSuggestionData(
+      const FormData& form_data,
+      const FormFieldData& field_data,
+      const FormStructure* form,
+      const AutofillField* field,
+      const AutofillClient& client,
+      base::FunctionRef<
+          void(std::pair<FillingProduct,
+                         std::vector<SuggestionGenerator::SuggestionData>>)>
+          callback);
+
+  // Like SuggestionGenerator override, but takes a base::FunctionRef instead of
+  // a base::OnceCallback. Calls that callback exactly once.
+  void GenerateSuggestions(
+      const FormData& form_data,
+      const FormFieldData& field_data,
+      const FormStructure* form,
+      const AutofillField* field,
+      const std::vector<std::pair<FillingProduct, std::vector<SuggestionData>>>&
+          all_suggestion_data,
+      base::FunctionRef<void(ReturnedSuggestions)> callback);
+
+  base::WeakPtr<AutofillAiSuggestionGenerator> GetWeakPtr() {
+    return weak_ptr_factory_.GetWeakPtr();
+  }
+
+ private:
+  std::string app_locale_;
+
+  base::WeakPtrFactory<AutofillAiSuggestionGenerator> weak_ptr_factory_{this};
+};
+
+}  // namespace autofill
+
+#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_SUGGESTIONS_AUTOFILL_AI_SUGGESTION_GENERATOR_H_
diff --git a/components/autofill/core/browser/suggestions/autofill_ai_suggestion_generator_unittests.cc b/components/autofill/core/browser/suggestions/autofill_ai_suggestion_generator_unittests.cc
new file mode 100644
index 0000000..e5add04
--- /dev/null
+++ b/components/autofill/core/browser/suggestions/autofill_ai_suggestion_generator_unittests.cc
@@ -0,0 +1,181 @@
+// Copyright 2025 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/suggestions/autofill_ai_suggestion_generator.h"
+
+#include "base/test/mock_callback.h"
+#include "base/test/run_until.h"
+#include "base/test/task_environment.h"
+#include "components/autofill/core/browser/foundations/test_autofill_client.h"
+#include "components/autofill/core/browser/suggestions/suggestion_type.h"
+#include "components/autofill/core/browser/test_utils/autofill_form_test_utils.h"
+#include "components/autofill/core/browser/test_utils/autofill_test_utils.h"
+#include "components/autofill/core/browser/webdata/autofill_ai/entity_table.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace autofill {
+namespace {
+using enum SuggestionType;
+using ::testing::Eq;
+using ::testing::Field;
+using ::testing::IsEmpty;
+
+auto HasType(SuggestionType expected_type) {
+  return Field("Suggestion::type", &Suggestion::type, Eq(expected_type));
+}
+
+class AutofillAiSuggestionGeneratorTest : public testing::Test {
+ protected:
+  AutofillAiSuggestionGeneratorTest() {
+    scoped_feature_list_.InitWithFeatures(
+        /*enabled_features=*/{features::kAutofillAiWithDataSchema,
+                              features::kAutofillAiNoTagTypes,
+                              features::kAutofillAiServerModel},
+        /*disabled_features=*/{});
+    autofill_client_.GetPersonalDataManager().SetPrefService(
+        autofill_client_.GetPrefs());
+    autofill_client_.set_entity_data_manager(
+        std::make_unique<EntityDataManager>(
+            webdata_helper_.autofill_webdata_service(),
+            /*history_service=*/nullptr,
+            /*strike_database=*/nullptr));
+
+    generator_ = std::make_unique<AutofillAiSuggestionGenerator>();
+  }
+
+  TestAutofillClient& client() { return autofill_client_; }
+  base::test::TaskEnvironment& task_environment() { return task_environment_; }
+
+  AutofillAiSuggestionGenerator& generator() { return *generator_; }
+  EntityDataManager& edm() { return *autofill_client_.GetEntityDataManager(); }
+  AutofillWebDataServiceTestHelper& webdata_helper() { return webdata_helper_; }
+
+  void SetForm(const std::vector<FieldType>& field_types) {
+    test::FormDescription form_description;
+    for (FieldType type : field_types) {
+      form_description.fields.emplace_back(
+          test::FieldDescription({.role = type}));
+    }
+    form_structure_.emplace(test::GetFormData(form_description));
+    CHECK_EQ(field_types.size(), form_structure_->field_count());
+    for (size_t i = 0; i < form_structure_->field_count(); i++) {
+      form_structure_->field(i)->set_server_predictions({[&] {
+        FieldPrediction prediction;
+        prediction.set_type(field_types[i]);
+        return prediction;
+      }()});
+    }
+  }
+
+  FormData form() { return form_structure_->ToFormData(); }
+  FormFieldData& field_data() { return *form_structure_->fields()[0]; }
+  FormStructure& form_structure() { return *form_structure_; }
+  AutofillField& field() { return *form_structure_->fields()[0]; }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+  std::unique_ptr<AutofillAiSuggestionGenerator> generator_;
+  base::test::SingleThreadTaskEnvironment task_environment_;
+  test::AutofillUnitTestEnvironment autofill_test_environment_;
+  AutofillWebDataServiceTestHelper webdata_helper_{
+      std::make_unique<EntityTable>()};
+  TestAutofillClient autofill_client_;
+  std::optional<FormStructure> form_structure_;
+};
+
+TEST_F(AutofillAiSuggestionGeneratorTest, GeneratesAutofillAiSuggestions) {
+  client().SetUpPrefsAndIdentityForAutofillAi();
+  SetForm({PASSPORT_NUMBER});
+  edm().AddOrUpdateEntityInstance(test::GetPassportEntityInstance());
+  webdata_helper().WaitUntilIdle();
+
+  base::MockCallback<base::OnceCallback<void(
+      std::pair<FillingProduct,
+                std::vector<SuggestionGenerator::SuggestionData>>)>>
+      suggestion_data_callback;
+  base::MockCallback<
+      base::OnceCallback<void(SuggestionGenerator::ReturnedSuggestions)>>
+      suggestions_generated_callback;
+
+  std::pair<FillingProduct, std::vector<SuggestionGenerator::SuggestionData>>
+      saved_on_suggestion_data_returned_argument;
+  SuggestionGenerator::ReturnedSuggestions
+      saved_on_suggestions_generated_argument;
+
+  EXPECT_CALL(
+      suggestion_data_callback,
+      Run(testing::Pair(FillingProduct::kAutofillAi, testing::SizeIs(1))))
+      .WillOnce(
+          testing::SaveArg<0>(&saved_on_suggestion_data_returned_argument));
+  generator().FetchSuggestionData(form(), field_data(), &form_structure(),
+                                  &field(), client(),
+                                  suggestion_data_callback.Get());
+  EXPECT_TRUE(
+      base::test::RunUntil([&saved_on_suggestion_data_returned_argument]() {
+        return !saved_on_suggestion_data_returned_argument.second.empty();
+      }));
+
+  EXPECT_CALL(suggestions_generated_callback,
+              Run(testing::Pair(
+                  FillingProduct::kAutofillAi,
+                  ElementsAre(HasType(kFillAutofillAi), HasType(kSeparator),
+                              HasType(kManageAutofillAi)))))
+      .WillOnce(testing::SaveArg<0>(&saved_on_suggestions_generated_argument));
+  generator().GenerateSuggestions(form(), field_data(), &form_structure(),
+                                  &field(),
+                                  {saved_on_suggestion_data_returned_argument},
+                                  suggestions_generated_callback.Get());
+  EXPECT_TRUE(
+      base::test::RunUntil([&saved_on_suggestions_generated_argument]() {
+        return !saved_on_suggestions_generated_argument.second.empty();
+      }));
+}
+
+TEST_F(AutofillAiSuggestionGeneratorTest, NoSuggestionsIfNoEntities) {
+  client().SetUpPrefsAndIdentityForAutofillAi();
+  SetForm({PASSPORT_NUMBER});
+
+  base::MockCallback<base::OnceCallback<void(
+      std::pair<FillingProduct,
+                std::vector<SuggestionGenerator::SuggestionData>>)>>
+      suggestion_data_callback;
+  base::MockCallback<
+      base::OnceCallback<void(SuggestionGenerator::ReturnedSuggestions)>>
+      suggestions_generated_callback;
+
+  std::pair<FillingProduct, std::vector<SuggestionGenerator::SuggestionData>>
+      saved_on_suggestion_data_returned_argument;
+  SuggestionGenerator::ReturnedSuggestions
+      saved_on_suggestions_generated_argument;
+
+  EXPECT_CALL(suggestion_data_callback,
+              Run(testing::Pair(FillingProduct::kAutofillAi, IsEmpty())))
+      .WillOnce(
+          testing::SaveArg<0>(&saved_on_suggestion_data_returned_argument));
+  generator().FetchSuggestionData(form(), field_data(), &form_structure(),
+                                  &field(), client(),
+                                  suggestion_data_callback.Get());
+  EXPECT_TRUE(
+      base::test::RunUntil([&saved_on_suggestion_data_returned_argument]() {
+        return saved_on_suggestion_data_returned_argument.first ==
+               FillingProduct::kAutofillAi;
+      }));
+
+  EXPECT_CALL(suggestions_generated_callback,
+              Run(testing::Pair(FillingProduct::kAutofillAi, IsEmpty())))
+      .WillOnce(testing::SaveArg<0>(&saved_on_suggestions_generated_argument));
+  generator().GenerateSuggestions(form(), field_data(), &form_structure(),
+                                  &field(),
+                                  {saved_on_suggestion_data_returned_argument},
+                                  suggestions_generated_callback.Get());
+  EXPECT_TRUE(
+      base::test::RunUntil([&saved_on_suggestions_generated_argument]() {
+        return saved_on_suggestions_generated_argument.first ==
+               FillingProduct::kAutofillAi;
+      }));
+}
+
+}  // namespace
+}  // namespace autofill
diff --git a/components/autofill/core/browser/test_utils/autofill_test_utils.cc b/components/autofill/core/browser/test_utils/autofill_test_utils.cc
index 5dd9d70..5f535be 100644
--- a/components/autofill/core/browser/test_utils/autofill_test_utils.cc
+++ b/components/autofill/core/browser/test_utils/autofill_test_utils.cc
@@ -1024,6 +1024,44 @@
       /*use_date=*/base::Time::FromTimeT(0));
 }
 
+EntityInstance GetNationalIdCardEntityInstance(NationalIdCardOptions options) {
+  using enum AttributeTypeName;
+  std::vector<AttributeInstance> attributes;
+  if (options.number) {
+    attributes.emplace_back(AttributeType(kNationalIdCardNumber));
+    attributes.back().SetInfo(NATIONAL_ID_CARD_NUMBER, options.number,
+                              std::string(options.app_locale),
+                              /*format_string=*/u"",
+                              VerificationStatus::kNoStatus);
+  }
+  if (options.country) {
+    attributes.emplace_back(AttributeType(kNationalIdCardCountry));
+    attributes.back().SetInfo(NATIONAL_ID_CARD_ISSUING_COUNTRY, options.country,
+                              std::string(options.app_locale),
+                              /*format_string=*/u"",
+                              VerificationStatus::kNoStatus);
+  }
+  if (options.issue_date) {
+    attributes.emplace_back(AttributeType(kNationalIdCardIssueDate));
+    attributes.back().SetInfo(NATIONAL_ID_CARD_ISSUE_DATE, options.issue_date,
+                              std::string(options.app_locale),
+                              /*format_string=*/u"",
+                              VerificationStatus::kNoStatus);
+  }
+  if (options.expiry_date) {
+    attributes.emplace_back(AttributeType(kNationalIdCardExpirationDate));
+    attributes.back().SetInfo(
+        NATIONAL_ID_CARD_EXPIRATION_DATE, options.expiry_date,
+        std::string(options.app_locale),
+        /*format_string=*/u"", VerificationStatus::kNoStatus);
+  }
+  return EntityInstance(
+      EntityType(EntityTypeName::kNationalIdCard), std::move(attributes),
+      base::Uuid::ParseLowercase(options.guid), std::string(options.nickname),
+      base::Time::FromTimeT(kJune2017.ToTimeT()), /*use_count=*/0,
+      /*use_date=*/base::Time::FromTimeT(0));
+}
+
 void InitializePossibleTypes(std::vector<FieldTypeSet>& possible_field_types,
                              const std::vector<FieldType>& possible_types) {
   possible_field_types.emplace_back();
@@ -1274,8 +1312,7 @@
     std::string issuer_id,
     std::string currency,
     uint64_t min_price_in_micros,
-    uint64_t max_price_in_micros,
-    std::vector<sync_pb::PaymentInstrument_ActionRequired> actions_required) {
+    uint64_t max_price_in_micros) {
   sync_pb::PaymentInstrument payment_instrument;
   payment_instrument.set_instrument_id(instrument_id);
   payment_instrument.add_supported_rails(
@@ -1290,25 +1327,16 @@
   eligible_price_range->set_min_price_in_micros(min_price_in_micros);
   eligible_price_range->set_max_price_in_micros(max_price_in_micros);
   eligible_price_range->set_currency(std::move(currency));
-
-  for (auto& action_required : actions_required) {
-    payment_instrument.add_action_required(action_required);
-  }
-
   return payment_instrument;
 }
 
-BnplIssuer GetTestLinkedBnplIssuer(
-    autofill::BnplIssuer::IssuerId issuer_id,
-    DenseSet<PaymentInstrument::ActionRequired> actions_required) {
+BnplIssuer GetTestLinkedBnplIssuer(autofill::BnplIssuer::IssuerId issuer_id) {
   std::vector<BnplIssuer::EligiblePriceRange> eligible_price_ranges;
   // Currency: USD, price lower bound: $50, price upper bound: $200.
   eligible_price_ranges.emplace_back(/*currency=*/"USD",
                                      /*price_lower_bound=*/50'000'000,
                                      /*price_upper_bound=*/200'000'000);
-  return BnplIssuer(
-      /*instrument_id=*/12345, issuer_id, std::move(eligible_price_ranges),
-      std::move(actions_required));
+  return BnplIssuer(12345, issuer_id, std::move(eligible_price_ranges));
 }
 
 BnplIssuer GetTestUnlinkedBnplIssuer() {
diff --git a/components/autofill/core/browser/test_utils/autofill_test_utils.h b/components/autofill/core/browser/test_utils/autofill_test_utils.h
index 585193e1..d08bd69 100644
--- a/components/autofill/core/browser/test_utils/autofill_test_utils.h
+++ b/components/autofill/core/browser/test_utils/autofill_test_utils.h
@@ -384,6 +384,21 @@
 
 EntityInstance GetVehicleEntityInstance(VehicleOptions options = {});
 
+template <typename = void>
+struct NationalIdCardOptionsT {
+  const char16_t* number = u"987654321";
+  const char16_t* country = u"United States";
+  const char16_t* issue_date = u"01/12/2020";
+  const char16_t* expiry_date = u"01/12/2030";
+  std::string_view guid = "00000000-0000-4000-8000-200000000000";
+  std::string_view nickname = "IdCard";
+  std::string_view app_locale = "en-US";
+};
+using NationalIdCardOptions = NationalIdCardOptionsT<>;
+
+EntityInstance GetNationalIdCardEntityInstance(
+    NationalIdCardOptions options = {});
+
 // Adds `possible_types` at the end of `possible_field_types`.
 void InitializePossibleTypes(std::vector<FieldTypeSet>& possible_field_types,
                              const std::vector<FieldType>& possible_types);
@@ -488,16 +503,12 @@
     std::string issuer_id,
     std::string currency,
     uint64_t min_price_in_micros,
-    uint64_t max_price_in_micros,
-    std::vector<sync_pb::PaymentInstrument_ActionRequired> actions_required =
-        {});
+    uint64_t max_price_in_micros);
 
 // Returns a linked BNPL issuer with fake data.
 BnplIssuer GetTestLinkedBnplIssuer(
     autofill::BnplIssuer::IssuerId issuer_id =
-        autofill::BnplIssuer::IssuerId::kBnplAffirm,
-    DenseSet<PaymentInstrument::ActionRequired> actions_required =
-        DenseSet<PaymentInstrument::ActionRequired>());
+        autofill::BnplIssuer::IssuerId::kBnplAffirm);
 
 // Returns an unlinked BNPL issuer with fake data.
 BnplIssuer GetTestUnlinkedBnplIssuer();
diff --git a/components/browser_ui/settings/android/java/src/org/chromium/components/browser_ui/settings/SettingsNavigation.java b/components/browser_ui/settings/android/java/src/org/chromium/components/browser_ui/settings/SettingsNavigation.java
index 7af353b..37cdb5aa 100644
--- a/components/browser_ui/settings/android/java/src/org/chromium/components/browser_ui/settings/SettingsNavigation.java
+++ b/components/browser_ui/settings/android/java/src/org/chromium/components/browser_ui/settings/SettingsNavigation.java
@@ -28,7 +28,6 @@
         SettingsFragment.SAFETY_CHECK,
         SettingsFragment.SITE,
         SettingsFragment.ACCESSIBILITY,
-        SettingsFragment.PASSWORDS,
         SettingsFragment.GOOGLE_SERVICES,
         SettingsFragment.MANAGE_SYNC,
         SettingsFragment.FINANCIAL_ACCOUNTS,
@@ -48,16 +47,14 @@
         int SITE = 4;
         /// Accessibility settings.
         int ACCESSIBILITY = 5;
-        /// Password settings.
-        int PASSWORDS = 6;
         /// Google services.
-        int GOOGLE_SERVICES = 7;
+        int GOOGLE_SERVICES = 6;
         /// Manage sync.
-        int MANAGE_SYNC = 8;
+        int MANAGE_SYNC = 7;
         /// Financial accounts.
-        int FINANCIAL_ACCOUNTS = 9;
+        int FINANCIAL_ACCOUNTS = 8;
         /// Non-card payment methods.
-        int NON_CARD_PAYMENT_METHODS = 10;
+        int NON_CARD_PAYMENT_METHODS = 9;
     }
 
     /**
diff --git a/components/browser_ui/site_settings/OWNERS b/components/browser_ui/site_settings/OWNERS
index 3bd31a8..b2d90de 100644
--- a/components/browser_ui/site_settings/OWNERS
+++ b/components/browser_ui/site_settings/OWNERS
@@ -1,4 +1,3 @@
-hkamila@chromium.org
 andypaicu@chromium.org
 dullweber@chromium.org
 tommasin@chromium.org
@@ -7,3 +6,6 @@
 per-file *AutoDarkMetrics.java=file://chrome/browser/ui/android/night_mode/OWNERS
 per-file ...*cookie_settings*=file://components/privacy_sandbox/OWNERS
 per-file ...*Cookie*=file://components/privacy_sandbox/OWNERS
+
+# emeritus:
+# hkamila@chromium.org
\ No newline at end of file
diff --git a/components/cronet/cronet_proxy_delegate.cc b/components/cronet/cronet_proxy_delegate.cc
index f20a0d1..153500e0e 100644
--- a/components/cronet/cronet_proxy_delegate.cc
+++ b/components/cronet/cronet_proxy_delegate.cc
@@ -37,9 +37,11 @@
     for (int i = 0; i < proxy_options_.proxies_size(); ++i) {
       const auto& proxy_server = proxy_options_.proxies(i);
       if (proxy_server.scheme() == cronet::proto::ProxyScheme::DIRECT) {
-        proxy_list.AddProxyChain(
+        auto chain =
             net::ProxyChain::WithOpaqueData(std::vector<net::ProxyServer>(),
-                                            /*opaque_data=*/i));
+                                            /*opaque_data=*/i);
+        CHECK(chain.IsValid());
+        proxy_list.AddProxyChain(std::move(chain));
       } else {
         net::ProxyServer::Scheme scheme =
             net::ProxyServer::Scheme::SCHEME_INVALID;
@@ -53,11 +55,13 @@
           default:
             NOTREACHED();
         }
-        proxy_list.AddProxyChain(net::ProxyChain::WithOpaqueData(
+        auto chain = net::ProxyChain::WithOpaqueData(
             std::vector<net::ProxyServer>{net::ProxyServer(
                 scheme,
                 net::HostPortPair(proxy_server.host(), proxy_server.port()))},
-            /*opaque_data=*/i));
+            /*opaque_data=*/i);
+        CHECK(chain.IsValid());
+        proxy_list.AddProxyChain(std::move(chain));
       }
     }
     result->UseProxyList(proxy_list);
diff --git a/components/gcm_driver/BUILD.gn b/components/gcm_driver/BUILD.gn
index fe33859..c7537d2f 100644
--- a/components/gcm_driver/BUILD.gn
+++ b/components/gcm_driver/BUILD.gn
@@ -66,7 +66,7 @@
     "//net",
     "//services/network/public/cpp",
     "//services/network/public/mojom",
-    "//url:url",
+    "//url",
   ]
 
   # This target goes with these other deps and they can include headers from
@@ -105,7 +105,7 @@
     ]
     deps += [
       "//components/crx_file",
-      "//components/version_info:version_info",
+      "//components/version_info",
       "//google_apis/gcm",
     ]
   }
diff --git a/components/gcm_driver/crypto/proto/BUILD.gn b/components/gcm_driver/crypto/proto/BUILD.gn
index bf6ab433..fa509ade 100644
--- a/components/gcm_driver/crypto/proto/BUILD.gn
+++ b/components/gcm_driver/crypto/proto/BUILD.gn
@@ -6,7 +6,7 @@
 
 proto_library("proto") {
   visibility = [
-    "//components/gcm_driver/crypto:crypto",
+    "//components/gcm_driver/crypto",
     "//components/gcm_driver/crypto:unit_tests",
   ]
 
diff --git a/components/gcm_driver/instance_id/BUILD.gn b/components/gcm_driver/instance_id/BUILD.gn
index f9bfee62f..d9c2b49c 100644
--- a/components/gcm_driver/instance_id/BUILD.gn
+++ b/components/gcm_driver/instance_id/BUILD.gn
@@ -21,8 +21,8 @@
   deps = [
     "//base",
     "//components/gcm_driver:gcm_buildflags",
-    "//components/keyed_service/core:core",
-    "//components/prefs:prefs",
+    "//components/keyed_service/core",
+    "//components/prefs",
     "//crypto",
     "//services/network/public/mojom",
   ]
diff --git a/components/global_media_controls/BUILD.gn b/components/global_media_controls/BUILD.gn
index 43db0c3..3565975 100644
--- a/components/global_media_controls/BUILD.gn
+++ b/components/global_media_controls/BUILD.gn
@@ -44,7 +44,7 @@
   ]
 
   if (is_chromeos) {
-    deps += [ "//chromeos/constants:constants" ]
+    deps += [ "//chromeos/constants" ]
     public += [ "public/views/chapter_item_view.h" ]
   }
 
diff --git a/components/guest_os/BUILD.gn b/components/guest_os/BUILD.gn
index b252403..b9809862 100644
--- a/components/guest_os/BUILD.gn
+++ b/components/guest_os/BUILD.gn
@@ -14,7 +14,7 @@
     "//components/exo",
     "//components/prefs",
     "//components/session_manager/core",
-    "//ui/wm/public:public",
+    "//ui/wm/public",
   ]
   sources = [
     "guest_os_engagement_metrics.cc",
@@ -36,10 +36,10 @@
   deps = [
     ":guest_os",
     ":prefs",
-    "//ash:ash",
+    "//ash",
     "//base/test:test_support",
     "//chromeos/ash/components/dbus/session_manager",
-    "//chromeos/dbus/power:power",
+    "//chromeos/dbus/power",
     "//chromeos/dbus/power:power_manager_proto",
     "//components/prefs:test_support",
     "//components/session_manager/core",
diff --git a/components/heap_profiling/in_process/BUILD.gn b/components/heap_profiling/in_process/BUILD.gn
index d50517b4..cd5a595 100644
--- a/components/heap_profiling/in_process/BUILD.gn
+++ b/components/heap_profiling/in_process/BUILD.gn
@@ -41,7 +41,7 @@
       "//components/metrics",
       "//components/metrics:child_call_stack_profile_builder",
       "//components/sampling_profiler:profile_params",
-      "//components/services/heap_profiling/public/cpp:cpp",
+      "//components/services/heap_profiling/public/cpp",
       "//components/variations",
       "//components/version_info",
       "//mojo/public/cpp/bindings",
diff --git a/components/history/content/browser/BUILD.gn b/components/history/content/browser/BUILD.gn
index 921bfe0..53c049f 100644
--- a/components/history/content/browser/BUILD.gn
+++ b/components/history/content/browser/BUILD.gn
@@ -26,7 +26,7 @@
     "//components/visitedlink/browser",
     "//components/visitedlink/core",
     "//content/public/browser",
-    "//url:url",
+    "//url",
   ]
 }
 
@@ -40,7 +40,7 @@
   deps = [
     ":browser",
     "//base",
-    "//components/history/core/browser:browser",
+    "//components/history/core/browser",
     "//components/history/core/test",
     "//content/test:test_support",
     "//testing/gmock",
diff --git a/components/history/core/test/BUILD.gn b/components/history/core/test/BUILD.gn
index 2c6132bc9..cc5f0462 100644
--- a/components/history/core/test/BUILD.gn
+++ b/components/history/core/test/BUILD.gn
@@ -31,7 +31,7 @@
     "//base",
     "//base/test:test_support",
     "//components/history/core/browser",
-    "//components/sync/protocol:protocol",
+    "//components/sync/protocol",
     "//components/version_info",
     "//net",
     "//services/network/public/cpp",
diff --git a/components/history_clusters/history_clusters_internals/webui/BUILD.gn b/components/history_clusters/history_clusters_internals/webui/BUILD.gn
index 1e8f476..58b6365c 100644
--- a/components/history_clusters/history_clusters_internals/webui/BUILD.gn
+++ b/components/history_clusters/history_clusters_internals/webui/BUILD.gn
@@ -16,7 +16,7 @@
     "//base",
     "//components/history/core/browser",
     "//components/history_clusters/core",
-    "//components/history_clusters/history_clusters_internals/resources:resources",
+    "//components/history_clusters/history_clusters_internals/resources",
     "//components/history_clusters/history_clusters_internals/webui:mojo_bindings",
     "//content/public/browser",
     "//third_party/abseil-cpp:absl",
diff --git a/components/image_fetcher/core/cache/BUILD.gn b/components/image_fetcher/core/cache/BUILD.gn
index 66012a4..acd8c8f 100644
--- a/components/image_fetcher/core/cache/BUILD.gn
+++ b/components/image_fetcher/core/cache/BUILD.gn
@@ -51,6 +51,6 @@
     "//components/leveldb_proto:test_support",
     "//components/prefs:test_support",
     "//testing/gmock",
-    "//testing/gtest:gtest",
+    "//testing/gtest",
   ]
 }
diff --git a/components/infobars/android/BUILD.gn b/components/infobars/android/BUILD.gn
index 062ab722..61ce346 100644
--- a/components/infobars/android/BUILD.gn
+++ b/components/infobars/android/BUILD.gn
@@ -119,7 +119,7 @@
     "//third_party/androidx:androidx_test_monitor_java",
     "//third_party/androidx:androidx_test_rules_java",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
   ]
   resources_package = "org.chromium.components.infobars.test"
 }
diff --git a/components/input/BUILD.gn b/components/input/BUILD.gn
index df9c57b..1066022c 100644
--- a/components/input/BUILD.gn
+++ b/components/input/BUILD.gn
@@ -96,10 +96,10 @@
     "//third_party/blink/public/common:headers",
     "//ui/base",
     "//ui/base/cursor",
-    "//ui/events:events",
+    "//ui/events",
     "//ui/events:events_base",
     "//ui/events:gesture_detection",
-    "//ui/events/blink:blink",
+    "//ui/events/blink",
     "//ui/events/gestures/blink",
   ]
   if (use_aura) {
@@ -190,16 +190,16 @@
   ]
   deps = [
     ":input",
-    "//base:base",
+    "//base",
     "//base/test:test_support",
     "//testing/gtest",
     "//third_party/blink/public/common:headers",
     "//ui/base:features",
+    "//ui/events",
     "//ui/events:dom_keycode_converter",
-    "//ui/events:events",
     "//ui/events:test_support",
     "//ui/events:velocity_tracker",
-    "//ui/events/blink:blink",
+    "//ui/events/blink",
   ]
   if (is_android) {
     sources += [
diff --git a/components/invalidation/BUILD.gn b/components/invalidation/BUILD.gn
index 02d153a..798028a 100644
--- a/components/invalidation/BUILD.gn
+++ b/components/invalidation/BUILD.gn
@@ -41,7 +41,7 @@
 
   deps = [
     "//base",
-    "//components/invalidation:invalidation",
+    "//components/invalidation",
   ]
 }
 
@@ -57,7 +57,7 @@
     "//components/invalidation/impl",
     "//components/sync_preferences:test_support",
     "//google_apis:test_support",
-    "//google_apis/gcm:gcm",
+    "//google_apis/gcm",
     "//testing/gmock",
     "//testing/gtest",
   ]
diff --git a/components/invalidation/impl/BUILD.gn b/components/invalidation/impl/BUILD.gn
index e7ec0379..6c5023a 100644
--- a/components/invalidation/impl/BUILD.gn
+++ b/components/invalidation/impl/BUILD.gn
@@ -57,7 +57,7 @@
     "//components/prefs",
     "//components/signin/public/identity_manager",
     "//google_apis",
-    "//net:net",
+    "//net",
     "//services/network/public/cpp",
     "//services/network/public/mojom",
   ]
@@ -84,7 +84,7 @@
     "//components/prefs:test_support",
     "//components/signin/public/identity_manager:test_support",
     "//google_apis:test_support",
-    "//google_apis/gcm:gcm",
+    "//google_apis/gcm",
     "//net",
     "//net:test_support",
     "//services/data_decoder/public/cpp:test_support",
diff --git a/components/ip_protection/android/BUILD.gn b/components/ip_protection/android/BUILD.gn
index 4a6ad6c..cae802e 100644
--- a/components/ip_protection/android/BUILD.gn
+++ b/components/ip_protection/android/BUILD.gn
@@ -43,7 +43,7 @@
     "//components/ip_protection/common:ip_protection_telemetry",
     "//components/ip_protection/common:ip_protection_token_fetcher",
     "//components/ip_protection/common:ip_protection_token_fetcher_helper",
-    "//content/public/browser:browser",
+    "//content/public/browser",
     "//net/third_party/quiche:blind_sign_auth",
   ]
 }
diff --git a/components/ip_protection/android/android_auth_client_lib/javatests/BUILD.gn b/components/ip_protection/android/android_auth_client_lib/javatests/BUILD.gn
index 4dea02bf..d9580172 100644
--- a/components/ip_protection/android/android_auth_client_lib/javatests/BUILD.gn
+++ b/components/ip_protection/android/android_auth_client_lib/javatests/BUILD.gn
@@ -34,6 +34,6 @@
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/google-truth:google_truth_java",
     "//third_party/jni_zero:jni_zero_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
   ]
 }
diff --git a/components/ip_protection/common/BUILD.gn b/components/ip_protection/common/BUILD.gn
index e942f1b..a5e6359 100644
--- a/components/ip_protection/common/BUILD.gn
+++ b/components/ip_protection/common/BUILD.gn
@@ -391,7 +391,7 @@
     ":ip_protection_data_types",
     ":ip_protection_telemetry",
     ":ip_protection_token_fetcher_helper",
-    "//components/signin/public/identity_manager:identity_manager",
+    "//components/signin/public/identity_manager",
     "//net/third_party/quiche:blind_sign_auth",
   ]
 }
@@ -547,7 +547,7 @@
     "//components/ip_protection/common/flat:masked_domain_list",
     "//testing/gtest",
     "//third_party/flatbuffers",
-    "//url:url",
+    "//url",
   ]
 }
 
diff --git a/components/ip_protection/common/ip_protection_core_impl.cc b/components/ip_protection/common/ip_protection_core_impl.cc
index 609fad6..10fc3a13 100644
--- a/components/ip_protection/common/ip_protection_core_impl.cc
+++ b/components/ip_protection/common/ip_protection_core_impl.cc
@@ -53,8 +53,14 @@
       quic_servers.emplace_back(net::ProxyServer::Scheme::SCHEME_QUIC,
                                 proxy_server.host_port_pair());
     }
-    return net::ProxyChain::ForIpProtection(
+    auto quic_proxy_chain = net::ProxyChain::ForIpProtection(
         std::move(quic_servers), proxy_chain.ip_protection_chain_id());
+    // The proxy chains passed to this function are assumed to be valid (
+    // validated by the `IpProtectionProxyConfigFetcher()` that created them),
+    // so creating a new QUIC proxy chain from those should also result in valid
+    // proxy chains.
+    CHECK(quic_proxy_chain.IsValid());
+    return quic_proxy_chain;
   };
 
   std::vector<net::ProxyChain> quic_proxy_list;
diff --git a/components/ip_protection/common/ip_protection_proxy_config_direct_fetcher.cc b/components/ip_protection/common/ip_protection_proxy_config_direct_fetcher.cc
index 2dfe1b7c..07e05bf 100644
--- a/components/ip_protection/common/ip_protection_proxy_config_direct_fetcher.cc
+++ b/components/ip_protection/common/ip_protection_proxy_config_direct_fetcher.cc
@@ -217,8 +217,13 @@
           chain_id > net::ProxyChain::kMaxIpProtectionChainId) {
         chain_id = net::ProxyChain::kDefaultIpProtectionChainId;
       }
-      proxy_list.push_back(
-          net::ProxyChain::ForIpProtection(std::move(proxies), chain_id));
+      auto chain =
+          net::ProxyChain::ForIpProtection(std::move(proxies), chain_id);
+      // `add_server()` fails if the proxy server is invalid, and `ok` will be
+      // false in that case, so it's safe to assume the chain we create here
+      // will be valid.
+      CHECK(chain.IsValid());
+      proxy_list.push_back(std::move(chain));
     }
   }
 
@@ -251,7 +256,9 @@
     servers.push_back(net::ProxyServer::FromSchemeHostAndPort(
         net::ProxyServer::SCHEME_HTTPS, hostname, std::nullopt));
   }
-  return net::ProxyChain::ForIpProtection(servers, chain_id);
+  auto chain = net::ProxyChain::ForIpProtection(servers, chain_id);
+  CHECK(chain.IsValid());
+  return chain;
 }
 
 IpProtectionProxyConfigDirectFetcher::Retriever::Retriever(
diff --git a/components/ip_protection/common/ip_protection_proxy_config_manager_impl.cc b/components/ip_protection/common/ip_protection_proxy_config_manager_impl.cc
index 42162b42..d3340f3 100644
--- a/components/ip_protection/common/ip_protection_proxy_config_manager_impl.cc
+++ b/components/ip_protection/common/ip_protection_proxy_config_manager_impl.cc
@@ -126,6 +126,12 @@
   // If the request for fetching the proxy list is successful, utilize the new
   // proxy list, otherwise, continue using the existing list, if any.
   if (proxy_list.has_value()) {
+    // The provider of the proxy list should have already validated the proxy
+    // chains, but double-check that here.
+    for (const auto& proxy_chain : *proxy_list) {
+      CHECK(proxy_chain.IsValid());
+      CHECK(proxy_chain.is_for_ip_protection());
+    }
     proxy_list_ = std::move(*proxy_list);
     have_fetched_proxy_list_ = true;
 
diff --git a/components/javascript_dialogs/BUILD.gn b/components/javascript_dialogs/BUILD.gn
index 534780f..c7f0c43 100644
--- a/components/javascript_dialogs/BUILD.gn
+++ b/components/javascript_dialogs/BUILD.gn
@@ -83,6 +83,6 @@
     ":javascript_dialogs",
     "//base",
     "//testing/gtest",
-    "//url:url",
+    "//url",
   ]
 }
diff --git a/components/keyed_service/core/BUILD.gn b/components/keyed_service/core/BUILD.gn
index 37eb66f..3ecedd20 100644
--- a/components/keyed_service/core/BUILD.gn
+++ b/components/keyed_service/core/BUILD.gn
@@ -46,7 +46,7 @@
   deps = [
     "//components/pref_registry",
     "//components/prefs",
-    "//services/tracing/public/cpp:cpp",
+    "//services/tracing/public/cpp",
   ]
 }
 
diff --git a/components/language/android/BUILD.gn b/components/language/android/BUILD.gn
index 7dac612..b9849c9 100644
--- a/components/language/android/BUILD.gn
+++ b/components/language/android/BUILD.gn
@@ -15,7 +15,7 @@
   deps = [
     ":jni_headers",
     "//base",
-    "//components/language/content/browser:browser",
+    "//components/language/content/browser",
   ]
 }
 
diff --git a/components/language/content/browser/BUILD.gn b/components/language/content/browser/BUILD.gn
index 235e1737..ec0adbff 100644
--- a/components/language/content/browser/BUILD.gn
+++ b/components/language/content/browser/BUILD.gn
@@ -22,12 +22,12 @@
   deps = [
     ":language_code_locator",
     "//base",
+    "//components/language/content/browser/ulp_language_code_locator",
     "//components/language/content/browser/ulp_language_code_locator:s2langquadtree",
-    "//components/language/content/browser/ulp_language_code_locator:ulp_language_code_locator",
-    "//components/language/core/browser:browser",
-    "//components/language/core/common:common",
-    "//components/language/core/language_model:language_model",
-    "//components/prefs:prefs",
+    "//components/language/core/browser",
+    "//components/language/core/common",
+    "//components/language/core/language_model",
+    "//components/prefs",
     "//content/public/browser",
     "//net",
     "//services/device/public/cpp/geolocation",
@@ -47,7 +47,7 @@
     ":browser",
     "//base",
     "//base/test:test_support",
-    "//components/language/content/browser/ulp_language_code_locator:ulp_language_code_locator",
+    "//components/language/content/browser/ulp_language_code_locator",
     "//components/language/content/browser/ulp_language_code_locator:unit_tests",
     "//components/language/core/common",
     "//components/prefs:test_support",
diff --git a/components/language/content/browser/ulp_language_code_locator/BUILD.gn b/components/language/content/browser/ulp_language_code_locator/BUILD.gn
index 0b251f4..eafe165 100644
--- a/components/language/content/browser/ulp_language_code_locator/BUILD.gn
+++ b/components/language/content/browser/ulp_language_code_locator/BUILD.gn
@@ -49,7 +49,7 @@
     ":ulp_serialized_to_static_c",
     "//base",
     "//components/language/content/browser:language_code_locator",
-    "//components/prefs:prefs",
+    "//components/prefs",
     "//third_party/s2cellid",
   ]
 }
diff --git a/components/language/core/browser/BUILD.gn b/components/language/core/browser/BUILD.gn
index 77865deb..fa438a9a 100644
--- a/components/language/core/browser/BUILD.gn
+++ b/components/language/core/browser/BUILD.gn
@@ -50,7 +50,7 @@
     ":test_support",
     "//base",
     "//components/language/core/language_model",
-    "//components/pref_registry:pref_registry",
+    "//components/pref_registry",
     "//components/prefs",
     "//components/prefs:test_support",
     "//components/sync_preferences:test_support",
diff --git a/components/language/core/language_model/BUILD.gn b/components/language/core/language_model/BUILD.gn
index a09f457..895eb79f 100644
--- a/components/language/core/language_model/BUILD.gn
+++ b/components/language/core/language_model/BUILD.gn
@@ -32,7 +32,7 @@
     "//components/language/core/browser:test_support",
     "//components/language/core/common",
     "//components/language/core/language_model",
-    "//components/pref_registry:pref_registry",
+    "//components/pref_registry",
     "//components/prefs",
     "//components/prefs:test_support",
     "//components/sync_preferences:test_support",
diff --git a/components/language_detection/content/browser/BUILD.gn b/components/language_detection/content/browser/BUILD.gn
index 1a81fe8..a8411e2 100644
--- a/components/language_detection/content/browser/BUILD.gn
+++ b/components/language_detection/content/browser/BUILD.gn
@@ -12,8 +12,8 @@
 
   deps = [
     "//base",
-    "//components/language_detection/content/common:common",
+    "//components/language_detection/content/common",
     "//components/language_detection/core/browser:language_detection_model_service",
-    "//mojo/public/cpp/bindings:bindings",
+    "//mojo/public/cpp/bindings",
   ]
 }
diff --git a/components/language_detection/core/BUILD.gn b/components/language_detection/core/BUILD.gn
index 1d89239..1c294809 100644
--- a/components/language_detection/core/BUILD.gn
+++ b/components/language_detection/core/BUILD.gn
@@ -77,6 +77,6 @@
     "//base",
     "//base/test:test_support",
     "//components/language_detection/testing",
-    "//components/translate/core/common:common",
+    "//components/translate/core/common",
   ]
 }
diff --git a/components/language_detection/testing/BUILD.gn b/components/language_detection/testing/BUILD.gn
index 4f1ee891..1c570c9 100644
--- a/components/language_detection/testing/BUILD.gn
+++ b/components/language_detection/testing/BUILD.gn
@@ -13,7 +13,7 @@
     ":unit_tests_bundle_data",
     "//base",
     "//base/test:test_support",
-    "//components/language_detection/core:core",
+    "//components/language_detection/core",
   ]
 }
 
diff --git a/components/live_caption/BUILD.gn b/components/live_caption/BUILD.gn
index d271614..9964868 100644
--- a/components/live_caption/BUILD.gn
+++ b/components/live_caption/BUILD.gn
@@ -92,12 +92,12 @@
       "//components/soda:constants",
       "//components/sync_preferences",
       "//content/public/browser",
-      "//google_apis:google_apis",
+      "//google_apis",
       "//media",
       "//media/mojo/mojom",
       "//net",
-      "//services/data_decoder/public/cpp:cpp",
-      "//services/data_decoder/public/mojom:mojom",
+      "//services/data_decoder/public/cpp",
+      "//services/data_decoder/public/mojom",
       "//services/network/public/cpp",
       "//services/network/public/mojom",
       "//ui/native_theme",
@@ -122,10 +122,10 @@
       "//components/prefs",
       "//components/prefs:test_support",
       "//media/mojo/mojom:speech_recognition",
-      "//mojo/public/cpp/bindings:bindings",
+      "//mojo/public/cpp/bindings",
       "//testing/gmock",
       "//testing/gtest",
-      "//ui/gfx/geometry:geometry",
+      "//ui/gfx/geometry",
     ]
 
     if (is_chromeos) {
@@ -182,7 +182,7 @@
     "//components/prefs",
     "//media",
     "//third_party/icu",
-    "//third_party/re2:re2",
+    "//third_party/re2",
     "//ui/base",
     "//ui/native_theme",
   ]
diff --git a/components/local_state/BUILD.gn b/components/local_state/BUILD.gn
index a62721b..681eeb95 100644
--- a/components/local_state/BUILD.gn
+++ b/components/local_state/BUILD.gn
@@ -40,7 +40,7 @@
   deps = [
     ":local_state",
     "//base",
-    "//components/prefs:prefs",
+    "//components/prefs",
     "//components/prefs:test_support",
     "//extensions/buildflags",
     "//testing/gtest",
diff --git a/components/lookalikes/core/BUILD.gn b/components/lookalikes/core/BUILD.gn
index 2790069..0cbdeca 100644
--- a/components/lookalikes/core/BUILD.gn
+++ b/components/lookalikes/core/BUILD.gn
@@ -21,7 +21,7 @@
     ":safety_tips",
     "//base",
     "//components/pref_registry",
-    "//components/prefs:prefs",
+    "//components/prefs",
     "//components/security_interstitials/core",
     "//components/strings",
     "//components/url_formatter",
diff --git a/components/manta/BUILD.gn b/components/manta/BUILD.gn
index 20959ccc..4d49831 100644
--- a/components/manta/BUILD.gn
+++ b/components/manta/BUILD.gn
@@ -29,7 +29,7 @@
   deps = [
     "proto",
     "//base",
-    "//components/account_id:account_id",
+    "//components/account_id",
     "//components/endpoint_fetcher",
     "//components/keyed_service/core",
     "//components/signin/public/identity_manager",
@@ -49,7 +49,7 @@
       "walrus_provider.cc",
       "walrus_provider.h",
     ]
-    deps += [ "//chromeos/constants:constants" ]
+    deps += [ "//chromeos/constants" ]
   }
 }
 
diff --git a/components/media_device_salt/BUILD.gn b/components/media_device_salt/BUILD.gn
index cb6ba0c..25b8e888d 100644
--- a/components/media_device_salt/BUILD.gn
+++ b/components/media_device_salt/BUILD.gn
@@ -14,9 +14,9 @@
 
   deps = [
     "//components/keyed_service/content",
-    "//components/pref_registry:pref_registry",
-    "//components/prefs:prefs",
-    "//components/user_prefs:user_prefs",
+    "//components/pref_registry",
+    "//components/prefs",
+    "//components/user_prefs",
     "//content/public/browser",
     "//sql",
   ]
@@ -36,7 +36,7 @@
     "//components/sync_preferences:test_support",
     "//components/user_prefs",
     "//content/test:test_support",
-    "//sql:sql",
+    "//sql",
     "//testing/gtest/",
   ]
 }
diff --git a/components/media_effects/BUILD.gn b/components/media_effects/BUILD.gn
index 4c31c77..329e3ef6 100644
--- a/components/media_effects/BUILD.gn
+++ b/components/media_effects/BUILD.gn
@@ -7,13 +7,13 @@
 source_set("media_effects") {
   public_deps = [
     "//media/capture/mojom:video_effects_manager",
-    "//services/video_effects/public/mojom:mojom",
+    "//services/video_effects/public/mojom",
   ]
   deps = [
     "//base",
     "//components/keyed_service/content",
     "//components/user_prefs",
-    "//components/viz/host:host",
+    "//components/viz/host",
     "//content/public/browser",
     "//services/audio/public/mojom",
     "//services/video_capture/public/mojom",
diff --git a/components/media_effects/test/BUILD.gn b/components/media_effects/test/BUILD.gn
index e1ae79c1..7244c9d 100644
--- a/components/media_effects/test/BUILD.gn
+++ b/components/media_effects/test/BUILD.gn
@@ -23,7 +23,7 @@
   deps = [
     "//base",
     "//base/test:test_support",
-    "//components/media_effects:media_effects",
+    "//components/media_effects",
     "//content/public/browser",
     "//services/audio/public/cpp:test_support",
     "//services/video_capture/public/cpp:mocks",
diff --git a/components/messages/android/BUILD.gn b/components/messages/android/BUILD.gn
index 3738be1..62e063e 100644
--- a/components/messages/android/BUILD.gn
+++ b/components/messages/android/BUILD.gn
@@ -53,7 +53,7 @@
     "//content/public/test/android:content_java_test_support",
     "//third_party/androidx:androidx_core_core_java",
     "//third_party/androidx:androidx_test_runner_java",
-    "//third_party/junit:junit",
+    "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
   ]
@@ -91,7 +91,7 @@
   deps = [
     ":jni_headers",
     "//content/public/browser",
-    "//ui/android:android",
+    "//ui/android",
   ]
 
   public_deps = [
diff --git a/components/messages/android/test/BUILD.gn b/components/messages/android/test/BUILD.gn
index dfac7b0..619e3785 100644
--- a/components/messages/android/test/BUILD.gn
+++ b/components/messages/android/test/BUILD.gn
@@ -35,7 +35,7 @@
     "messages_test_helper.cc",
     "messages_test_helper.h",
   ]
-  public_deps = [ "//ui/android:android" ]
+  public_deps = [ "//ui/android" ]
   deps = [
     ":jni_headers",
     "//base",
diff --git a/components/metrics/BUILD.gn b/components/metrics/BUILD.gn
index ffe525b..5a84e9a 100644
--- a/components/metrics/BUILD.gn
+++ b/components/metrics/BUILD.gn
@@ -282,7 +282,7 @@
       "//components/prefs",
       "//components/variations",
       "//components/variations/field_trial_config",
-      "//components/version_info:version_info",
+      "//components/version_info",
       "//components/webui/flags:switches",
       "//crypto",
       "//extensions/buildflags",
@@ -442,8 +442,8 @@
 
     deps = [
       "//base",
+      "//components/encrypted_messages",
       "//components/encrypted_messages:encrypted_message_proto",
-      "//components/encrypted_messages:encrypted_messages",
       "//components/variations",
       "//net",
       "//services/network/public/cpp",
@@ -507,7 +507,7 @@
     ]
 
     deps = [
-      "//base:base",
+      "//base",
       "//components/sampling_profiler:profile_params",
       "//third_party/metrics_proto",
     ]
@@ -652,7 +652,7 @@
       "//mojo/public/cpp/bindings",
       "//net:test_support",
       "//services/network:test_support",
-      "//services/network/public/cpp:cpp",
+      "//services/network/public/cpp",
       "//services/service_manager/public/cpp",
       "//testing/gmock",
       "//testing/gtest",
diff --git a/components/metrics/dwa/BUILD.gn b/components/metrics/dwa/BUILD.gn
index c13f35f..80ca4c64 100644
--- a/components/metrics/dwa/BUILD.gn
+++ b/components/metrics/dwa/BUILD.gn
@@ -47,10 +47,10 @@
     "//build:buildflag_header_h",
     "//components/metrics",
     "//components/metrics:metrics_pref_names",
-    "//components/prefs:prefs",
-    "//components/version_info:version_info",
+    "//components/prefs",
+    "//components/version_info",
     "//mojo/public/cpp/bindings",
-    "//net:net",
+    "//net",
   ]
 }
 
@@ -67,7 +67,7 @@
     "//base/test:test_support",
     "//components/metrics",
     "//components/metrics:test_support",
-    "//components/prefs:prefs",
+    "//components/prefs",
     "//components/prefs:test_support",
     "//testing/gmock",
     "//testing/gtest",
diff --git a/components/metrics/structured/BUILD.gn b/components/metrics/structured/BUILD.gn
index 41e0d40..7e0a4ce8 100644
--- a/components/metrics/structured/BUILD.gn
+++ b/components/metrics/structured/BUILD.gn
@@ -294,7 +294,7 @@
     ":structured_metrics_validator",
     "//base",
     "//base/test:test_support",
-    "//components/metrics:metrics",
+    "//components/metrics",
     "//components/metrics/structured/lib",
   ]
 }
diff --git a/components/metrics_services_manager/BUILD.gn b/components/metrics_services_manager/BUILD.gn
index 6848011..213ebe10 100644
--- a/components/metrics_services_manager/BUILD.gn
+++ b/components/metrics_services_manager/BUILD.gn
@@ -17,6 +17,6 @@
     "//components/ukm",
     "//components/variations",
     "//components/variations/service",
-    "//services/network/public/cpp:cpp",
+    "//services/network/public/cpp",
   ]
 }
diff --git a/components/mirroring/browser/BUILD.gn b/components/mirroring/browser/BUILD.gn
index c786e7c0..dbb252e 100644
--- a/components/mirroring/browser/BUILD.gn
+++ b/components/mirroring/browser/BUILD.gn
@@ -17,7 +17,7 @@
 
   deps = [
     "//media/capture",
-    "//media/mojo/common:common",
+    "//media/mojo/common",
     "//media/mojo/mojom:remoting",
     "//mojo/public/cpp/bindings",
   ]
diff --git a/components/mirroring/service/BUILD.gn b/components/mirroring/service/BUILD.gn
index 562bec66..20a2c0bd 100644
--- a/components/mirroring/service/BUILD.gn
+++ b/components/mirroring/service/BUILD.gn
@@ -56,7 +56,7 @@
     "//media/cast/openscreen:remoting_utils",
     "//media/gpu",
     "//media/mojo/clients",
-    "//media/mojo/common:common",
+    "//media/mojo/common",
     "//media/mojo/mojom",
     "//media/mojo/mojom:remoting",
     "//media/remoting:remoting_device_capability",
diff --git a/components/navigation_metrics/BUILD.gn b/components/navigation_metrics/BUILD.gn
index 35630276..b72501e5 100644
--- a/components/navigation_metrics/BUILD.gn
+++ b/components/navigation_metrics/BUILD.gn
@@ -11,9 +11,9 @@
   deps = [
     "//base",
     "//base:i18n",
-    "//components/dom_distiller/core:core",
+    "//components/dom_distiller/core",
     "//components/profile_metrics",
-    "//components/url_formatter:url_formatter",
+    "//components/url_formatter",
     "//url",
   ]
 }
diff --git a/components/network_session_configurator/browser/BUILD.gn b/components/network_session_configurator/browser/BUILD.gn
index dd8e822..8a998be2 100644
--- a/components/network_session_configurator/browser/BUILD.gn
+++ b/components/network_session_configurator/browser/BUILD.gn
@@ -23,7 +23,7 @@
   deps = [
     ":browser",
     "//base/test:test_support",
-    "//components/variations:variations",
+    "//components/variations",
     "//testing/gtest",
   ]
 }
diff --git a/components/network_session_configurator/browser/network_session_configurator.cc b/components/network_session_configurator/browser/network_session_configurator.cc
index 5619ee07..d4b4cfee 100644
--- a/components/network_session_configurator/browser/network_session_configurator.cc
+++ b/components/network_session_configurator/browser/network_session_configurator.cc
@@ -28,6 +28,7 @@
 #include "net/base/features.h"
 #include "net/base/host_mapping_rules.h"
 #include "net/disk_cache/backend_experiment.h"
+#include "net/disk_cache/buildflags.h"
 #include "net/http/http_network_session.h"
 #include "net/http/http_stream_factory.h"
 #include "net/quic/quic_context.h"
@@ -831,13 +832,25 @@
 }
 
 net::URLRequestContextBuilder::HttpCacheParams::Type ChooseCacheType() {
-  if constexpr (disk_cache::IsSimpleBackendEnabledByDefaultPlatform()) {
-    return net::URLRequestContextBuilder::HttpCacheParams::DISK_SIMPLE;
+  if (base::FeatureList::IsEnabled(
+          net::features::kDiskCacheBackendExperiment)) {
+    switch (net::features::kDiskCacheBackendParam.Get()) {
+      case net::features::DiskCacheBackend::kDefault:
+        break;
+      case net::features::DiskCacheBackend::kSimple:
+        return net::URLRequestContextBuilder::HttpCacheParams::DISK_SIMPLE;
+      case net::features::DiskCacheBackend::kBlockfile:
+        return net::URLRequestContextBuilder::HttpCacheParams::DISK_BLOCKFILE;
+#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
+      case net::features::DiskCacheBackend::kSql:
+        return net::URLRequestContextBuilder::HttpCacheParams::
+            DISK_EXPERIMENTAL_SQL;
+#endif  // ENABLE_DISK_CACHE_SQL_BACKEND
+    }
   }
-  if (disk_cache::InSimpleBackendExperimentGroup()) {
-    return net::URLRequestContextBuilder::HttpCacheParams::DISK_SIMPLE;
-  }
-  return net::URLRequestContextBuilder::HttpCacheParams::DISK_BLOCKFILE;
+  return disk_cache::IsSimpleBackendEnabledByDefaultPlatform()
+             ? net::URLRequestContextBuilder::HttpCacheParams::DISK_SIMPLE
+             : net::URLRequestContextBuilder::HttpCacheParams::DISK_BLOCKFILE;
 }
 
 }  // namespace network_session_configurator
diff --git a/components/network_session_configurator/browser/network_session_configurator_unittest.cc b/components/network_session_configurator/browser/network_session_configurator_unittest.cc
index 015f95c5..3edb842f 100644
--- a/components/network_session_configurator/browser/network_session_configurator_unittest.cc
+++ b/components/network_session_configurator/browser/network_session_configurator_unittest.cc
@@ -22,6 +22,7 @@
 #include "net/base/host_mapping_rules.h"
 #include "net/base/host_port_pair.h"
 #include "net/disk_cache/backend_experiment.h"
+#include "net/disk_cache/buildflags.h"
 #include "net/http/http_network_session.h"
 #include "net/http/http_stream_factory.h"
 #include "net/third_party/quiche/src/quiche/http2/core/spdy_protocol.h"
@@ -845,13 +846,11 @@
 }
 
 TEST_F(NetworkSessionConfiguratorTest, DefaultCacheBackend) {
-  if constexpr (disk_cache::IsSimpleBackendEnabledByDefaultPlatform()) {
-    EXPECT_EQ(net::URLRequestContextBuilder::HttpCacheParams::DISK_SIMPLE,
-              ChooseCacheType());
-  } else {
-    EXPECT_EQ(net::URLRequestContextBuilder::HttpCacheParams::DISK_BLOCKFILE,
-              ChooseCacheType());
-  }
+  EXPECT_EQ(
+      disk_cache::IsSimpleBackendEnabledByDefaultPlatform()
+          ? net::URLRequestContextBuilder::HttpCacheParams::DISK_SIMPLE
+          : net::URLRequestContextBuilder::HttpCacheParams::DISK_BLOCKFILE,
+      ChooseCacheType());
 }
 
 TEST_F(NetworkSessionConfiguratorTest, DiskCacheExperimentSimpleBackend) {
@@ -866,13 +865,36 @@
   scoped_feature_list_.Reset();
   scoped_feature_list_.InitAndEnableFeatureWithParameters(
       net::features::kDiskCacheBackendExperiment, {{"backend", "blockfile"}});
-  if constexpr (disk_cache::IsSimpleBackendEnabledByDefaultPlatform()) {
-    EXPECT_EQ(net::URLRequestContextBuilder::HttpCacheParams::DISK_SIMPLE,
-              ChooseCacheType());
-  } else {
-    EXPECT_EQ(net::URLRequestContextBuilder::HttpCacheParams::DISK_BLOCKFILE,
-              ChooseCacheType());
-  }
+  EXPECT_EQ(net::URLRequestContextBuilder::HttpCacheParams::DISK_BLOCKFILE,
+            ChooseCacheType());
+}
+
+TEST_F(NetworkSessionConfiguratorTest, DiskCacheExperimentDefaultBackend) {
+  scoped_feature_list_.Reset();
+  scoped_feature_list_.InitAndEnableFeatureWithParameters(
+      net::features::kDiskCacheBackendExperiment, {{"backend", "default"}});
+  EXPECT_EQ(
+      disk_cache::IsSimpleBackendEnabledByDefaultPlatform()
+          ? net::URLRequestContextBuilder::HttpCacheParams::DISK_SIMPLE
+          : net::URLRequestContextBuilder::HttpCacheParams::DISK_BLOCKFILE,
+      ChooseCacheType());
+}
+
+TEST_F(NetworkSessionConfiguratorTest, DiskCacheExperimentSqlBackend) {
+  scoped_feature_list_.Reset();
+  scoped_feature_list_.InitAndEnableFeatureWithParameters(
+      net::features::kDiskCacheBackendExperiment, {{"backend", "sql"}});
+#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
+  EXPECT_EQ(
+      net::URLRequestContextBuilder::HttpCacheParams::DISK_EXPERIMENTAL_SQL,
+      ChooseCacheType());
+#else   // BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
+  EXPECT_EQ(
+      disk_cache::IsSimpleBackendEnabledByDefaultPlatform()
+          ? net::URLRequestContextBuilder::HttpCacheParams::DISK_SIMPLE
+          : net::URLRequestContextBuilder::HttpCacheParams::DISK_BLOCKFILE,
+      ChooseCacheType());
+#endif  // BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
 }
 
 TEST_F(NetworkSessionConfiguratorTest, Http2GreaseSettingsFromCommandLine) {
diff --git a/components/network_time/BUILD.gn b/components/network_time/BUILD.gn
index 0067c43..f8a339f 100644
--- a/components/network_time/BUILD.gn
+++ b/components/network_time/BUILD.gn
@@ -18,7 +18,7 @@
     "//components/prefs",
     "//components/variations",
     "//net",
-    "//services/network/public/cpp:cpp",
+    "//services/network/public/cpp",
   ]
 }
 
diff --git a/components/no_state_prefetch/browser/BUILD.gn b/components/no_state_prefetch/browser/BUILD.gn
index 89305d6..a080009 100644
--- a/components/no_state_prefetch/browser/BUILD.gn
+++ b/components/no_state_prefetch/browser/BUILD.gn
@@ -40,7 +40,7 @@
     "//components/guest_view/buildflags",
     "//components/no_state_prefetch/common",
     "//components/no_state_prefetch/common:mojo_bindings",
-    "//components/paint_preview/browser:browser",
+    "//components/paint_preview/browser",
     "//content/public/browser",
     "//net",
     "//services/metrics/public/cpp:ukm_builders",
@@ -67,8 +67,8 @@
     "//base/test:test_support",
     "//components/no_state_prefetch/browser",
     "//content/test:test_support",
-    "//google_apis:google_apis",
+    "//google_apis",
     "//testing/gtest",
-    "//url:url",
+    "//url",
   ]
 }
diff --git a/components/no_state_prefetch/common/BUILD.gn b/components/no_state_prefetch/common/BUILD.gn
index ee952fb..24b19f1 100644
--- a/components/no_state_prefetch/common/BUILD.gn
+++ b/components/no_state_prefetch/common/BUILD.gn
@@ -18,7 +18,7 @@
   ]
   deps = [
     ":mojo_bindings",
-    "//content/public/common:common",
+    "//content/public/common",
     "//extensions/buildflags",
     "//ipc",
     "//ipc:message_support",
@@ -51,6 +51,6 @@
     "//components/no_state_prefetch/common",
     "//content/test:test_support",
     "//testing/gtest",
-    "//url:url",
+    "//url",
   ]
 }
diff --git a/components/ntp_tiles/BUILD.gn b/components/ntp_tiles/BUILD.gn
index 93160be5..13aa524 100644
--- a/components/ntp_tiles/BUILD.gn
+++ b/components/ntp_tiles/BUILD.gn
@@ -51,7 +51,7 @@
   public_deps = [
     "//base",
     "//components/history/core/browser",
-    "//components/ntp_tiles/webui/resources:resources",
+    "//components/ntp_tiles/webui/resources",
   ]
   deps = [
     "//build:branding_buildflags",
@@ -69,7 +69,7 @@
     "//components/url_formatter",
     "//components/variations",
     "//components/variations/service",
-    "//components/webapps/common:common",
+    "//components/webapps/common",
     "//extensions/buildflags",
     "//services/data_decoder/public/cpp",
     "//services/network/public/cpp",
@@ -114,11 +114,11 @@
     "//components/history/core/test",
     "//components/image_fetcher/core",
     "//components/image_fetcher/core:test_support",
-    "//components/pref_registry:pref_registry",
-    "//components/prefs:prefs",
+    "//components/pref_registry",
+    "//components/prefs",
     "//components/supervised_user/core/common:buildflags",
     "//components/sync_preferences:test_support",
-    "//components/webapps/common:common",
+    "//components/webapps/common",
     "//extensions/buildflags",
     "//net:test_support",
     "//services/data_decoder/public/cpp:test_support",
diff --git a/components/offline_items_collection/core/BUILD.gn b/components/offline_items_collection/core/BUILD.gn
index 96c8d69..859b219 100644
--- a/components/offline_items_collection/core/BUILD.gn
+++ b/components/offline_items_collection/core/BUILD.gn
@@ -42,7 +42,7 @@
   ]
 
   deps = [
-    "utilities:utilities",
+    "utilities",
     "//ui/gfx/geometry",
   ]
 
diff --git a/components/offline_pages/core/BUILD.gn b/components/offline_pages/core/BUILD.gn
index 83b8e1cf..1d702be 100644
--- a/components/offline_pages/core/BUILD.gn
+++ b/components/offline_pages/core/BUILD.gn
@@ -92,7 +92,7 @@
     "//components/offline_pages/task",
     "//crypto",
     "//net",
-    "//sql:sql",
+    "//sql",
     "//url",
   ]
 }
@@ -125,7 +125,7 @@
     "//base/test:test_support",
     "//components/keyed_service/core",
     "//components/offline_pages/task:test_support",
-    "//sql:sql",
+    "//sql",
     "//testing/gmock",
     "//testing/gtest",
     "//url",
@@ -182,7 +182,7 @@
     "//base",
     "//base/test:test_support",
     "//components/offline_pages/task:test_support",
-    "//sql:sql",
+    "//sql",
     "//sql:test_support",
     "//testing/gmock",
     "//testing/gtest",
diff --git a/components/offline_pages/core/background/BUILD.gn b/components/offline_pages/core/background/BUILD.gn
index 78b9fed..e2ab2ec4 100644
--- a/components/offline_pages/core/background/BUILD.gn
+++ b/components/offline_pages/core/background/BUILD.gn
@@ -71,7 +71,7 @@
     "//components/offline_pages/task",
     "//net",
     "//services/network/public/cpp",
-    "//sql:sql",
+    "//sql",
     "//url",
   ]
 }
@@ -134,7 +134,7 @@
     "//components/offline_pages/core:switches",
     "//services/network:test_support",
     "//services/network/public/cpp",
-    "//sql:sql",
+    "//sql",
     "//sql:test_support",
     "//testing/gmock",
     "//testing/gtest",
diff --git a/components/offline_pages/core/request_header/BUILD.gn b/components/offline_pages/core/request_header/BUILD.gn
index cea57c0..d4b530e 100644
--- a/components/offline_pages/core/request_header/BUILD.gn
+++ b/components/offline_pages/core/request_header/BUILD.gn
@@ -16,7 +16,7 @@
 
   deps = [
     "//base",
-    "//url:url",
+    "//url",
   ]
 }
 
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn
index 49a2f61..985f3e8 100644
--- a/components/omnibox/browser/BUILD.gn
+++ b/components/omnibox/browser/BUILD.gn
@@ -366,7 +366,7 @@
     "//build:branding_buildflags",
     "//components/bookmarks/browser",
     "//components/component_updater",
-    "//components/dom_distiller/core:core",
+    "//components/dom_distiller/core",
     "//components/favicon/core",
     "//components/favicon_base",
     "//components/history_clusters/core",
@@ -509,9 +509,9 @@
   ]
   deps = [
     ":buildflags",
-    "//components/dom_distiller/core:core",
+    "//components/dom_distiller/core",
     "//components/lens/proto/server:proto",
-    "//components/safe_browsing/core/common:common",
+    "//components/safe_browsing/core/common",
     "//components/search_engines",
     "//components/strings",
     "//components/url_formatter",
@@ -669,7 +669,7 @@
       "//components/embedder_support/android:util_java",
       "//components/omnibox/common:features_java",
       "//third_party/android_deps:protobuf_lite_runtime_java",
-      "//third_party/junit:junit",
+      "//third_party/junit",
       "//third_party/metrics_proto:metrics_proto_java",
       "//third_party/mockito:mockito_java",
     ]
@@ -916,24 +916,24 @@
     "//build:blink_buildflags",
     "//components/bookmarks/browser",
     "//components/bookmarks/test",
-    "//components/dom_distiller/core:core",
+    "//components/dom_distiller/core",
     "//components/favicon/core/test:test_support",
     "//components/history/core/test",
     "//components/history_embeddings",
     "//components/history_embeddings:test_support",
     "//components/memory_pressure:test_support",
-    "//components/ntp_tiles:ntp_tiles",
+    "//components/ntp_tiles",
     "//components/omnibox/common",
     "//components/open_from_clipboard:test_support",
     "//components/optimization_guide/core",
     "//components/optimization_guide/core:test_support",
     "//components/optimization_guide/proto:optimization_guide_proto",
     "//components/os_crypt/async/browser",
-    "//components/passage_embeddings:passage_embeddings",
+    "//components/passage_embeddings",
     "//components/passage_embeddings:test_support",
     "//components/prefs:test_support",
-    "//components/query_parser:query_parser",
-    "//components/safe_browsing/core/common:common",
+    "//components/query_parser",
+    "//components/safe_browsing/core/common",
     "//components/saved_tab_groups/test_support",
     "//components/search",
     "//components/search_engines",
@@ -946,7 +946,7 @@
     "//components/url_formatter",
     "//components/variations",
     "//components/variations:test_support",
-    "//components/variations/net:net",
+    "//components/variations/net",
     "//extensions/buildflags",
     "//services/metrics/public/cpp:ukm_builders",
     "//services/network:test_support",
@@ -976,7 +976,7 @@
   }
 
   if (is_chromeos) {
-    deps += [ "//chromeos/constants:constants" ]
+    deps += [ "//chromeos/constants" ]
   }
 
   if (enable_extensions) {
@@ -999,7 +999,7 @@
     ":test_support",
     "//base",
     "//base:i18n",
-    "//third_party/metrics_proto:metrics_proto",
+    "//third_party/metrics_proto",
   ]
 }
 
@@ -1019,7 +1019,7 @@
     "//base",
     "//base:i18n",
     "//third_party/icu:icui18n",
-    "//third_party/metrics_proto:metrics_proto",
+    "//third_party/metrics_proto",
   ]
   seed_corpus = "fuzz_corpus_suggest"
 }
diff --git a/components/omnibox/common/BUILD.gn b/components/omnibox/common/BUILD.gn
index 37d4e8be..6105c9c 100644
--- a/components/omnibox/common/BUILD.gn
+++ b/components/omnibox/common/BUILD.gn
@@ -17,7 +17,7 @@
   deps = [
     "//base",
     "//base:i18n",
-    "//components/url_formatter:url_formatter",
+    "//components/url_formatter",
     "//ui/base:features",
     "//url",
   ]
diff --git a/components/omnibox/composebox/BUILD.gn b/components/omnibox/composebox/BUILD.gn
index 6778bc1a..bb8517b 100644
--- a/components/omnibox/composebox/BUILD.gn
+++ b/components/omnibox/composebox/BUILD.gn
@@ -20,11 +20,11 @@
   ]
   deps = [
     ":mojo_bindings",
-    "//base:base",
+    "//base",
     "//components/endpoint_fetcher",
     "//components/lens",
     "//components/search",
-    "//components/search_engines:search_engines",
+    "//components/search_engines",
     "//components/signin/public/base",
     "//components/signin/public/identity_manager",
     "//components/variations",
@@ -66,7 +66,7 @@
     "//components/lens",
     "//components/variations",
     "//google_apis/common",
-    "//services/network/public/cpp:cpp",
+    "//services/network/public/cpp",
     "//third_party/lens_server_proto:lens_overlay_proto",
   ]
 }
diff --git a/components/open_from_clipboard/BUILD.gn b/components/open_from_clipboard/BUILD.gn
index e65fc9d..c94ac1d77 100644
--- a/components/open_from_clipboard/BUILD.gn
+++ b/components/open_from_clipboard/BUILD.gn
@@ -13,7 +13,7 @@
     "//base",
     "//components/variations",
     "//net",
-    "//ui/base:base",
+    "//ui/base",
     "//url",
   ]
 
@@ -68,7 +68,7 @@
   deps = [
     ":open_from_clipboard",
     "//base",
-    "//ui/gfx:gfx",
+    "//ui/gfx",
     "//url",
   ]
 }
diff --git a/components/optimization_guide/content/renderer/BUILD.gn b/components/optimization_guide/content/renderer/BUILD.gn
index 4b9a8b02..5edfaf3a 100644
--- a/components/optimization_guide/content/renderer/BUILD.gn
+++ b/components/optimization_guide/content/renderer/BUILD.gn
@@ -13,7 +13,7 @@
     "//components/optimization_guide/content/mojom:mojo_interfaces",
     "//content/public/renderer",
     "//third_party/blink/public:blink_headers",
-    "//third_party/blink/public/common:common",
+    "//third_party/blink/public/common",
   ]
 
   configs += [ "//build/config/compiler:wexit_time_destructors" ]
diff --git a/components/optimization_guide/internal b/components/optimization_guide/internal
index dd2a475..34545b5 160000
--- a/components/optimization_guide/internal
+++ b/components/optimization_guide/internal
@@ -1 +1 @@
-Subproject commit dd2a4751e727af7bf8fb5baa1fb52e070f354c17
+Subproject commit 34545b579229b4993a3f0ea5a1046b34e305a2aa
diff --git a/components/optimization_guide/optimization_guide_internals/webui/BUILD.gn b/components/optimization_guide/optimization_guide_internals/webui/BUILD.gn
index 4672c5a..14ff7bd6 100644
--- a/components/optimization_guide/optimization_guide_internals/webui/BUILD.gn
+++ b/components/optimization_guide/optimization_guide_internals/webui/BUILD.gn
@@ -23,7 +23,7 @@
   public_deps = [
     ":mojo_bindings",
     ":url_constants",
-    "//components/optimization_guide/optimization_guide_internals/resources:resources",
+    "//components/optimization_guide/optimization_guide_internals/resources",
   ]
   configs += [ "//build/config/compiler:wexit_time_destructors" ]
 }
diff --git a/components/optimization_guide/proto/BUILD.gn b/components/optimization_guide/proto/BUILD.gn
index d57147c..a85ceb3 100644
--- a/components/optimization_guide/proto/BUILD.gn
+++ b/components/optimization_guide/proto/BUILD.gn
@@ -82,7 +82,7 @@
 
   # These are required to import system_profile.proto in
   # model_quality_metadata.proto.
-  deps = [ "//third_party/metrics_proto:metrics_proto" ]
+  deps = [ "//third_party/metrics_proto" ]
   import_dirs = [ "//third_party/metrics_proto/" ]
 }
 
@@ -106,7 +106,7 @@
   sources = [ "features/feature_proto_registry.proto" ]
   deps = [
     ":optimization_guide_proto",
-    "//third_party/metrics_proto:metrics_proto",
+    "//third_party/metrics_proto",
   ]
   generate_cc = false
   generate_python = false
diff --git a/components/origin_trials/BUILD.gn b/components/origin_trials/BUILD.gn
index 723bbf4d..954ed0b 100644
--- a/components/origin_trials/BUILD.gn
+++ b/components/origin_trials/BUILD.gn
@@ -22,7 +22,7 @@
     "//content/public/browser",
     "//net",
     "//third_party/blink/public/common:headers",
-    "//url:url",
+    "//url",
   ]
 }
 
@@ -36,7 +36,7 @@
     "//base",
     "//content/public/common",
     "//third_party/blink/public/common:headers",
-    "//url:url",
+    "//url",
   ]
 }
 
@@ -55,7 +55,7 @@
     ":common",
     ":db_trial_token",
     "//base",
-    "//url:url",
+    "//url",
   ]
 }
 
@@ -76,14 +76,14 @@
     "//base/test:test_support",
     "//components/leveldb_proto:test_support",
     "//components/sync_preferences:test_support",
-    "//components/user_prefs:user_prefs",
+    "//components/user_prefs",
     "//content/public/browser",
     "//content/public/common",
     "//content/test:test_support",
     "//testing/gmock",
     "//testing/gtest",
     "//third_party/blink/public:test_headers",
-    "//url:url",
+    "//url",
   ]
 
   # TODO(crbug.com/40031409): Fix code that adds exit-time destructors and
diff --git a/components/permissions/PERMISSIONS_OWNERS b/components/permissions/PERMISSIONS_OWNERS
index 3d92024..e321fbf 100644
--- a/components/permissions/PERMISSIONS_OWNERS
+++ b/components/permissions/PERMISSIONS_OWNERS
@@ -3,6 +3,8 @@
 elklm@chromium.org
 engedy@chromium.org
 fjacky@chromium.org
-hkamila@chromium.org
 ravjit@chromium.org
 tungnh@chromium.org
+
+# emeritus:
+# hkamila@chromium.org
\ No newline at end of file
diff --git a/components/policy/core/browser/cloud/user_policy_signin_service_base.cc b/components/policy/core/browser/cloud/user_policy_signin_service_base.cc
index 8374c9a..fef5105 100644
--- a/components/policy/core/browser/cloud/user_policy_signin_service_base.cc
+++ b/components/policy/core/browser/cloud/user_policy_signin_service_base.cc
@@ -23,22 +23,29 @@
 #include "components/signin/public/identity_manager/account_info.h"
 #include "components/signin/public/identity_manager/account_managed_status_finder.h"
 
+#if BUILDFLAG(IS_ANDROID)
+#include "base/android/build_info.h"
+#endif
+
 namespace em = enterprise_management;
 
 namespace policy {
 
 namespace {
 
+em::DeviceRegisterRequest::Type GetCloudPolicyRegistrationType() {
 #if BUILDFLAG(IS_ANDROID)
-const em::DeviceRegisterRequest::Type kCloudPolicyRegistrationType =
-    em::DeviceRegisterRequest::ANDROID_BROWSER;
+  if (base::android::BuildInfo::GetInstance()->is_desktop()) {
+    return em::DeviceRegisterRequest::BROWSER;
+  } else {
+    return em::DeviceRegisterRequest::ANDROID_BROWSER;
+  }
 #elif BUILDFLAG(IS_IOS)
-const em::DeviceRegisterRequest::Type kCloudPolicyRegistrationType =
-    em::DeviceRegisterRequest::IOS_BROWSER;
+  return em::DeviceRegisterRequest::IOS_BROWSER;
 #else
-const em::DeviceRegisterRequest::Type kCloudPolicyRegistrationType =
-    em::DeviceRegisterRequest::BROWSER;
+  return em::DeviceRegisterRequest::BROWSER;
 #endif
+}
 
 }  // namespace
 
@@ -310,7 +317,7 @@
   // `RegisterForPolicyWithAccountId()`, if any.
   registration_helper_for_temporary_client_ =
       std::make_unique<CloudPolicyClientRegistrationHelper>(
-          policy_client.get(), kCloudPolicyRegistrationType);
+          policy_client.get(), GetCloudPolicyRegistrationType());
 
   // Using a raw pointer to |this| is okay, because the service owns
   // |registration_helper_for_temporary_client_|.
@@ -344,7 +351,7 @@
   // Start the process of registering the CloudPolicyClient. Once it completes,
   // policy fetch will automatically happen.
   registration_helper_ = std::make_unique<CloudPolicyClientRegistrationHelper>(
-      policy_manager()->core()->client(), kCloudPolicyRegistrationType);
+      policy_manager()->core()->client(), GetCloudPolicyRegistrationType());
   registration_helper_->StartRegistration(
       identity_manager(),
       identity_manager()->GetPrimaryAccountId(signin::ConsentLevel::kSignin),
diff --git a/components/policy/core/common/cloud/affiliation_unittest.cc b/components/policy/core/common/cloud/affiliation_unittest.cc
index c15b65e6..939ec6e 100644
--- a/components/policy/core/common/cloud/affiliation_unittest.cc
+++ b/components/policy/core/common/cloud/affiliation_unittest.cc
@@ -113,7 +113,7 @@
 
   policy::MockUserCloudPolicyStore store;
   policy::CloudPolicyCore core(
-      policy::dm_protocol::kChromeUserPolicyType, std::string(), &store,
+      policy::dm_protocol::GetChromeUserPolicyType(), std::string(), &store,
       base::SingleThreadTaskRunner::GetCurrentDefault(),
       network::TestNetworkConnectionTracker::CreateGetter());
 
@@ -137,7 +137,7 @@
 
   policy::MockUserCloudPolicyStore store;
   policy::CloudPolicyCore core(
-      policy::dm_protocol::kChromeUserPolicyType, std::string(), &store,
+      policy::dm_protocol::GetChromeUserPolicyType(), std::string(), &store,
       base::SingleThreadTaskRunner::GetCurrentDefault(),
       network::TestNetworkConnectionTracker::CreateGetter());
 
@@ -161,7 +161,7 @@
 
   policy::MockUserCloudPolicyStore store;
   policy::CloudPolicyCore core(
-      policy::dm_protocol::kChromeUserPolicyType, std::string(), &store,
+      policy::dm_protocol::GetChromeUserPolicyType(), std::string(), &store,
       base::SingleThreadTaskRunner::GetCurrentDefault(),
       network::TestNetworkConnectionTracker::CreateGetter());
 
@@ -182,7 +182,7 @@
 
   policy::MockUserCloudPolicyStore store;
   policy::CloudPolicyCore core(
-      policy::dm_protocol::kChromeUserPolicyType, std::string(), &store,
+      policy::dm_protocol::GetChromeUserPolicyType(), std::string(), &store,
       base::SingleThreadTaskRunner::GetCurrentDefault(),
       network::TestNetworkConnectionTracker::CreateGetter());
 
diff --git a/components/policy/core/common/cloud/cloud_policy_client.cc b/components/policy/core/common/cloud/cloud_policy_client.cc
index 8d373a7..a43b6a6c 100644
--- a/components/policy/core/common/cloud/cloud_policy_client.cc
+++ b/components/policy/core/common/cloud/cloud_policy_client.cc
@@ -93,7 +93,7 @@
 
 bool IsChromePolicy(const std::string& type) {
   return type == dm_protocol::kChromeDevicePolicyType ||
-         type == dm_protocol::kChromeUserPolicyType ||
+         type == dm_protocol::GetChromeUserPolicyType() ||
          IsMachineLevelUserCloudPolicyType(type);
 }
 
@@ -275,7 +275,7 @@
 // Returns the histogram variant for the corresponding `type`. Returns nullopt
 // if there is no variant for the type.
 std::optional<std::string_view> HistogramVariantForType(std::string_view type) {
-  if (type == dm_protocol::kChromeUserPolicyType) {
+  if (type == dm_protocol::GetChromeUserPolicyType()) {
     return "UserPolicy";
   } else if (type == dm_protocol::kChromeMachineLevelUserCloudPolicyType) {
     return "MachineLevelUserCloudPolicy";
diff --git a/components/policy/core/common/cloud/cloud_policy_client_unittest.cc b/components/policy/core/common/cloud/cloud_policy_client_unittest.cc
index dc8f9dcd..12c23d31 100644
--- a/components/policy/core/common/cloud/cloud_policy_client_unittest.cc
+++ b/components/policy/core/common/cloud/cloud_policy_client_unittest.cc
@@ -183,7 +183,7 @@
 
 std::string CreatePolicyData(const std::string& policy_value) {
   em::PolicyData policy_data;
-  policy_data.set_policy_type(dm_protocol::kChromeUserPolicyType);
+  policy_data.set_policy_type(dm_protocol::GetChromeUserPolicyType());
   policy_data.set_policy_value(policy_value);
   return policy_data.SerializeAsString();
 }
@@ -193,7 +193,7 @@
 
   em::PolicyFetchRequest* policy_fetch_request =
       policy_request.mutable_policy_request()->add_requests();
-  policy_fetch_request->set_policy_type(dm_protocol::kChromeUserPolicyType);
+  policy_fetch_request->set_policy_type(dm_protocol::GetChromeUserPolicyType());
   policy_fetch_request->set_signature_type(em::PolicyFetchRequest::SHA256_RSA);
   policy_fetch_request->set_verification_key_hash(kPolicyVerificationKeyHash);
   policy_fetch_request->set_device_dm_token(kDeviceDMToken);
@@ -462,7 +462,7 @@
       : task_environment_(std::move(task_env)),
         job_type_(DeviceManagementService::JobConfiguration::TYPE_INVALID),
         client_id_(kClientID),
-        policy_type_(dm_protocol::kChromeUserPolicyType) {
+        policy_type_(dm_protocol::GetChromeUserPolicyType()) {
 #if BUILDFLAG(IS_CHROMEOS)
     fake_statistics_provider_.SetMachineStatistic(ash::system::kSerialNumberKey,
                                                   "fake_serial_number");
@@ -1765,7 +1765,7 @@
       expected_requests;
   // Expected user policy fetch request.
   std::pair<std::string, std::string> user_policy_key(
-      dm_protocol::kChromeUserPolicyType, std::string());
+      dm_protocol::GetChromeUserPolicyType(), std::string());
   expected_requests[user_policy_key] =
       GetPolicyRequest().policy_request().requests(0);
   // Expected user cloud policy fetch request.
@@ -1905,8 +1905,8 @@
       ResponseMap;
   ResponseMap expected_responses;
   std::set<std::pair<std::string, std::string>> expected_namespaces;
-  std::pair<std::string, std::string> key(dm_protocol::kChromeUserPolicyType,
-                                          std::string());
+  std::pair<std::string, std::string> key(
+      dm_protocol::GetChromeUserPolicyType(), std::string());
   // Copy the user policy fetch request.
   expected_responses[key].CopyFrom(
       policy_response.policy_response().responses(0));
diff --git a/components/policy/core/common/cloud/cloud_policy_constants.cc b/components/policy/core/common/cloud/cloud_policy_constants.cc
index 9003393..52f1b3f 100644
--- a/components/policy/core/common/cloud/cloud_policy_constants.cc
+++ b/components/policy/core/common/cloud/cloud_policy_constants.cc
@@ -10,6 +10,10 @@
 #include "build/build_config.h"
 #include "components/policy/core/common/policy_switches.h"
 
+#if BUILDFLAG(IS_ANDROID)
+#include "base/android/build_info.h"
+#endif
+
 namespace policy {
 
 // Constants related to the device management protocol.
@@ -84,16 +88,8 @@
 const char kValueRequestDeterminePromotionEligibility[] =
     "promotion_eligibility";
 
+// User policy type is determined in GetChromeUserPolicyType.
 const char kChromeDevicePolicyType[] = "google/chromeos/device";
-#if BUILDFLAG(IS_CHROMEOS)
-const char kChromeUserPolicyType[] = "google/chromeos/user";
-#elif BUILDFLAG(IS_ANDROID)
-const char kChromeUserPolicyType[] = "google/android/user";
-#elif BUILDFLAG(IS_IOS)
-const char kChromeUserPolicyType[] = "google/ios/user";
-#else
-const char kChromeUserPolicyType[] = "google/chrome/user";
-#endif
 const char kChromePublicAccountPolicyType[] = "google/chromeos/publicaccount";
 const char kChromeExtensionPolicyType[] = "google/chrome/extension";
 const char kChromeSigninExtensionPolicyType[] =
@@ -132,6 +128,22 @@
 const char kChromeMachineLevelUserCloudPolicyTypeBase64[] =
     "Z29vZ2xlL2Nocm9tZS9tYWNoaW5lLWxldmVsLXVzZXI=";
 
+const char* GetChromeUserPolicyType() {
+#if BUILDFLAG(IS_CHROMEOS)
+  return "google/chromeos/user";
+#elif BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_desktop()) {
+    return "google/chrome/user";
+  } else {
+    return "google/android/user";
+  }
+#elif BUILDFLAG(IS_IOS)
+  return "google/ios/user";
+#else
+  return "google/chrome/user";
+#endif
+}
+
 }  // namespace dm_protocol
 
 const uint8_t kPolicyVerificationKey[] = {
diff --git a/components/policy/core/common/cloud/cloud_policy_constants.h b/components/policy/core/common/cloud/cloud_policy_constants.h
index 06722faa..6b837e3 100644
--- a/components/policy/core/common/cloud/cloud_policy_constants.h
+++ b/components/policy/core/common/cloud/cloud_policy_constants.h
@@ -80,7 +80,6 @@
 
 // Policy type strings for the policy_type field in PolicyFetchRequest.
 extern const char kChromeDevicePolicyType[];
-extern const char kChromeUserPolicyType[];
 extern const char kChromePublicAccountPolicyType[];
 extern const char kChromeExtensionPolicyType[];
 extern const char kChromeSigninExtensionPolicyType[];
@@ -108,6 +107,9 @@
   POLICY_FETCH_ERROR_NOT_FOUND = 902,
 };
 
+// Chrome managed-user's policy type when fetching user policy from DM server.
+const char* GetChromeUserPolicyType();
+
 }  // namespace dm_protocol
 
 // Public half of the verification key that is used to verify that policy
diff --git a/components/policy/core/common/cloud/cloud_policy_core_unittest.cc b/components/policy/core/common/cloud/cloud_policy_core_unittest.cc
index 3501b17..430eade 100644
--- a/components/policy/core/common/cloud/cloud_policy_core_unittest.cc
+++ b/components/policy/core/common/cloud/cloud_policy_core_unittest.cc
@@ -42,7 +42,7 @@
  protected:
   CloudPolicyCoreTest() {
     core_ = std::make_unique<CloudPolicyCore>(
-        dm_protocol::kChromeUserPolicyType, std::string(), &store_,
+        dm_protocol::GetChromeUserPolicyType(), std::string(), &store_,
         base::SingleThreadTaskRunner::GetCurrentDefault(),
         network::TestNetworkConnectionTracker::CreateGetter());
     prefs_.registry()->RegisterIntegerPref(
diff --git a/components/policy/core/common/cloud/cloud_policy_manager_unittest.cc b/components/policy/core/common/cloud/cloud_policy_manager_unittest.cc
index c48dadf..9855248 100644
--- a/components/policy/core/common/cloud/cloud_policy_manager_unittest.cc
+++ b/components/policy/core/common/cloud/cloud_policy_manager_unittest.cc
@@ -92,7 +92,7 @@
   store_ = store.get();
   store_->NotifyStoreLoaded();
   ConfigurationPolicyProvider* provider = new CloudPolicyManager(
-      dm_protocol::kChromeUserPolicyType, std::string(), std::move(store),
+      dm_protocol::GetChromeUserPolicyType(), std::string(), std::move(store),
       task_runner, network::TestNetworkConnectionTracker::CreateGetter());
   Mock::VerifyAndClearExpectations(store_.get());
   return provider;
@@ -164,7 +164,7 @@
 
  protected:
   CloudPolicyManagerTest()
-      : policy_type_(dm_protocol::kChromeUserPolicyType) {}
+      : policy_type_(dm_protocol::GetChromeUserPolicyType()) {}
 
   void SetUp() override {
     // Set up a policy map for testing.
diff --git a/components/policy/core/common/cloud/cloud_policy_refresh_scheduler_unittest.cc b/components/policy/core/common/cloud/cloud_policy_refresh_scheduler_unittest.cc
index dfc53e0..374e04c9 100644
--- a/components/policy/core/common/cloud/cloud_policy_refresh_scheduler_unittest.cc
+++ b/components/policy/core/common/cloud/cloud_policy_refresh_scheduler_unittest.cc
@@ -265,7 +265,7 @@
 
 TEST_F(CloudPolicyRefreshSchedulerTest, InitialRefreshManagedAlreadyFetched) {
   SetLastUpdateToNow();
-  client_.SetPolicy(dm_protocol::kChromeUserPolicyType, std::string(),
+  client_.SetPolicy(dm_protocol::GetChromeUserPolicyType(), std::string(),
                     em::PolicyFetchResponse());
   auto scheduler = base::WrapUnique(CreateRefreshScheduler());
   CheckTiming(scheduler.get(), kPolicyRefreshRate);
@@ -311,7 +311,7 @@
 
   // The refresh scheduled for soon is not overridden by the notification on the
   // already fetched policy.
-  client_.SetPolicy(dm_protocol::kChromeUserPolicyType, std::string(),
+  client_.SetPolicy(dm_protocol::GetChromeUserPolicyType(), std::string(),
                     em::PolicyFetchResponse());
   store_.NotifyStoreLoaded();
   CheckTiming(scheduler.get(), 0);
@@ -481,7 +481,7 @@
 TEST_F(CloudPolicyRefreshSchedulerTest, OnConnectionChangedAfterSleep) {
   auto scheduler = base::WrapUnique(CreateRefreshScheduler());
 
-  client_.SetPolicy(dm_protocol::kChromeUserPolicyType, std::string(),
+  client_.SetPolicy(dm_protocol::GetChromeUserPolicyType(), std::string(),
                     em::PolicyFetchResponse());
   task_runner_->RunPendingTasks();
   EXPECT_FALSE(task_runner_->HasPendingTask());
diff --git a/components/policy/core/common/cloud/cloud_policy_service.cc b/components/policy/core/common/cloud/cloud_policy_service.cc
index 5e80300..06b85fd 100644
--- a/components/policy/core/common/cloud/cloud_policy_service.cc
+++ b/components/policy/core/common/cloud/cloud_policy_service.cc
@@ -110,7 +110,7 @@
   if (!policy_timestamp.is_null() && !old_timestamp.is_null() &&
       policy_timestamp != old_timestamp) {
     const base::TimeDelta age = policy_timestamp - old_timestamp;
-    if (policy_type_ == dm_protocol::kChromeUserPolicyType) {
+    if (policy_type_ == dm_protocol::GetChromeUserPolicyType()) {
       UMA_HISTOGRAM_CUSTOM_COUNTS("Enterprise.PolicyUpdatePeriod.User",
                                   age.InDays(), 1, 1000, 100);
     } else if (policy_type_ == dm_protocol::kChromeDevicePolicyType) {
diff --git a/components/policy/core/common/cloud/cloud_policy_service_unittest.cc b/components/policy/core/common/cloud/cloud_policy_service_unittest.cc
index ad786f8f..a9a7fe7 100644
--- a/components/policy/core/common/cloud/cloud_policy_service_unittest.cc
+++ b/components/policy/core/common/cloud/cloud_policy_service_unittest.cc
@@ -28,7 +28,7 @@
 class CloudPolicyServiceTest : public testing::Test {
  public:
   CloudPolicyServiceTest()
-      : policy_type_(dm_protocol::kChromeUserPolicyType),
+      : policy_type_(dm_protocol::GetChromeUserPolicyType()),
         service_(policy_type_, std::string(), &client_, &store_) {}
 
   MOCK_METHOD1(OnPolicyRefresh, void(bool));
diff --git a/components/policy/core/common/cloud/cloud_policy_validator_unittest.cc b/components/policy/core/common/cloud/cloud_policy_validator_unittest.cc
index 4fc74f5..9004a425 100644
--- a/components/policy/core/common/cloud/cloud_policy_validator_unittest.cc
+++ b/components/policy/core/common/cloud/cloud_policy_validator_unittest.cc
@@ -142,7 +142,7 @@
       validator->ValidateDomain(owning_domain_);
     validator->ValidateDMToken(existing_dm_token_, dm_token_option_);
     validator->ValidateDeviceId(existing_device_id_, device_id_option_);
-    validator->ValidatePolicyType(dm_protocol::kChromeUserPolicyType);
+    validator->ValidatePolicyType(dm_protocol::GetChromeUserPolicyType());
     validator->ValidatePayload();
     validator->ValidateCachedKey(public_key, cached_key_signature_,
                                  owning_domain_, verification_data,
@@ -334,12 +334,12 @@
 // as unsigned, which is not supported.
 TEST_F(CloudPolicyValidatorTest, FailedValidationWithSignatureTypeNONE) {
   policy_.SetSignatureType(em::PolicyFetchRequest::SHA1_RSA);
-  policy_.policy_data().set_policy_type(dm_protocol::kChromeUserPolicyType);
+  policy_.policy_data().set_policy_type(dm_protocol::GetChromeUserPolicyType());
   policy_.Build();
   policy_.policy().set_policy_data_signature_type(em::PolicyFetchRequest::NONE);
   std::unique_ptr<UserCloudPolicyValidator> validator =
       CreateValidator(policy_.GetCopy());
-  validator->ValidatePolicyType(dm_protocol::kChromeUserPolicyType);
+  validator->ValidatePolicyType(dm_protocol::GetChromeUserPolicyType());
   ValidatePolicy(
       CheckStatus(CloudPolicyValidatorBase::VALIDATION_BAD_SIGNATURE),
       std::move(validator));
diff --git a/components/policy/core/common/cloud/component_cloud_policy_service_unittest.cc b/components/policy/core/common/cloud/component_cloud_policy_service_unittest.cc
index 12a7492..37a7586 100644
--- a/components/policy/core/common/cloud/component_cloud_policy_service_unittest.cc
+++ b/components/policy/core/common/cloud/component_cloud_policy_service_unittest.cc
@@ -116,7 +116,7 @@
   ComponentCloudPolicyServiceTest()
       : cache_(nullptr),
         client_(nullptr),
-        core_(dm_protocol::kChromeUserPolicyType,
+        core_(dm_protocol::GetChromeUserPolicyType(),
               std::string(),
               &store_,
               base::SingleThreadTaskRunner::GetCurrentDefault(),
diff --git a/components/policy/core/common/cloud/component_cloud_policy_store_unittest.cc b/components/policy/core/common/cloud/component_cloud_policy_store_unittest.cc
index 3e050f9..1e4953e 100644
--- a/components/policy/core/common/cloud/component_cloud_policy_store_unittest.cc
+++ b/components/policy/core/common/cloud/component_cloud_policy_store_unittest.cc
@@ -239,7 +239,8 @@
 }
 
 TEST_F(ComponentCloudPolicyStoreTest, ValidatePolicyBadType) {
-  builder_.policy_data().set_policy_type(dm_protocol::kChromeUserPolicyType);
+  builder_.policy_data().set_policy_type(
+      dm_protocol::GetChromeUserPolicyType());
   std::string error;
   EXPECT_FALSE(store_->ValidatePolicy(kTestPolicyNS, CreateResponse(),
                                       nullptr /* policy_data */,
@@ -517,7 +518,8 @@
   EXPECT_TRUE(IsStoreEmpty(*store_));
 
   // Store policy for an unsupported domain.
-  builder_.policy_data().set_policy_type(dm_protocol::kChromeUserPolicyType);
+  builder_.policy_data().set_policy_type(
+      dm_protocol::GetChromeUserPolicyType());
   EXPECT_FALSE(
       store_->Store(PolicyNamespace(POLICY_DOMAIN_CHROME, kTestExtension),
                     CreateSerializedResponse(), CreatePolicyData().get(),
diff --git a/components/policy/core/common/cloud/mock_cloud_policy_manager.cc b/components/policy/core/common/cloud/mock_cloud_policy_manager.cc
index 632e512..5451529 100644
--- a/components/policy/core/common/cloud/mock_cloud_policy_manager.cc
+++ b/components/policy/core/common/cloud/mock_cloud_policy_manager.cc
@@ -20,7 +20,7 @@
     std::unique_ptr<CloudPolicyStore> store,
     const scoped_refptr<base::SequencedTaskRunner>& task_runner)
     : CloudPolicyManager(
-          dm_protocol::kChromeUserPolicyType,
+          dm_protocol::GetChromeUserPolicyType(),
           std::string(),
           std::move(store),
           task_runner,
diff --git a/components/policy/core/common/cloud/profile_cloud_policy_manager.cc b/components/policy/core/common/cloud/profile_cloud_policy_manager.cc
index a6367b7..6a1ed3a 100644
--- a/components/policy/core/common/cloud/profile_cloud_policy_manager.cc
+++ b/components/policy/core/common/cloud/profile_cloud_policy_manager.cc
@@ -45,7 +45,7 @@
     network::NetworkConnectionTrackerGetter network_connection_tracker_getter,
     bool is_dasherless)
     : CloudPolicyManager(
-          is_dasherless ? dm_protocol::kChromeUserPolicyType
+          is_dasherless ? dm_protocol::GetChromeUserPolicyType()
                         : dm_protocol::kChromeMachineLevelUserCloudPolicyType,
           /*settings_entity_id=*/std::string(),
           std::move(profile_store),
diff --git a/components/policy/core/common/cloud/profile_cloud_policy_store.cc b/components/policy/core/common/cloud/profile_cloud_policy_store.cc
index 39c5bad..7d87699 100644
--- a/components/policy/core/common/cloud/profile_cloud_policy_store.cc
+++ b/components/policy/core/common/cloud/profile_cloud_policy_store.cc
@@ -66,7 +66,7 @@
   // validation.
 
   validator->ValidatePolicyType(
-      is_dasherless_ ? dm_protocol::kChromeUserPolicyType
+      is_dasherless_ ? dm_protocol::GetChromeUserPolicyType()
                      : dm_protocol::kChromeMachineLevelUserCloudPolicyType);
   validator->ValidateAgainstCurrentPolicy(
       policy(), option, CloudPolicyValidatorBase::DM_TOKEN_REQUIRED,
diff --git a/components/policy/core/common/cloud/test/policy_builder.cc b/components/policy/core/common/cloud/test/policy_builder.cc
index f0c9e36..5aa3024e 100644
--- a/components/policy/core/common/cloud/test/policy_builder.cc
+++ b/components/policy/core/common/cloud/test/policy_builder.cc
@@ -531,7 +531,7 @@
 template <>
 TypedPolicyBuilder<em::CloudPolicySettings>::TypedPolicyBuilder()
     : payload_(new em::CloudPolicySettings()) {
-  policy_data().set_policy_type(dm_protocol::kChromeUserPolicyType);
+  policy_data().set_policy_type(dm_protocol::GetChromeUserPolicyType());
 }
 
 // Have the instantiation compiled into the module.
diff --git a/components/policy/core/common/cloud/user_cloud_policy_manager.cc b/components/policy/core/common/cloud/user_cloud_policy_manager.cc
index c0087d3..2d6aa3a3 100644
--- a/components/policy/core/common/cloud/user_cloud_policy_manager.cc
+++ b/components/policy/core/common/cloud/user_cloud_policy_manager.cc
@@ -46,7 +46,7 @@
     std::unique_ptr<CloudExternalDataManager> external_data_manager,
     const scoped_refptr<base::SequencedTaskRunner>& task_runner,
     network::NetworkConnectionTrackerGetter network_connection_tracker_getter)
-    : CloudPolicyManager(dm_protocol::kChromeUserPolicyType,
+    : CloudPolicyManager(dm_protocol::GetChromeUserPolicyType(),
                          std::string(),
                          std::move(user_store),
                          task_runner,
diff --git a/components/policy/core/common/cloud/user_cloud_policy_store_base.cc b/components/policy/core/common/cloud/user_cloud_policy_store_base.cc
index 5dd4b9d1..896294b6 100644
--- a/components/policy/core/common/cloud/user_cloud_policy_store_base.cc
+++ b/components/policy/core/common/cloud/user_cloud_policy_store_base.cc
@@ -32,7 +32,7 @@
   // Configure the validator.
   auto validator = std::make_unique<UserCloudPolicyValidator>(
       std::move(policy_fetch_response), background_task_runner_);
-  validator->ValidatePolicyType(dm_protocol::kChromeUserPolicyType);
+  validator->ValidatePolicyType(dm_protocol::GetChromeUserPolicyType());
   validator->ValidateAgainstCurrentPolicy(
       policy(), timestamp_option, CloudPolicyValidatorBase::DM_TOKEN_REQUIRED,
       CloudPolicyValidatorBase::DEVICE_ID_REQUIRED);
diff --git a/components/policy/resources/templates/policy_definitions/Sharing/TabGroupSharingSettings.yaml b/components/policy/resources/templates/policy_definitions/Sharing/TabGroupSharingSettings.yaml
index 18ff1132..4735a9d 100644
--- a/components/policy/resources/templates/policy_definitions/Sharing/TabGroupSharingSettings.yaml
+++ b/components/policy/resources/templates/policy_definitions/Sharing/TabGroupSharingSettings.yaml
@@ -12,9 +12,9 @@
 supported_on:
 - android:140-
 - chrome.*:140-
+- ios:140-
 future_on:
 - chrome_os
-- ios
 features:
   cloud_only: true
   dynamic_refresh: true
diff --git a/components/policy/test_support/fake_dmserver_unittest.cc b/components/policy/test_support/fake_dmserver_unittest.cc
index 924e835..4f1f972 100644
--- a/components/policy/test_support/fake_dmserver_unittest.cc
+++ b/components/policy/test_support/fake_dmserver_unittest.cc
@@ -205,7 +205,7 @@
   EXPECT_EQ(clients[0].username.value(), "tast-user@managedchrome.com");
   ASSERT_EQ(clients[0].allowed_policy_types.size(), 1u);
   EXPECT_EQ(*clients[0].allowed_policy_types.begin(),
-            policy::dm_protocol::kChromeUserPolicyType);
+            policy::dm_protocol::GetChromeUserPolicyType());
   EXPECT_TRUE(clients[0].state_keys.empty());
 
   JSONFileValueDeserializer deserializer(client_state_path_);
@@ -237,7 +237,7 @@
   ASSERT_TRUE(allowed_policy_types);
   ASSERT_EQ(allowed_policy_types->size(), 1u);
   EXPECT_EQ((*allowed_policy_types)[0].GetString(),
-            policy::dm_protocol::kChromeUserPolicyType);
+            policy::dm_protocol::GetChromeUserPolicyType());
 
   const base::Value::List* state_keys = client_dict->FindList("state_keys");
   ASSERT_TRUE(state_keys);
diff --git a/components/policy/test_support/request_handler_for_policy.cc b/components/policy/test_support/request_handler_for_policy.cc
index bffdaab..d398b420 100644
--- a/components/policy/test_support/request_handler_for_policy.cc
+++ b/components/policy/test_support/request_handler_for_policy.cc
@@ -50,7 +50,7 @@
       dm_protocol::kChromeMachineLevelExtensionCloudPolicyType,
       dm_protocol::kChromePublicAccountPolicyType,
       dm_protocol::kChromeSigninExtensionPolicyType,
-      dm_protocol::kChromeUserPolicyType,
+      dm_protocol::GetChromeUserPolicyType(),
       dm_protocol::kGoogleUpdateMachineLevelAppsPolicyType,
       dm_protocol::kGoogleUpdateMachineLevelOmahaPolicyType,
   };
@@ -215,7 +215,7 @@
     policy_data.set_public_key_version(signing_key_version);
   }
 
-  if (policy_type == dm_protocol::kChromeUserPolicyType ||
+  if (policy_type == policy::dm_protocol::GetChromeUserPolicyType() ||
       policy_type == dm_protocol::kChromePublicAccountPolicyType) {
     std::vector<std::string> user_affiliation_ids =
         policy_storage()->user_affiliation_ids();
diff --git a/components/policy/test_support/request_handler_for_register_browser.cc b/components/policy/test_support/request_handler_for_register_browser.cc
index 0d0eec1..866f5ed 100644
--- a/components/policy/test_support/request_handler_for_register_browser.cc
+++ b/components/policy/test_support/request_handler_for_register_browser.cc
@@ -100,12 +100,12 @@
   return nullptr;
 }
 
-constexpr base::flat_set<std::string>
+base::flat_set<std::string>
 RequestHandlerForRegisterBrowser::allowed_policy_types() {
   return base::MakeFlatSet<std::string>(
       std::vector({dm_protocol::kChromeMachineLevelUserCloudPolicyType,
                    dm_protocol::kChromeMachineLevelExtensionCloudPolicyType,
-                   dm_protocol::kChromeUserPolicyType}));
+                   dm_protocol::GetChromeUserPolicyType()}));
 }
 
 RequestHandlerForRegisterPolicyAgent::RequestHandlerForRegisterPolicyAgent(
@@ -139,7 +139,7 @@
   return nullptr;
 }
 
-constexpr base::flat_set<std::string>
+base::flat_set<std::string>
 RequestHandlerForRegisterPolicyAgent::allowed_policy_types() {
   return base::MakeFlatSet<std::string>(
       std::vector({dm_protocol::kGoogleUpdateMachineLevelAppsPolicyType,
diff --git a/components/policy/test_support/request_handler_for_register_browser.h b/components/policy/test_support/request_handler_for_register_browser.h
index def66427..a2f0ed8 100644
--- a/components/policy/test_support/request_handler_for_register_browser.h
+++ b/components/policy/test_support/request_handler_for_register_browser.h
@@ -37,7 +37,7 @@
       const enterprise_management::RegisterBrowserRequest&
           register_browser_request) = 0;
 
-  virtual constexpr base::flat_set<std::string> allowed_policy_types() = 0;
+  virtual base::flat_set<std::string> allowed_policy_types() = 0;
 };
 
 // Handler for request type `register_browser`.
@@ -61,7 +61,7 @@
       const enterprise_management::RegisterBrowserRequest&
           register_browser_request) override;
 
-  constexpr base::flat_set<std::string> allowed_policy_types() override;
+  base::flat_set<std::string> allowed_policy_types() override;
 };
 
 // Handler for request type `register_policy_agent`.
@@ -86,7 +86,7 @@
       const enterprise_management::RegisterBrowserRequest&
           register_browser_request) override;
 
-  constexpr base::flat_set<std::string> allowed_policy_types() override;
+  base::flat_set<std::string> allowed_policy_types() override;
 };
 
 }  // namespace policy
diff --git a/components/policy/test_support/request_handler_for_register_device_and_user.cc b/components/policy/test_support/request_handler_for_register_device_and_user.cc
index 2eb4e11a..4c50757 100644
--- a/components/policy/test_support/request_handler_for_register_device_and_user.cc
+++ b/components/policy/test_support/request_handler_for_register_device_and_user.cc
@@ -34,10 +34,10 @@
     // TODO(crbug.com/1289442): Remove this case once the type is correctly set
     // for request type `register`.
     case em::DeviceRegisterRequest::TT:
-      allowed_policy_types->insert({dm_protocol::kChromeUserPolicyType});
+      allowed_policy_types->insert({dm_protocol::GetChromeUserPolicyType()});
       break;
     case em::DeviceRegisterRequest::USER:
-      allowed_policy_types->insert({dm_protocol::kChromeUserPolicyType,
+      allowed_policy_types->insert({dm_protocol::GetChromeUserPolicyType(),
                                     dm_protocol::kChromeExtensionPolicyType});
       break;
     case em::DeviceRegisterRequest::DEVICE:
@@ -48,14 +48,14 @@
            dm_protocol::kChromeSigninExtensionPolicyType});
       break;
     case em::DeviceRegisterRequest::BROWSER:
-      allowed_policy_types->insert({dm_protocol::kChromeUserPolicyType,
+      allowed_policy_types->insert({dm_protocol::GetChromeUserPolicyType(),
                                     dm_protocol::kChromeExtensionPolicyType});
       break;
     case em::DeviceRegisterRequest::ANDROID_BROWSER:
-      allowed_policy_types->insert({dm_protocol::kChromeUserPolicyType});
+      allowed_policy_types->insert({dm_protocol::GetChromeUserPolicyType()});
       break;
     case em::DeviceRegisterRequest::IOS_BROWSER:
-      allowed_policy_types->insert({dm_protocol::kChromeUserPolicyType});
+      allowed_policy_types->insert({dm_protocol::GetChromeUserPolicyType()});
       break;
     default:
       NOTREACHED();
diff --git a/components/supervised_user/core/browser/supervised_user_metrics_service.cc b/components/supervised_user/core/browser/supervised_user_metrics_service.cc
index 9c5653d..963646e6 100644
--- a/components/supervised_user/core/browser/supervised_user_metrics_service.cc
+++ b/components/supervised_user/core/browser/supervised_user_metrics_service.cc
@@ -4,9 +4,14 @@
 
 #include "components/supervised_user/core/browser/supervised_user_metrics_service.h"
 
+#include <memory>
+#include <optional>
+#include <string>
+#include <utility>
+
 #include "base/check.h"
-#include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
+#include "base/strings/strcat.h"
 #include "base/time/time.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
@@ -29,10 +34,10 @@
 }
 #endif  // BUILDFLAG(IS_ANDROID)
 
-// UMA histogram FamilyUser.WebFilterType
 // Reports WebFilterType which indicates web filter behaviour are used for
 // current Family Link user.
-constexpr char kWebFilterTypeHistogramName[] = "FamilyUser.WebFilterType";
+constexpr char kFamilyUserWebFilterTypeHistogramName[] =
+    "FamilyUser.WebFilterType";
 
 // UMA histogram FamilyUser.ManualSiteListType
 // Reports ManualSiteListType which indicates approved list and blocked list
@@ -55,7 +60,6 @@
 int GetDayId(base::Time time) {
   return time.LocalMidnight().since_origin().InDaysFloored();
 }
-
 }  // namespace
 
 // static
@@ -104,7 +108,9 @@
 SupervisedUserMetricsService::~SupervisedUserMetricsService() = default;
 
 void SupervisedUserMetricsService::Shutdown() {
-  CheckForNewDay();
+  // Per histograms.xml description, FamilyUser.WebFilterType must not emit on
+  // signout. Shutdown is also called on signout, and the timer most probably
+  // already emitted for the given day.
   timer_.Stop();
 }
 
@@ -114,28 +120,24 @@
   // The OnNewDay() event can fire sooner or later than 24 hours due to clock or
   // time zone changes.
   if (day_id < current_day_id) {
-    bool should_update_day_id = false;
-    // Since this service's periodical check runs independently from the
-    // SupervisedUserService, do not emit if the filtering expected to be
-    // inactive.
-    if (supervised_user_service_->GetURLFilter()->GetWebFilterType() !=
-        WebFilterType::kDisabled) {
-      ClearMetricsCache();
-      EmitMetrics();
-      should_update_day_id = true;
-    }
+    ClearMetricsCache();
+    TryEmittingMetricsAndRecordCurrentDay();
 
     if (extensions_metrics_delegate_ &&
         extensions_metrics_delegate_->RecordExtensionsMetrics()) {
-      should_update_day_id = true;
-    }
-    if (should_update_day_id) {
-      pref_service_->SetInteger(prefs::kSupervisedUserMetricsDayId,
-                                current_day_id);
+      // Note that TryEmittingMetricsAndRecordCurrentDay above records the day
+      // internally, but the delegate is external and new day must be recorded
+      // explicitly.
+      RecordCurrentDay();
     }
   }
 }
 
+void SupervisedUserMetricsService::RecordCurrentDay() {
+  pref_service_->SetInteger(prefs::kSupervisedUserMetricsDayId,
+                            GetDayId(base::Time::Now()));
+}
+
 void SupervisedUserMetricsService::OnBrowserContentFiltersChanged() {
 #if BUILDFLAG(IS_ANDROID)
   metrics_service_accessor_delegate_->RegisterSyntheticFieldTrial(
@@ -155,36 +157,52 @@
 }
 
 void SupervisedUserMetricsService::OnURLFilterChanged() {
-  EmitMetrics();
+  TryEmittingMetricsAndRecordCurrentDay();
 }
 
-void SupervisedUserMetricsService::EmitMetrics() {
+bool SupervisedUserMetricsService::TryEmittingMetricsAndRecordCurrentDay() {
+  if (!supervised_user_service_->IsSupervisedLocally() &&
+      !IsSubjectToParentalControls(*pref_service_.get())) {
+    return false;
+  }
+
+  bool emitted = false;
+  WebFilterType web_filter_type =
+      supervised_user_service_->GetURLFilter()->GetWebFilterType();
   if (!last_recorded_web_filter_type_.has_value() ||
-      *last_recorded_web_filter_type_ !=
-          supervised_user_service_->GetURLFilter()->GetWebFilterType()) {
-    WebFilterType web_filter_type =
-        supervised_user_service_->GetURLFilter()->GetWebFilterType();
-
-    base::UmaHistogramEnumeration(kWebFilterTypeHistogramName, web_filter_type);
+      *last_recorded_web_filter_type_ != web_filter_type) {
+    base::UmaHistogramEnumeration(kFamilyUserWebFilterTypeHistogramName,
+                                  web_filter_type);
     last_recorded_web_filter_type_ = web_filter_type;
+    emitted = true;
   }
 
-  if (!last_recorded_statistics_.has_value() ||
-      *last_recorded_statistics_ !=
-          supervised_user_service_->GetURLFilter()->GetFilteringStatistics()) {
-    SupervisedUserURLFilter::Statistics statistics =
-        supervised_user_service_->GetURLFilter()->GetFilteringStatistics();
+  // Only for Family Link users.
+  if (IsSubjectToParentalControls(*pref_service_.get())) {
+    if (!last_recorded_statistics_.has_value() ||
+        *last_recorded_statistics_ != supervised_user_service_->GetURLFilter()
+                                          ->GetFilteringStatistics()) {
+      SupervisedUserURLFilter::Statistics statistics =
+          supervised_user_service_->GetURLFilter()->GetFilteringStatistics();
 
-    base::UmaHistogramCounts1000(
-        kApprovedSitesCountHistogramName,
-        statistics.allowed_hosts_count + statistics.allowed_urls_count);
-    base::UmaHistogramCounts1000(
-        kBlockedSitesCountHistogramName,
-        statistics.blocked_hosts_count + statistics.blocked_urls_count);
-    base::UmaHistogramEnumeration(kManagedSiteListHistogramName,
-                                  statistics.GetManagedSiteList());
-    last_recorded_statistics_ = statistics;
+      base::UmaHistogramCounts1000(
+          kApprovedSitesCountHistogramName,
+          statistics.allowed_hosts_count + statistics.allowed_urls_count);
+      base::UmaHistogramCounts1000(
+          kBlockedSitesCountHistogramName,
+          statistics.blocked_hosts_count + statistics.blocked_urls_count);
+      base::UmaHistogramEnumeration(kManagedSiteListHistogramName,
+                                    statistics.GetManagedSiteList());
+      last_recorded_statistics_ = statistics;
+      emitted = true;
+    }
   }
+
+  if (emitted) {
+    RecordCurrentDay();
+  }
+
+  return emitted;
 }
 
 void SupervisedUserMetricsService::ClearMetricsCache() {
diff --git a/components/supervised_user/core/browser/supervised_user_metrics_service.h b/components/supervised_user/core/browser/supervised_user_metrics_service.h
index 958b72e..92337b3 100644
--- a/components/supervised_user/core/browser/supervised_user_metrics_service.h
+++ b/components/supervised_user/core/browser/supervised_user_metrics_service.h
@@ -79,12 +79,18 @@
 
   // Helper function to check if a new day has arrived.
   void CheckForNewDay();
+  // Returns true if metrics were emitted. Dispatches to one of the below
+  // functions depending on the user type.
+  bool TryEmittingMetricsAndRecordCurrentDay();
+  bool TryEmittingFamilyLinkMetrics();
 
-  void EmitMetrics();
-  // Clears cache of last recorded metrics. Subsequent `::EmitMetrics` will emit
-  // all metrics.
+  // Clears cache of last recorded metrics. Subsequent `::TryEmittingMetrics` will emit
+  // all metrics (for eligible users)
   void ClearMetricsCache();
 
+  // Records the current day's metrics, to avoid repetitions.
+  void RecordCurrentDay();
+
   const raw_ptr<PrefService> pref_service_;
   raw_ref<SupervisedUserService> supervised_user_service_;
   std::unique_ptr<SupervisedUserMetricsServiceExtensionDelegate>
diff --git a/components/supervised_user/core/browser/supervised_user_metrics_service_unittest.cc b/components/supervised_user/core/browser/supervised_user_metrics_service_unittest.cc
index f2d0362..4852c13 100644
--- a/components/supervised_user/core/browser/supervised_user_metrics_service_unittest.cc
+++ b/components/supervised_user/core/browser/supervised_user_metrics_service_unittest.cc
@@ -5,6 +5,8 @@
 #include "components/supervised_user/core/browser/supervised_user_metrics_service.h"
 
 #include <memory>
+#include <string>
+#include <utility>
 
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
@@ -31,28 +33,36 @@
 constexpr char kBlockedSitesCountHistogramName[] =
     "FamilyUser.ManagedSiteListCount.Blocked";
 
-// Tests for family user metrics service.
-class SupervisedUserMetricsServiceTest : public testing::Test {
+class SupervisedUserMetricsServiceTest : public ::testing::Test {
  protected:
-  ~SupervisedUserMetricsServiceTest() override {
-    supervised_user_test_environment_.Shutdown();
+  // Explicit environment initialization reduces the number of fixtures.
+  void Initialize(InitialSupervisionState initial_state) {
+    supervised_user_test_environment_ =
+        std::make_unique<SupervisedUserTestEnvironment>(initial_state);
   }
 
+  void TearDown() override { supervised_user_test_environment_->Shutdown(); }
+
   int GetDayIdPref() {
-    return supervised_user_test_environment_.pref_service()->GetInteger(
+    return supervised_user_test_environment_->pref_service()->GetInteger(
         prefs::kSupervisedUserMetricsDayId);
   }
 
+#if BUILDFLAG(IS_ANDROID)
+  base::test::ScopedFeatureList scoped_feature_list_{
+      kPropagateDeviceContentFiltersToSupervisedUser};
+#endif  // BUILDFLAG(IS_ANDROID)
+
+  base::HistogramTester histogram_tester_;
   base::test::TaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
-  base::HistogramTester histogram_tester_;
-  SupervisedUserTestEnvironment supervised_user_test_environment_;
+  std::unique_ptr<SupervisedUserTestEnvironment>
+      supervised_user_test_environment_;
 };
 
 // Tests that the recorded day is updated after more than one day passes.
 TEST_F(SupervisedUserMetricsServiceTest, NewDayAfterMultipleDays) {
-  EnableParentalControls(*supervised_user_test_environment_.pref_service());
-
+  Initialize(InitialSupervisionState::kFamilyLinkDefault);
   task_environment_.FastForwardBy(base::Days(1) + base::Hours(1));
   EXPECT_EQ(SupervisedUserMetricsService::GetDayIdForTesting(base::Time::Now()),
             GetDayIdPref());
@@ -60,26 +70,30 @@
 }
 
 // Tests that the recorded day is updated after metrics service is created.
-TEST_F(SupervisedUserMetricsServiceTest, NewDayAfterServiceCreation) {
-  EnableParentalControls(*supervised_user_test_environment_.pref_service());
-
-  task_environment_.FastForwardBy(base::Hours(1));
-  EXPECT_EQ(SupervisedUserMetricsService::GetDayIdForTesting(base::Time::Now()),
-            GetDayIdPref());
+TEST_F(SupervisedUserMetricsServiceTest,
+       NewDayAfterServiceCreationForFamilyLink) {
+  Initialize(InitialSupervisionState::kFamilyLinkDefault);
   EXPECT_NE(0, GetDayIdPref());
 }
 
-// Tests that the recorded day is updated only after a supervised user is
-// detected.
-TEST_F(SupervisedUserMetricsServiceTest, NewDayAfterSupervisedUserDetected) {
-  DisableParentalControls(*supervised_user_test_environment_.pref_service());
+#if BUILDFLAG(IS_ANDROID)
+TEST_F(SupervisedUserMetricsServiceTest,
+       NewDayAfterServiceCreationForLocallySupervised) {
+  Initialize(InitialSupervisionState::kSupervisedWithAllContentFilters);
+  EXPECT_NE(0, GetDayIdPref());
+}
+#endif  // BUILDFLAG(IS_ANDROID)
 
-  task_environment_.FastForwardBy(base::Hours(1));
-  // Day ID should not change if the filter is not initialized.
+// Unsupervised user doesn't emit metrics and will not have a day id pref.
+TEST_F(SupervisedUserMetricsServiceTest, NewDayAfterSupervisedUserDetected) {
+  Initialize(InitialSupervisionState::kUnsupervised);
   EXPECT_EQ(0, GetDayIdPref());
 
-  EnableParentalControls(*supervised_user_test_environment_.pref_service());
-  task_environment_.FastForwardBy(base::Hours(1));
+  // Advancing clock won't change the day id pref - user is not supervised.
+  task_environment_.FastForwardBy(base::Days(1) + base::Hours(1));
+  EXPECT_EQ(0, GetDayIdPref());
+
+  EnableParentalControls(*supervised_user_test_environment_->pref_service());
   EXPECT_EQ(SupervisedUserMetricsService::GetDayIdForTesting(base::Time::Now()),
             GetDayIdPref());
 }
@@ -87,23 +101,26 @@
 // Tests that metrics are not recorded for unsupervised users.
 TEST_F(SupervisedUserMetricsServiceTest,
        MetricsNotRecordedForSignedOutSupervisedUser) {
-  DisableParentalControls(*supervised_user_test_environment_.pref_service());
+  Initialize(InitialSupervisionState::kUnsupervised);
   histogram_tester_.ExpectTotalCount(kWebFilterTypeHistogramName,
                                      /*expected_count=*/0);
   histogram_tester_.ExpectTotalCount(kManagedSiteListHistogramName,
                                      /*expected_count=*/0);
+  histogram_tester_.ExpectTotalCount(kApprovedSitesCountHistogramName,
+                                     /*expected_count=*/0);
+  histogram_tester_.ExpectTotalCount(kBlockedSitesCountHistogramName,
+                                     /*expected_count=*/0);
 }
 
-// Tests that default metrics are recorded for supervised users whose parent has
-// not changed the initial configuration.
-TEST_F(SupervisedUserMetricsServiceTest, RecordDefaultMetrics) {
-  // If the parent has not changed their configuration the supervised user
-  // should be subject to default mature sites blocking.
-  EnableParentalControls(*supervised_user_test_environment_.pref_service());
+TEST_F(SupervisedUserMetricsServiceTest,
+       MetricsRecordedForFamilyLinkSupervisedUser) {
+  Initialize(InitialSupervisionState::kFamilyLinkDefault);
+
   histogram_tester_.ExpectUniqueSample(kWebFilterTypeHistogramName,
                                        /*sample=*/
                                        WebFilterType::kTryToBlockMatureSites,
                                        /*expected_bucket_count=*/1);
+
   histogram_tester_.ExpectUniqueSample(
       kManagedSiteListHistogramName,
       /*sample=*/
@@ -118,9 +135,21 @@
 }
 
 #if BUILDFLAG(IS_ANDROID)
+TEST_F(SupervisedUserMetricsServiceTest,
+       MetricsRecordedForLocallySupervisedUser) {
+  Initialize(InitialSupervisionState::kSupervisedWithAllContentFilters);
+
+  // For this type of supervised user, the managed site list is not reported.
+  histogram_tester_.ExpectTotalCount(kManagedSiteListHistogramName,
+                                     /*expected_count=*/0);
+  histogram_tester_.ExpectTotalCount(kApprovedSitesCountHistogramName,
+                                     /*expected_count=*/0);
+  histogram_tester_.ExpectTotalCount(kBlockedSitesCountHistogramName,
+                                     /*expected_count=*/0);
+}
 
 using FieldTrialName = std::string;
-
+// Test suite to check correct association with synthetic field trials
 class SupervisedUserMetricsServiceFieldTrialTest
     : public testing::TestWithParam<FieldTrialName> {
  protected:
@@ -164,8 +193,7 @@
   // Register calls before environment's created, because the metrics service
   // calls field trial registration on creation.
   auto mock = std::make_unique<MetricsServiceAccessorDelegateMock>();
-  EXPECT_CALL(*mock, RegisterSyntheticFieldTrial(_, "Disabled"))
-      .Times(1);
+  EXPECT_CALL(*mock, RegisterSyntheticFieldTrial(_, "Disabled")).Times(1);
   EXPECT_CALL(*mock, RegisterSyntheticFieldTrial(Eq(GetParam()), "Disabled"))
       .Times(2);
   EXPECT_CALL(*mock, RegisterSyntheticFieldTrial(Eq(GetParam()), "Enabled"))
@@ -190,7 +218,71 @@
       return info.param;
     });
 
-#endif  // BUILDFLAG(IS_CHROMEOS)
+#endif  // BUILDFLAG(IS_ANDROID)
 
+struct PeriodicalWebFilterTypeTestParams {
+  std::string test_name;
+  // Which user type to start with.
+  InitialSupervisionState initial_supervision_state;
+  // Whether we expect any emissions at all.
+  bool expect_emissions;
+};
+
+class SupervisedUserMetricsServiceWebFilterTypePeriodicalTest
+    : public SupervisedUserMetricsServiceTest,
+      public ::testing::WithParamInterface<PeriodicalWebFilterTypeTestParams> {
+};
+
+TEST_P(SupervisedUserMetricsServiceWebFilterTypePeriodicalTest,
+       WebFilterTypeEmittedDaily) {
+  Initialize(GetParam().initial_supervision_state);
+  // Check post-initialization counts of FamilyUser metrics reset histogram
+  // tracker.
+  histogram_tester_.ExpectBucketCount(kWebFilterTypeHistogramName,
+                                      WebFilterType::kTryToBlockMatureSites,
+                                      GetParam().expect_emissions ? 1 : 0);
+
+  int start_day_id =
+      base::Time::Now().LocalMidnight().since_origin().InDaysFloored();
+  EXPECT_EQ(GetParam().expect_emissions ? start_day_id : 0,
+            supervised_user_test_environment_->pref_service()->GetInteger(
+                prefs::kSupervisedUserMetricsDayId));
+
+  // Advance clock by some days and note how many calendar days have passed
+  // (DST, service's polling resolution and other details can affect the day
+  // count).
+  task_environment_.FastForwardBy(base::Days(1));
+  int end_day_id =
+      base::Time::Now().LocalMidnight().since_origin().InDaysFloored();
+
+  // Initial day emission + one for each *new* day or none.
+  int expected_count =
+      GetParam().expect_emissions ? (1 + (end_day_id - start_day_id)) : 0;
+
+  histogram_tester_.ExpectBucketCount(kWebFilterTypeHistogramName,
+                                      WebFilterType::kTryToBlockMatureSites,
+                                      expected_count);
+}
+
+const PeriodicalWebFilterTypeTestParams kPeriodicalWebFilterTypeTestParams[] = {
+    {"Unsupervised", InitialSupervisionState::kUnsupervised,
+     /*expect_emissions=*/false},
+    {"SupervisedWithParentalControls",
+     InitialSupervisionState::kFamilyLinkDefault,
+     /*expect_emissions=*/true},
+#if BUILDFLAG(IS_ANDROID)
+    {"SupervisedLocally",
+     InitialSupervisionState::kSupervisedWithAllContentFilters,
+     /*expect_emissions=*/true},
+#endif  // BUILDFLAG(IS_ANDROID)
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    ,
+    SupervisedUserMetricsServiceWebFilterTypePeriodicalTest,
+    testing::ValuesIn(kPeriodicalWebFilterTypeTestParams),
+    [](const testing::TestParamInfo<
+        SupervisedUserMetricsServiceWebFilterTypePeriodicalTest::ParamType>&
+           info) { return info.param.test_name; });
 }  // namespace
 }  // namespace supervised_user
diff --git a/components/supervised_user/core/browser/supervised_user_service.cc b/components/supervised_user/core/browser/supervised_user_service.cc
index 0cde463..218d541 100644
--- a/components/supervised_user/core/browser/supervised_user_service.cc
+++ b/components/supervised_user/core/browser/supervised_user_service.cc
@@ -14,7 +14,6 @@
 #include "base/containers/contains.h"
 #include "base/feature_list.h"
 #include "base/functional/bind.h"
-#include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/user_metrics.h"
 #include "base/strings/stringprintf.h"
@@ -50,9 +49,9 @@
 
 // All prefs that configure the url filter.
 std::array<const char*, 4> kUrlFilterSettingsPrefs = {
-  prefs::kDefaultSupervisedUserFilteringBehavior,
-  prefs::kSupervisedUserSafeSites, prefs::kSupervisedUserManualHosts,
-  prefs::kSupervisedUserManualURLs};
+    prefs::kDefaultSupervisedUserFilteringBehavior,
+    prefs::kSupervisedUserSafeSites, prefs::kSupervisedUserManualHosts,
+    prefs::kSupervisedUserManualURLs};
 
 // Helper that extracts custodian data from given preferences.
 std::optional<Custodian> GetCustodianFromPrefs(
@@ -426,6 +425,8 @@
   // groups and then reloads search pages.
   observer_list_.Notify(
       &SupervisedUserServiceObserver::OnSearchContentFiltersChanged);
+  // Required to emit WebFilterType metrics.
+  UpdateURLFilter();
 }
 void SupervisedUserService::DisableSearchContentFilters() {
   content_filters_service_->SetSearchFiltersEnabled(false);
@@ -455,7 +456,8 @@
   // groups
   observer_list_.Notify(
       &SupervisedUserServiceObserver::OnBrowserContentFiltersChanged);
-  // Updates URL filter settings and reclassifies the observed navigations.
+  // Required to emit WebFilterType metrics and reclassifies the observed
+  // navigations.
   UpdateURLFilter();
 }
 
@@ -470,7 +472,8 @@
   // groups
   observer_list_.Notify(
       &SupervisedUserServiceObserver::OnBrowserContentFiltersChanged);
-  // Updates URL filter settings and reclassifies the observed navigations.
+  // Required to emit WebFilterType metrics and reclassifies the observed
+  // navigations.
   UpdateURLFilter();
 }
 
diff --git a/components/supervised_user/core/browser/supervised_user_service_unittest.cc b/components/supervised_user/core/browser/supervised_user_service_unittest.cc
index df60f58..192226b 100644
--- a/components/supervised_user/core/browser/supervised_user_service_unittest.cc
+++ b/components/supervised_user/core/browser/supervised_user_service_unittest.cc
@@ -31,7 +31,6 @@
 namespace supervised_user {
 namespace {
 
-constexpr char kWebFilterTypeHistogramName[] = "FamilyUser.WebFilterType";
 constexpr char kManagedSiteListHistogramName[] = "FamilyUser.ManagedSiteList";
 constexpr char kApprovedSitesCountHistogramName[] =
     "FamilyUser.ManagedSiteListCount.Approved";
@@ -47,155 +46,126 @@
   bool RecordExtensionsMetrics() override { return false; }
 };
 
-class SupervisedUserServiceTestBase : public ::testing::Test {
- public:
-  explicit SupervisedUserServiceTestBase(bool is_supervised) {
-    if (is_supervised) {
-      supervised_user_test_environment_.pref_service()->SetString(
-          prefs::kSupervisedUserId, kChildAccountSUID);
-    } else {
-      supervised_user_test_environment_.pref_service()->ClearPref(
-          prefs::kSupervisedUserId);
-    }
+class SupervisedUserServiceTest : public ::testing::Test {
+ protected:
+  // Explicit environment initialization reduces the number of fixtures.
+  void Initialize(InitialSupervisionState initial_state) {
+    supervised_user_test_environment_ =
+        std::make_unique<SupervisedUserTestEnvironment>(initial_state);
   }
 
-  void TearDown() override { supervised_user_test_environment_.Shutdown(); }
+  void TearDown() override { supervised_user_test_environment_->Shutdown(); }
 
- protected:
+  void SetWebFilterType(WebFilterType web_filter_type) {
+    supervised_user_test_environment_->SetWebFilterType(web_filter_type);
+  }
+
+#if BUILDFLAG(IS_ANDROID)
+  base::test::ScopedFeatureList scoped_feature_list_{
+      kPropagateDeviceContentFiltersToSupervisedUser};
+#endif  // BUILDFLAG(IS_ANDROID)
+
+  base::HistogramTester histogram_tester_;
   base::test::TaskEnvironment task_environment_;
-  SupervisedUserTestEnvironment supervised_user_test_environment_;
-};
-
-class SupervisedUserServiceTest : public SupervisedUserServiceTestBase {
- public:
-  SupervisedUserServiceTest()
-      : SupervisedUserServiceTestBase(/*is_supervised=*/true) {}
+  std::unique_ptr<SupervisedUserTestEnvironment>
+      supervised_user_test_environment_;
 };
 
 // Tests that web approvals are enabled for supervised users.
 TEST_F(SupervisedUserServiceTest, ApprovalRequestsEnabled) {
-  EXPECT_TRUE(supervised_user_test_environment_.service()
+  Initialize(InitialSupervisionState::kFamilyLinkDefault);
+  EXPECT_TRUE(supervised_user_test_environment_->service()
                   ->remote_web_approvals_manager()
                   .AreApprovalRequestsEnabled());
 }
 
 // Tests that restricting all site navigation is applied to supervised users.
 TEST_F(SupervisedUserServiceTest, UrlIsBlockedForUser) {
-  supervised_user_test_environment_.SetWebFilterType(
-      WebFilterType::kCertainSites);
-  EXPECT_TRUE(supervised_user_test_environment_.url_filter()
+  Initialize(InitialSupervisionState::kFamilyLinkCertainSites);
+  EXPECT_TRUE(supervised_user_test_environment_->url_filter()
                   ->GetFilteringBehavior(GURL("http://google.com"))
                   .IsBlocked());
 }
 
 // Tests that allowing all site navigation is applied to supervised users.
 TEST_F(SupervisedUserServiceTest, UrlIsAllowedForUser) {
-  supervised_user_test_environment_.SetWebFilterType(
-      WebFilterType::kAllowAllSites);
-  EXPECT_TRUE(supervised_user_test_environment_.url_filter()
+  Initialize(InitialSupervisionState::kFamilyLinkAllowAllSites);
+  EXPECT_TRUE(supervised_user_test_environment_->url_filter()
                   ->GetFilteringBehavior(GURL("http://google.com"))
                   .IsAllowed());
 }
 
-// Tests that changes in parent configuration for web filter types are recorded.
-TEST_F(SupervisedUserServiceTest, WebFilterTypeOnPrefsChange) {
-  base::HistogramTester histogram_tester;
-
-  supervised_user_test_environment_.SetWebFilterType(
-      WebFilterType::kTryToBlockMatureSites);
-  histogram_tester.ExpectUniqueSample(kWebFilterTypeHistogramName,
-                                      /*sample=*/
-                                      WebFilterType::kTryToBlockMatureSites,
-                                      /*expected_bucket_count=*/0);
-
-  supervised_user_test_environment_.SetWebFilterType(
-      WebFilterType::kAllowAllSites);
-  histogram_tester.ExpectBucketCount(kWebFilterTypeHistogramName,
-                                     /*sample=*/
-                                     WebFilterType::kAllowAllSites,
-                                     /*expected_count=*/1);
-
-  supervised_user_test_environment_.SetWebFilterType(
-      WebFilterType::kCertainSites);
-  histogram_tester.ExpectBucketCount(kWebFilterTypeHistogramName,
-                                     /*sample=*/
-                                     WebFilterType::kCertainSites,
-                                     /*expected_count=*/1);
-  histogram_tester.ExpectTotalCount(kWebFilterTypeHistogramName,
-                                    /*expected_count=*/2);
-}
-
 // Tests that changes to the allow or blocklist of the parent configuration are
 // recorded.
 TEST_F(SupervisedUserServiceTest, ManagedSiteListTypeMetricOnPrefsChange) {
-  base::HistogramTester histogram_tester;
+  Initialize(InitialSupervisionState::kFamilyLinkDefault);
+  // Check post-initialization counts of FamilyUser metrics.
+  histogram_tester_.ExpectBucketCount(kApprovedSitesCountHistogramName,
+                                      /*sample=*/0, /*expected_count=*/1);
+  histogram_tester_.ExpectBucketCount(kBlockedSitesCountHistogramName,
+                                      /*sample=*/0, /*expected_count=*/1);
 
-  supervised_user_test_environment_.SetWebFilterType(
-      WebFilterType::kAllowAllSites);
+  SetWebFilterType(WebFilterType::kAllowAllSites);
   // Blocks `kExampleUrl0`.
-  supervised_user_test_environment_.SetManualFilterForHost(kExampleUrl0, false);
+  supervised_user_test_environment_->SetManualFilterForHost(kExampleUrl0,
+                                                            false);
 
-  histogram_tester.ExpectBucketCount(
+  histogram_tester_.ExpectBucketCount(
       kManagedSiteListHistogramName,
       /*sample=*/
       SupervisedUserURLFilter::ManagedSiteList::kBlockedListOnly,
       /*expected_count=*/1);
-  histogram_tester.ExpectBucketCount(kApprovedSitesCountHistogramName,
-                                     /*sample=*/0, /*expected_count=*/1);
-  histogram_tester.ExpectBucketCount(kBlockedSitesCountHistogramName,
-                                     /*sample=*/1, /*expected_count=*/1);
+  histogram_tester_.ExpectBucketCount(kApprovedSitesCountHistogramName,
+                                      /*sample=*/0, /*expected_count=*/2);
+  histogram_tester_.ExpectBucketCount(kBlockedSitesCountHistogramName,
+                                      /*sample=*/1, /*expected_count=*/1);
 
-  // Approves `kExampleUrl0`.
-  supervised_user_test_environment_.SetManualFilterForHost(kExampleUrl0, true);
-
-  histogram_tester.ExpectBucketCount(
+  // Unblocks and approves `kExampleUrl0`.
+  supervised_user_test_environment_->SetManualFilterForHost(kExampleUrl0, true);
+  histogram_tester_.ExpectBucketCount(
       kManagedSiteListHistogramName,
       /*sample=*/
       SupervisedUserURLFilter::ManagedSiteList::kApprovedListOnly,
       /*expected_count=*/1);
-  histogram_tester.ExpectBucketCount(kApprovedSitesCountHistogramName,
-                                     /*sample=*/1, /*expected_count=*/1);
-  histogram_tester.ExpectBucketCount(kBlockedSitesCountHistogramName,
-                                     /*sample=*/0, /*expected_count=*/1);
+  histogram_tester_.ExpectBucketCount(kApprovedSitesCountHistogramName,
+                                      /*sample=*/1, /*expected_count=*/1);
+  histogram_tester_.ExpectBucketCount(kBlockedSitesCountHistogramName,
+                                      /*sample=*/0, /*expected_count=*/2);
 
   // Blocks `kExampleURL1`.
-  supervised_user_test_environment_.SetManualFilterForHost(kExampleUrl1, false);
+  ASSERT_NE(kExampleUrl0, kExampleUrl1);
+  supervised_user_test_environment_->SetManualFilterForHost(kExampleUrl1,
+                                                            false);
 
-  histogram_tester.ExpectBucketCount(
+  histogram_tester_.ExpectBucketCount(
       kManagedSiteListHistogramName,
       /*sample=*/
       SupervisedUserURLFilter::ManagedSiteList::kBoth,
       /*expected_count=*/1);
-  histogram_tester.ExpectBucketCount(kApprovedSitesCountHistogramName,
-                                     /*sample=*/1, /*expected_count=*/2);
-  histogram_tester.ExpectBucketCount(kBlockedSitesCountHistogramName,
-                                     /*sample=*/1, /*expected_count=*/2);
+  histogram_tester_.ExpectBucketCount(kApprovedSitesCountHistogramName,
+                                      /*sample=*/1, /*expected_count=*/2);
+  histogram_tester_.ExpectBucketCount(kBlockedSitesCountHistogramName,
+                                      /*sample=*/1, /*expected_count=*/2);
 
-  histogram_tester.ExpectTotalCount(kManagedSiteListHistogramName,
-                                    /*expected_count=*/3);
-  histogram_tester.ExpectTotalCount(kApprovedSitesCountHistogramName,
-                                    /*expected_count=*/3);
-  histogram_tester.ExpectTotalCount(kBlockedSitesCountHistogramName,
-                                    /*expected_count=*/3);
+  // 4 transitions: initial, 2 * kExampleUrl0 and 1 * kExampleUrl1.
+  histogram_tester_.ExpectTotalCount(kManagedSiteListHistogramName,
+                                     /*expected_count=*/4);
+  histogram_tester_.ExpectTotalCount(kApprovedSitesCountHistogramName,
+                                     /*expected_count=*/4);
+  histogram_tester_.ExpectTotalCount(kBlockedSitesCountHistogramName,
+                                     /*expected_count=*/4);
 }
 
-class SupervisedUserServiceTestUnsupervised
-    : public SupervisedUserServiceTestBase {
+class SupervisedUserServiceTestUnsupervised : public SupervisedUserServiceTest {
  public:
-  SupervisedUserServiceTestUnsupervised()
-      : SupervisedUserServiceTestBase(/*is_supervised=*/false) {}
-
- private:
-#if BUILDFLAG(IS_ANDROID)
- private:
-  base::test::ScopedFeatureList scoped_feature_list_{
-      kPropagateDeviceContentFiltersToSupervisedUser};
-#endif  // BUILDFLAG(IS_ANDROID)
+  SupervisedUserServiceTestUnsupervised() {
+    Initialize(InitialSupervisionState::kUnsupervised);
+  }
 };
 
 // Tests that web approvals are not enabled for unsupervised users.
 TEST_F(SupervisedUserServiceTestUnsupervised, ApprovalRequestsDisabled) {
-  EXPECT_FALSE(supervised_user_test_environment_.service()
+  EXPECT_FALSE(supervised_user_test_environment_->service()
                    ->remote_web_approvals_manager()
                    .AreApprovalRequestsEnabled());
 }
@@ -203,93 +173,300 @@
 // Tests that supervision restrictions do not apply to unsupervised users.
 TEST_F(SupervisedUserServiceTestUnsupervised,
        CantRequestUrlClassificationBlocking) {
-  supervised_user_test_environment_.SetWebFilterType(
-      WebFilterType::kCertainSites);
-  EXPECT_EQ(static_cast<int>(FilteringBehavior::kAllow),
-            supervised_user_test_environment_.pref_service()->GetInteger(
-                prefs::kDefaultSupervisedUserFilteringBehavior))
-      << "Check why supervised user service received "
-         "WebFilterType::kCertainSites change (FilteringBehavior::kBlock)";
+  SetWebFilterType(WebFilterType::kCertainSites);
 
-  EXPECT_FALSE(supervised_user_test_environment_.service()->IsBlockedURL(
+  EXPECT_TRUE(
+      supervised_user_test_environment_->pref_service()
+          ->FindPreference(prefs::kDefaultSupervisedUserFilteringBehavior)
+          ->IsDefaultValue())
+      << "With supervision disabled, the pref should be"
+         " reset to default.";
+  EXPECT_EQ(static_cast<int>(FilteringBehavior::kAllow),
+            supervised_user_test_environment_->pref_service()->GetInteger(
+                prefs::kDefaultSupervisedUserFilteringBehavior));
+
+  EXPECT_FALSE(supervised_user_test_environment_->service()->IsBlockedURL(
       GURL("http://google.com")));
 }
 
 // Tests that supervision restrictions do not apply to unsupervised users.
 TEST_F(SupervisedUserServiceTestUnsupervised,
        CantRequestTryToFilterClassificationViaFamilyLink) {
-  supervised_user_test_environment_.SetWebFilterType(
-      WebFilterType::kTryToBlockMatureSites);
-  EXPECT_EQ(static_cast<int>(FilteringBehavior::kAllow),
-            supervised_user_test_environment_.pref_service()->GetInteger(
-                prefs::kDefaultSupervisedUserFilteringBehavior));
-  EXPECT_FALSE(supervised_user_test_environment_.pref_service()->GetBoolean(
+  SetWebFilterType(WebFilterType::kTryToBlockMatureSites);
+
+  EXPECT_TRUE(supervised_user_test_environment_->pref_service()
+                  ->FindPreference(prefs::kSupervisedUserSafeSites)
+                  ->IsDefaultValue())
+      << "With supervision disabled, the pref should be "
+         "reset to default.";
+  EXPECT_FALSE(supervised_user_test_environment_->pref_service()->GetBoolean(
       prefs::kSupervisedUserSafeSites));
 
-  EXPECT_FALSE(supervised_user_test_environment_.service()->IsBlockedURL(
+  EXPECT_FALSE(supervised_user_test_environment_->service()->IsBlockedURL(
       GURL("http://google.com")));
 }
 
-// This checks verifies whether single profile can cycle through the all types
-// of supervision.
-TEST_F(SupervisedUserServiceTestUnsupervised, CyclesThroughFilteringSettings) {
-  ASSERT_EQ(WebFilterType::kDisabled,
-            supervised_user_test_environment_.url_filter()->GetWebFilterType());
-
-#if BUILDFLAG(IS_ANDROID)
-  // Browser content filtering is functionally equivalent to
-  // WebFilterType::kTryToBlockMatureSites with empty manual allow and
-  // blocklists.
-  supervised_user_test_environment_.service()
-      ->browser_content_filters_observer_weak_ptr()
-      ->SetEnabled(true);
-  EXPECT_EQ(WebFilterType::kTryToBlockMatureSites,
-            supervised_user_test_environment_.url_filter()->GetWebFilterType());
-
-  supervised_user_test_environment_.service()
-      ->browser_content_filters_observer_weak_ptr()
-      ->SetEnabled(false);
-  EXPECT_EQ(WebFilterType::kDisabled,
-            supervised_user_test_environment_.url_filter()->GetWebFilterType());
-#endif  // BUILDFLAG(IS_ANDROID)
-
-  // "Try to block mature sites" is the default setting for child accounts
-  // (profiles supervised by the Family Link).
-  EnableParentalControls(*supervised_user_test_environment_.pref_service());
-  EXPECT_EQ(WebFilterType::kTryToBlockMatureSites,
-            supervised_user_test_environment_.url_filter()->GetWebFilterType());
-
-  // Once Family Link parental controls are enabled, more settings are
-  // available:
-  supervised_user_test_environment_.SetWebFilterType(
-      WebFilterType::kAllowAllSites);
-  EXPECT_EQ(WebFilterType::kAllowAllSites,
-            supervised_user_test_environment_.url_filter()->GetWebFilterType());
-
-  supervised_user_test_environment_.SetWebFilterType(
-      WebFilterType::kCertainSites);
-  EXPECT_EQ(WebFilterType::kCertainSites,
-            supervised_user_test_environment_.url_filter()->GetWebFilterType());
-
-  supervised_user_test_environment_.SetWebFilterType(
-      WebFilterType::kTryToBlockMatureSites);
-  EXPECT_EQ(WebFilterType::kTryToBlockMatureSites,
-            supervised_user_test_environment_.url_filter()->GetWebFilterType());
-
-  // Finally, turn all controls and bring back to defaults.
-  DisableParentalControls(*supervised_user_test_environment_.pref_service());
-  EXPECT_EQ(WebFilterType::kDisabled,
-            supervised_user_test_environment_.url_filter()->GetWebFilterType());
-}
-
 // Tests that supervision restrictions do not apply to unsupervised users.
 TEST_F(SupervisedUserServiceTestUnsupervised, UrlIsAllowedForUser) {
-  supervised_user_test_environment_.SetWebFilterType(
-      WebFilterType::kCertainSites);
-  EXPECT_FALSE(supervised_user_test_environment_.service()->IsBlockedURL(
+  SetWebFilterType(WebFilterType::kCertainSites);
+  EXPECT_FALSE(supervised_user_test_environment_->service()->IsBlockedURL(
       GURL("http://google.com")));
 }
 
+// This test suite verifies how web filter type changes are propagated from this
+// service to the metrics service.
+class SupervisedUserServiceWebFilterTypeTransitionsTest
+    : public SupervisedUserServiceTest {
+ protected:
+  WebFilterType GetWebFilterType() {
+    return supervised_user_test_environment_->service()
+        ->GetURLFilter()
+        ->GetWebFilterType();
+  }
+};
+
+// Transitions between Family Link supervision states. There is 1 unsupervised
+// state and 3 states of web filter type for Family Link. Each state can
+// transition to any other state. "FamilyUser.WebFilterType" is a legacy
+// histogram but is still asserted.
+class SupervisedUserServiceFamilyLinkWebFilterTypeTransitionsTest
+    : public SupervisedUserServiceWebFilterTypeTransitionsTest {
+ protected:
+  void EnableParentalControls() {
+    ::supervised_user::EnableParentalControls(
+        *supervised_user_test_environment_->pref_service_syncable());
+  }
+
+  void DisableParentalControls() {
+    ::supervised_user::DisableParentalControls(
+        *supervised_user_test_environment_->pref_service_syncable());
+  }
+};
+
+TEST_F(SupervisedUserServiceFamilyLinkWebFilterTypeTransitionsTest,
+       FromUnsupervisedToSupervisedWithAllowAllSites) {
+  // Set initial state to unsupervised. Web filter type is dormant.
+  Initialize(InitialSupervisionState::kUnsupervised);
+  SetWebFilterType(WebFilterType::kAllowAllSites);
+
+  // Filter is disabled, but unsupervised users don't report the metric.
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kDisabled);
+  histogram_tester_.ExpectTotalCount("FamilyUser.WebFilterType", 0);
+
+  EnableParentalControls();
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kAllowAllSites);
+  histogram_tester_.ExpectBucketCount("FamilyUser.WebFilterType",
+                                      WebFilterType::kAllowAllSites, 1);
+
+  // Disable parental controls. No more metrics are emitted.
+  DisableParentalControls();
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kDisabled);
+  histogram_tester_.ExpectTotalCount("FamilyUser.WebFilterType", 1);
+}
+
+TEST_F(SupervisedUserServiceFamilyLinkWebFilterTypeTransitionsTest,
+       FromUnsupervisedToSupervisedWithCertainSites) {
+  // Set initial state to unsupervised. Web filter type is dormant.
+  Initialize(InitialSupervisionState::kUnsupervised);
+  SetWebFilterType(WebFilterType::kCertainSites);
+
+  // Filter is disabled, but unsupervised users don't report the metric.
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kDisabled);
+  histogram_tester_.ExpectTotalCount("FamilyUser.WebFilterType", 0);
+
+  EnableParentalControls();
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kCertainSites);
+  histogram_tester_.ExpectBucketCount("FamilyUser.WebFilterType",
+                                      WebFilterType::kCertainSites, 1);
+
+  // Disable parental controls. No more metrics are emitted.
+  DisableParentalControls();
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kDisabled);
+  histogram_tester_.ExpectTotalCount("FamilyUser.WebFilterType", 1);
+}
+
+TEST_F(SupervisedUserServiceFamilyLinkWebFilterTypeTransitionsTest,
+       FromUnsupervisedToSupervised) {
+  // Set initial state to unsupervised.
+  Initialize(InitialSupervisionState::kUnsupervised);
+
+  // Filter is disabled, but unsupervised users don't report the metric.
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kDisabled);
+  histogram_tester_.ExpectTotalCount("FamilyUser.WebFilterType", 0);
+
+  EnableParentalControls();
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kTryToBlockMatureSites);
+  histogram_tester_.ExpectBucketCount("FamilyUser.WebFilterType",
+                                      WebFilterType::kTryToBlockMatureSites, 1);
+
+  // Disable parental controls. No more metrics are emitted.
+  DisableParentalControls();
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kDisabled);
+  histogram_tester_.ExpectTotalCount("FamilyUser.WebFilterType", 1);
+}
+
+TEST_F(SupervisedUserServiceFamilyLinkWebFilterTypeTransitionsTest,
+       FromTryToBlockMatureSitesToAllowAllSites) {
+  // Set initial state to supervised with try to block mature sites.
+  Initialize(InitialSupervisionState::kFamilyLinkTryToBlockMatureSites);
+
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kTryToBlockMatureSites);
+  histogram_tester_.ExpectBucketCount("FamilyUser.WebFilterType",
+                                      WebFilterType::kTryToBlockMatureSites, 1);
+
+  SetWebFilterType(WebFilterType::kAllowAllSites);
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kAllowAllSites);
+  histogram_tester_.ExpectBucketCount("FamilyUser.WebFilterType",
+                                      WebFilterType::kAllowAllSites, 1);
+
+  SetWebFilterType(WebFilterType::kTryToBlockMatureSites);
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kTryToBlockMatureSites);
+  histogram_tester_.ExpectBucketCount("FamilyUser.WebFilterType",
+                                      WebFilterType::kTryToBlockMatureSites, 2);
+
+  histogram_tester_.ExpectTotalCount("FamilyUser.WebFilterType", 3);
+}
+
+TEST_F(SupervisedUserServiceFamilyLinkWebFilterTypeTransitionsTest,
+       FromAllowAllSitesToCertainSites) {
+  // Set initial state to supervised with try to block mature sites.
+  Initialize(InitialSupervisionState::kFamilyLinkAllowAllSites);
+
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kAllowAllSites);
+  histogram_tester_.ExpectBucketCount("FamilyUser.WebFilterType",
+                                      WebFilterType::kAllowAllSites, 1);
+
+  SetWebFilterType(WebFilterType::kCertainSites);
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kCertainSites);
+  histogram_tester_.ExpectBucketCount("FamilyUser.WebFilterType",
+                                      WebFilterType::kCertainSites, 1);
+
+  SetWebFilterType(WebFilterType::kAllowAllSites);
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kAllowAllSites);
+  histogram_tester_.ExpectBucketCount("FamilyUser.WebFilterType",
+                                      WebFilterType::kAllowAllSites, 2);
+
+  histogram_tester_.ExpectTotalCount("FamilyUser.WebFilterType", 3);
+}
+
+TEST_F(SupervisedUserServiceFamilyLinkWebFilterTypeTransitionsTest,
+       FromTryToBlockMatureSitesToCertainSites) {
+  // Set initial state to supervised with try to block mature sites.
+  Initialize(InitialSupervisionState::kFamilyLinkTryToBlockMatureSites);
+
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kTryToBlockMatureSites);
+  histogram_tester_.ExpectBucketCount("FamilyUser.WebFilterType",
+                                      WebFilterType::kTryToBlockMatureSites, 1);
+
+  SetWebFilterType(WebFilterType::kCertainSites);
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kCertainSites);
+  histogram_tester_.ExpectBucketCount("FamilyUser.WebFilterType",
+                                      WebFilterType::kCertainSites, 1);
+
+  SetWebFilterType(WebFilterType::kTryToBlockMatureSites);
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kTryToBlockMatureSites);
+  histogram_tester_.ExpectBucketCount("FamilyUser.WebFilterType",
+                                      WebFilterType::kTryToBlockMatureSites, 2);
+
+  histogram_tester_.ExpectTotalCount("FamilyUser.WebFilterType", 3);
+}
+
+#if BUILDFLAG(IS_ANDROID)
+// Transitions between local supervision states. There are two boolean filters,
+// so there are 4 states in total. Transitions that change only one filter at a
+// time are possible, both ways.
+class SupervisedUserServiceLocallySupervisedWebFilterTypeTransitionsTest
+    : public SupervisedUserServiceWebFilterTypeTransitionsTest {
+ protected:
+  void SetBrowserFilterEnabled(bool enabled) {
+    supervised_user_test_environment_->browser_content_filters_observer()
+        ->SetEnabled(enabled);
+  }
+  void SetSearchFilterEnabled(bool enabled) {
+    supervised_user_test_environment_->search_content_filters_observer()
+        ->SetEnabled(enabled);
+  }
+  bool IsSupervisedLocally() const {
+    return supervised_user_test_environment_->service()->IsSupervisedLocally();
+  }
+};
+
+// All enabled -> only browser filter enabled -> all disabled -> only search
+// filter enabled.
+TEST_F(SupervisedUserServiceLocallySupervisedWebFilterTypeTransitionsTest,
+       AllToBrowserToNoneToSearchToAll) {
+  Initialize(InitialSupervisionState::kSupervisedWithAllContentFilters);
+  EXPECT_TRUE(IsSupervisedLocally());
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kTryToBlockMatureSites);
+  histogram_tester_.ExpectBucketCount("FamilyUser.WebFilterType",
+                                      WebFilterType::kTryToBlockMatureSites, 1);
+
+  // Leaves only browser filter enabled - no change in web filter type.
+  SetSearchFilterEnabled(false);
+  EXPECT_TRUE(IsSupervisedLocally());
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kTryToBlockMatureSites);
+  histogram_tester_.ExpectTotalCount("FamilyUser.WebFilterType", 1);
+
+  // All filters disabled. Disabling supervision won't yield WebFilterType
+  // metric.
+  SetBrowserFilterEnabled(false);
+  EXPECT_FALSE(IsSupervisedLocally());
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kDisabled);
+  histogram_tester_.ExpectTotalCount("FamilyUser.WebFilterType", 1);
+
+  // Supervision is back on, but the browser filter is still disabled. This time
+  // WebFilterType metric is emitted to indicate disabled filter setting.
+  SetSearchFilterEnabled(true);
+  EXPECT_TRUE(IsSupervisedLocally());
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kDisabled);
+  histogram_tester_.ExpectBucketCount("FamilyUser.WebFilterType",
+                                      WebFilterType::kDisabled, 1);
+
+  // Back to where we started: both filters enabled.
+  SetBrowserFilterEnabled(true);
+  EXPECT_TRUE(IsSupervisedLocally());
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kTryToBlockMatureSites);
+  histogram_tester_.ExpectBucketCount("FamilyUser.WebFilterType",
+                                      WebFilterType::kTryToBlockMatureSites, 2);
+
+  histogram_tester_.ExpectTotalCount("FamilyUser.WebFilterType", 3);
+}
+
+TEST_F(SupervisedUserServiceLocallySupervisedWebFilterTypeTransitionsTest,
+       NoneToBrowserToAllToSearchToNone) {
+  Initialize(InitialSupervisionState::kUnsupervised);
+  EXPECT_FALSE(IsSupervisedLocally());
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kDisabled);
+  histogram_tester_.ExpectTotalCount("FamilyUser.WebFilterType", 0);
+
+  SetBrowserFilterEnabled(true);
+  EXPECT_TRUE(IsSupervisedLocally());
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kTryToBlockMatureSites);
+  histogram_tester_.ExpectTotalCount("FamilyUser.WebFilterType", 1);
+
+  // All filters enabled
+  SetSearchFilterEnabled(true);
+  EXPECT_TRUE(IsSupervisedLocally());
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kTryToBlockMatureSites);
+  histogram_tester_.ExpectTotalCount("FamilyUser.WebFilterType", 1);
+
+  // Leaves only the search filter enabled - disables browser filter.
+  SetBrowserFilterEnabled(false);
+  EXPECT_TRUE(IsSupervisedLocally());
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kDisabled);
+  histogram_tester_.ExpectBucketCount("FamilyUser.WebFilterType",
+                                      WebFilterType::kDisabled, 1);
+
+  // Back to where we started: unsupervised. Disabling supervision won't yield
+  // WebFilterType metric.
+  SetSearchFilterEnabled(false);
+  EXPECT_FALSE(IsSupervisedLocally());
+  EXPECT_EQ(GetWebFilterType(), WebFilterType::kDisabled);
+  histogram_tester_.ExpectTotalCount("FamilyUser.WebFilterType", 2);
+}
+
+#endif  // BUILDFLAG(IS_ANDROID)
+
 // TODO(crbug.com/1364589): Failing consistently on linux-chromeos-dbg
 // due to failed timezone conversion assertion.
 #if BUILDFLAG(IS_CHROMEOS)
@@ -298,11 +475,12 @@
 #define MAYBE_DeprecatedFilterPolicy DeprecatedFilterPolicy
 #endif
 TEST_F(SupervisedUserServiceTest, MAYBE_DeprecatedFilterPolicy) {
-  ASSERT_EQ(supervised_user_test_environment_.pref_service()->GetInteger(
+  Initialize(InitialSupervisionState::kFamilyLinkDefault);
+  ASSERT_EQ(supervised_user_test_environment_->pref_service()->GetInteger(
                 prefs::kDefaultSupervisedUserFilteringBehavior),
             static_cast<int>(FilteringBehavior::kAllow));
   EXPECT_DCHECK_DEATH(
-      supervised_user_test_environment_.pref_service_syncable()
+      supervised_user_test_environment_->pref_service_syncable()
           ->SetSupervisedUserPref(
               prefs::kDefaultSupervisedUserFilteringBehavior,
               /* SupervisedUserURLFilter::WARN */ base::Value(1)));
diff --git a/components/supervised_user/core/browser/supervised_user_test_environment.cc b/components/supervised_user/core/browser/supervised_user_test_environment.cc
index dc2655c5..e06dde8 100644
--- a/components/supervised_user/core/browser/supervised_user_test_environment.cc
+++ b/components/supervised_user/core/browser/supervised_user_test_environment.cc
@@ -90,11 +90,14 @@
 
 #if BUILDFLAG(IS_ANDROID)
 std::unique_ptr<ContentFiltersObserverBridge>
-CreateFakeContentFiltersObserverBridge(std::string_view setting_name,
+CreateFakeContentFiltersObserverBridge(InitialSupervisionState initial_state,
+                                       std::string_view setting_name,
                                        base::RepeatingClosure on_enabled,
                                        base::RepeatingClosure on_disabled) {
   return std::make_unique<FakeContentFiltersObserverBridge>(
-      setting_name, on_enabled, on_disabled);
+      setting_name, on_enabled, on_disabled,
+      /*enabled=*/initial_state ==
+          InitialSupervisionState::kSupervisedWithAllContentFilters);
 }
 #endif
 }  // namespace
@@ -112,6 +115,7 @@
       syncer::SUPERVISED_USER_SETTINGS, syncer::SyncDataList(),
       std::unique_ptr<syncer::SyncChangeProcessor>(
           new syncer::FakeSyncChangeProcessor));
+
   return settings_service;
 }
 
@@ -152,6 +156,34 @@
 SupervisedUserPrefStoreTestEnvironment::
     ~SupervisedUserPrefStoreTestEnvironment() = default;
 
+void SupervisedUserPrefStoreTestEnvironment::ConfigureInitialValues(
+    InitialSupervisionState initial_state) {
+  // These initial states indicate that the user is supervised, so the main pref
+  // must be set.
+  switch (initial_state) {
+    case InitialSupervisionState::kFamilyLinkDefault:
+    case InitialSupervisionState::kFamilyLinkTryToBlockMatureSites:
+      EnableParentalControls(*syncable_pref_service_);
+      break;
+    case InitialSupervisionState::kFamilyLinkAllowAllSites:
+      EnableParentalControls(*syncable_pref_service_);
+      settings_service_.SetLocalSetting(supervised_user::kSafeSitesEnabled,
+                                       base::Value(false));
+      break;
+    case InitialSupervisionState::kFamilyLinkCertainSites:
+      EnableParentalControls(*syncable_pref_service_);
+      settings_service_.SetLocalSetting(supervised_user::kSafeSitesEnabled,
+                                       base::Value(false));
+      settings_service_.SetLocalSetting(
+          supervised_user::kContentPackDefaultFilteringBehavior,
+          base::Value(
+              static_cast<int>(supervised_user::FilteringBehavior::kBlock)));
+      break;
+    default:
+      break;
+  }
+}
+
 void SupervisedUserPrefStoreTestEnvironment::Shutdown() {
   settings_service_.Shutdown();
 }
@@ -170,28 +202,32 @@
   return syncable_pref_service_.get();
 }
 
-SupervisedUserTestEnvironment::SupervisedUserTestEnvironment()
+SupervisedUserTestEnvironment::SupervisedUserTestEnvironment(
+    InitialSupervisionState initial_state)
     : SupervisedUserTestEnvironment(
-          std::make_unique<MetricsServiceAccessorDelegateMock>()) {}
+          std::make_unique<MetricsServiceAccessorDelegateMock>(),
+          initial_state) {}
 
 SupervisedUserTestEnvironment::SupervisedUserTestEnvironment(
     std::unique_ptr<MetricsServiceAccessorDelegateMock>
-        metrics_service_accessor_delegate) {
+        metrics_service_accessor_delegate,
+    InitialSupervisionState initial_state) {
   std::unique_ptr<safe_search_api::FakeURLCheckerClient> client =
       std::make_unique<safe_search_api::FakeURLCheckerClient>();
   url_checker_client_ = client.get();
 
+  pref_store_environment_.ConfigureInitialValues(initial_state);
+
   service_ = std::make_unique<TestSupervisedUserService>(
       identity_test_env_.identity_manager(),
       test_url_loader_factory_.GetSafeWeakWrapper(),
       *pref_store_environment_.pref_service(),
       *pref_store_environment_.settings_service(),
-      pref_store_environment_.content_filters_service(),
-      &sync_service_,
+      pref_store_environment_.content_filters_service(), &sync_service_,
       std::make_unique<SupervisedUserURLFilter>(
           *pref_store_environment_.pref_service(),
           std::make_unique<FakeURLFilterDelegate>(), std::move(client)),
-      std::make_unique<FakePlatformDelegate>());
+      std::make_unique<FakePlatformDelegate>(), initial_state);
   metrics_service_ = std::make_unique<SupervisedUserMetricsService>(
       pref_store_environment_.pref_service(), *service_.get(),
       std::make_unique<SupervisedUserMetricsServiceExtensionDelegateFake>(),
@@ -324,7 +360,9 @@
 FakeContentFiltersObserverBridge::~FakeContentFiltersObserverBridge() = default;
 
 void FakeContentFiltersObserverBridge::Init() {
+  // Imitates behavior of the real bridge: it always notifies on creation.
   SetEnabled(initial_value_);
+  OnChange(/*env=*/nullptr, initial_value_);
 }
 
 void FakeContentFiltersObserverBridge::Shutdown() {
@@ -332,6 +370,12 @@
 }
 
 void FakeContentFiltersObserverBridge::SetEnabled(bool enabled) {
+  // Imitates behavior of the real bridge: it does not notify if the value
+  // did not change.
+  if (enabled == IsEnabled()) {
+    return;
+  }
+
   ContentFiltersObserverBridge::SetEnabled(enabled);
   // This is fine: JNIEnv is not used, because OnChange notifies native code.
   OnChange(/*env=*/nullptr, enabled);
@@ -356,7 +400,8 @@
     SupervisedUserContentFiltersService* content_filters_service,
     syncer::SyncService* sync_service,
     std::unique_ptr<SupervisedUserURLFilter> url_filter,
-    std::unique_ptr<SupervisedUserService::PlatformDelegate> platform_delegate)
+    std::unique_ptr<SupervisedUserService::PlatformDelegate> platform_delegate,
+    InitialSupervisionState initial_state)
     : SupervisedUserService(
           identity_manager,
           url_loader_factory,
@@ -368,7 +413,8 @@
           std::move(platform_delegate)
 #if BUILDFLAG(IS_ANDROID)
               ,
-          base::BindRepeating(&CreateFakeContentFiltersObserverBridge)
+          base::BindRepeating(&CreateFakeContentFiltersObserverBridge,
+                              initial_state)
 #endif
       ) {
 }
diff --git a/components/supervised_user/core/browser/supervised_user_test_environment.h b/components/supervised_user/core/browser/supervised_user_test_environment.h
index 6472485..b12e074 100644
--- a/components/supervised_user/core/browser/supervised_user_test_environment.h
+++ b/components/supervised_user/core/browser/supervised_user_test_environment.h
@@ -29,6 +29,20 @@
 
 namespace supervised_user {
 
+// Handy set of initial states of supervision stack, to preset before testing.
+enum class InitialSupervisionState : int {
+  // Default mode, no supervision, no content filters at startup.
+  kUnsupervised,
+  // Enable family link, and use defaults.
+  kFamilyLinkDefault,
+  // Enable family link and set specific initial settings.
+  kFamilyLinkAllowAllSites,
+  kFamilyLinkTryToBlockMatureSites,
+  kFamilyLinkCertainSites,
+  // Local supervision startup states.
+  kSupervisedWithAllContentFilters,
+};
+
 // Launches the service from empty settings, typically during context
 // initialization.
 SupervisedUserSettingsService* InitializeSettingsServiceForTesting(
@@ -56,6 +70,10 @@
 
   void Shutdown();
 
+  // Sets initial values in components like pref service and content filters
+  // before services are created.
+  void ConfigureInitialValues(InitialSupervisionState initial_state);
+
  private:
   SupervisedUserSettingsService settings_service_;
   SupervisedUserContentFiltersService content_filters_service_;
@@ -130,7 +148,8 @@
 #endif  // BUILDFLAG(IS_ANDROID)
 
 // Offers access to the protected constructor of SupervisedUserService, used
-// to inject fake content filters observers.
+// to inject fake content filters observers (with initial values described in
+// initial_state)
 class TestSupervisedUserService : public SupervisedUserService {
  public:
   // Matching constructor of SupervisedUserService.
@@ -143,7 +162,9 @@
       syncer::SyncService* sync_service,
       std::unique_ptr<SupervisedUserURLFilter> url_filter,
       std::unique_ptr<SupervisedUserService::PlatformDelegate>
-          platform_delegate);
+          platform_delegate,
+      InitialSupervisionState initial_state =
+          InitialSupervisionState::kUnsupervised);
 
 #if BUILDFLAG(IS_ANDROID)
   base::WeakPtr<FakeContentFiltersObserverBridge>
@@ -160,10 +181,15 @@
 // base::test::TaskEnvironment), and requires that Shutdown() is called.
 class SupervisedUserTestEnvironment {
  public:
-  SupervisedUserTestEnvironment();
+  explicit SupervisedUserTestEnvironment(
+      InitialSupervisionState initial_state =
+          InitialSupervisionState::kUnsupervised);
   explicit SupervisedUserTestEnvironment(
       std::unique_ptr<MetricsServiceAccessorDelegateMock>
-          metrics_service_accessor_delegate);
+          metrics_service_accessor_delegate,
+      InitialSupervisionState initial_state =
+          InitialSupervisionState::kUnsupervised);
+
   SupervisedUserTestEnvironment(const SupervisedUserTestEnvironment&) = delete;
   SupervisedUserTestEnvironment& operator=(
       const SupervisedUserTestEnvironment&) = delete;
diff --git a/components/user_data_importer/OWNERS b/components/user_data_importer/OWNERS
index af5a108..0ae02327 100644
--- a/components/user_data_importer/OWNERS
+++ b/components/user_data_importer/OWNERS
@@ -1,2 +1,4 @@
+fsenra@google.com
 sugoi@chromium.org
 tmartino@chromium.org
+treib@chromium.org
diff --git a/components/user_data_importer/content/stable_portability_data_importer.cc b/components/user_data_importer/content/stable_portability_data_importer.cc
index e7e3520..6eb9d18 100644
--- a/components/user_data_importer/content/stable_portability_data_importer.cc
+++ b/components/user_data_importer/content/stable_portability_data_importer.cc
@@ -29,13 +29,17 @@
 
 void StablePortabilityDataImporter::
     RustHistoryCallbackForStablePortabilityFormat::ImportHistoryEntries(
-        const std::unique_ptr<std::vector<StablePortabilityHistoryEntry>>
+        std::unique_ptr<std::vector<StablePortabilityHistoryEntry>>
             history_entries,
         bool completed) {
-  transfer_history_callback_.Run(*history_entries);
+  const size_t history_entries_size = history_entries->size();
+  transfer_history_callback_.Run(std::move(*history_entries));
 
   if (completed && done_callback_) {
-    std::move(done_callback_).Run(history_entries->size());
+    // TODO(crbug.com/430253028): Execute the callback with the total number of
+    // history entries imported. As of now, we only return the number of
+    // entries in the last batch.
+    std::move(done_callback_).Run(history_entries_size);
   }
 }
 
@@ -47,9 +51,9 @@
 }
 
 StablePortabilityDataImporter::StablePortabilityDataImporter(
-    history::HistoryService& history_service,
-    bookmarks::BookmarkModel& bookmark_model,
-    ReadingListModel& reading_list_model,
+    history::HistoryService* history_service,
+    bookmarks::BookmarkModel* bookmark_model,
+    ReadingListModel* reading_list_model,
     scoped_refptr<ContentBookmarkParser> bookmark_parser)
     : history_service_(history_service),
       bookmark_model_(bookmark_model),
@@ -157,19 +161,15 @@
 }
 
 void StablePortabilityDataImporter::TransferHistoryEntries(
-    const std::vector<user_data_importer::StablePortabilityHistoryEntry>&
-        history_entries) {
+    std::vector<StablePortabilityHistoryEntry> history_entries) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   // TODO(crbug.com/431204966): Add the history entries to the user's storage.
-  // Also avoid excessive copying of the entries. Furthermore, Consider
-  // reserving memory for the entries before transferring them to avoid
-  // resizing.
-
-  pending_history_entries_.insert(pending_history_entries_.end(),
-                                  history_entries.begin(),
-                                  history_entries.end());
+  pending_history_entries_.insert(
+      pending_history_entries_.end(),
+      std::make_move_iterator(history_entries.begin()),
+      std::make_move_iterator(history_entries.end()));
 }
 
 void StablePortabilityDataImporter::ImportHistory(
diff --git a/components/user_data_importer/content/stable_portability_data_importer.h b/components/user_data_importer/content/stable_portability_data_importer.h
index bbbaf0e..a71d99a 100644
--- a/components/user_data_importer/content/stable_portability_data_importer.h
+++ b/components/user_data_importer/content/stable_portability_data_importer.h
@@ -5,6 +5,7 @@
 #ifndef COMPONENTS_USER_DATA_IMPORTER_CONTENT_STABLE_PORTABILITY_DATA_IMPORTER_H_
 #define COMPONENTS_USER_DATA_IMPORTER_CONTENT_STABLE_PORTABILITY_DATA_IMPORTER_H_
 
+#include "base/memory/raw_ptr.h"
 #include "base/threading/sequence_bound.h"
 #include "components/user_data_importer/content/content_bookmark_parser.h"
 #include "components/user_data_importer/utility/bookmark_parser.h"
@@ -39,10 +40,13 @@
   // bookmarks, reading list items, or urls (for history import).
   using ImportCallback = base::OnceCallback<void(int)>;
 
+  // `history_service`, `bookmark_model`, and `reading_list_model` may be null,
+  // but if non-null must outlive this class. `bookmark_parser` must not be
+  // null.
   StablePortabilityDataImporter(
-      history::HistoryService& history_service,
-      bookmarks::BookmarkModel& bookmark_model,
-      ReadingListModel& reading_list_model,
+      history::HistoryService* history_service,
+      bookmarks::BookmarkModel* bookmark_model,
+      ReadingListModel* reading_list_model,
       scoped_refptr<ContentBookmarkParser> bookmark_parser);
   ~StablePortabilityDataImporter();
 
@@ -71,7 +75,7 @@
             StablePortabilityHistoryEntry> {
    public:
     using TransferHistoryCallback = base::RepeatingCallback<void(
-        const std::vector<user_data_importer::StablePortabilityHistoryEntry>&)>;
+        std::vector<StablePortabilityHistoryEntry>)>;
 
     explicit RustHistoryCallbackForStablePortabilityFormat(
         TransferHistoryCallback transfer_history_callback,
@@ -82,7 +86,7 @@
 
     // Called from Rust when a batch of history entries has been parsed.
     void ImportHistoryEntries(
-        const std::unique_ptr<std::vector<
+        std::unique_ptr<std::vector<
             user_data_importer::StablePortabilityHistoryEntry>> history_entries,
         bool completed) override;
 
@@ -121,8 +125,7 @@
   // Transfers the history entries to the importer. This is used by the Rust
   // History import pipeline to communicate results back to this importer.
   void TransferHistoryEntries(
-      const std::vector<user_data_importer::StablePortabilityHistoryEntry>&
-          history_entries);
+      std::vector<StablePortabilityHistoryEntry> history_entries);
 
   // Receives the result of parsing bookmarks, stores them for later use, and
   // invokes `bookmarks_callback` with the number of parsed bookmarks.
@@ -139,13 +142,13 @@
   void PostCallback(auto callback, auto results);
 
   // Service used to import history URLs.
-  const raw_ref<history::HistoryService> history_service_;
+  const raw_ptr<history::HistoryService> history_service_;
 
   // Service used to import bookmarks.
-  const raw_ref<bookmarks::BookmarkModel> bookmark_model_;
+  const raw_ptr<bookmarks::BookmarkModel> bookmark_model_;
 
   // Service used to import reading list items.
-  const raw_ref<ReadingListModel> reading_list_model_;
+  const raw_ptr<ReadingListModel> reading_list_model_;
 
   SEQUENCE_CHECKER(sequence_checker_);
 
diff --git a/components/user_data_importer/content/stable_portability_data_importer_unittest.cc b/components/user_data_importer/content/stable_portability_data_importer_unittest.cc
index b76b245..b4fdee6 100644
--- a/components/user_data_importer/content/stable_portability_data_importer_unittest.cc
+++ b/components/user_data_importer/content/stable_portability_data_importer_unittest.cc
@@ -51,7 +51,8 @@
         base::DefaultClock::GetInstance());
 
     importer_ = std::make_unique<StablePortabilityDataImporter>(
-        *history_service_, *bookmark_model_, *reading_list_model_,
+        history_service_.get(), bookmark_model_.get(),
+        reading_list_model_.get(),
         base::MakeRefCounted<ContentBookmarkParser>());
   }
 
diff --git a/components/viz/service/gl/gpu_service_impl.cc b/components/viz/service/gl/gpu_service_impl.cc
index 3a733f77..12514a5e 100644
--- a/components/viz/service/gl/gpu_service_impl.cc
+++ b/components/viz/service/gl/gpu_service_impl.cc
@@ -1276,18 +1276,11 @@
   }
   auto size = gfx::Size(2, 2);
 
-  // Note that |gmb_id| and |client_id| does not matter here as this is the
-  // first GMB which will created and immediately destroyed.
-  auto gmb_id = gfx::GpuMemoryBufferId(
-      static_cast<int>(gpu::MappableSIClientGmbId::kGpuServiceImpl));
-  auto client_id = gpu::kMappableSIClientId;
-  auto gmb_handle = gpu_memory_buffer_factory_->CreateGpuMemoryBuffer(
-      gmb_id, size, /*framebuffer_size=*/size, buffer_format, buffer_usage,
-      client_id, gpu::kNullSurfaceHandle);
-
-  // Destroy the gmb_handle since it will be no longer needed.
-  gpu_memory_buffer_factory_->DestroyGpuMemoryBuffer(gmb_id, client_id);
-  return !gmb_handle.is_null();
+  return !gpu_memory_buffer_factory_
+              ->CreateNativeGmbHandle(
+                  gpu::MappableSIClientGmbId::kGpuServiceImpl, size,
+                  buffer_format, buffer_usage)
+              .is_null();
 }
 #endif
 
diff --git a/components/webapps/isolated_web_apps/BUILD.gn b/components/webapps/isolated_web_apps/BUILD.gn
index bc79ea1a..7a23237 100644
--- a/components/webapps/isolated_web_apps/BUILD.gn
+++ b/components/webapps/isolated_web_apps/BUILD.gn
@@ -2,6 +2,9 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+assert(is_chromeos || is_win || is_mac || is_linux,
+       "components/webapps/isolated_web_apps are no-op on Android or iOS.")
+
 # TODO(crbug.com/431980377): Should this be a group()?
 source_set("isolated_web_apps") {
   sources = []
@@ -10,6 +13,7 @@
     ":features",
     ":key_distribution",
     "//base",
+    "//components/webapps/isolated_web_apps/download",
     "//components/webapps/isolated_web_apps/error",
     "//components/webapps/isolated_web_apps/identity",
     "//components/webapps/isolated_web_apps/proto",
@@ -19,14 +23,6 @@
   ]
 }
 
-group("unit_tests") {
-  testonly = true
-  deps = [
-    "//components/webapps/isolated_web_apps/error:unit_tests",
-    "//components/webapps/isolated_web_apps/types:unit_tests",
-  ]
-}
-
 source_set("features") {
   sources = [
     "features.cc",
@@ -62,3 +58,12 @@
     "//url",
   ]
 }
+
+group("unit_tests") {
+  testonly = true
+  deps = [
+    "//components/webapps/isolated_web_apps/download:unit_tests",
+    "//components/webapps/isolated_web_apps/error:unit_tests",
+    "//components/webapps/isolated_web_apps/types:unit_tests",
+  ]
+}
diff --git a/components/webapps/isolated_web_apps/download/BUILD.gn b/components/webapps/isolated_web_apps/download/BUILD.gn
new file mode 100644
index 0000000..9cd92ed
--- /dev/null
+++ b/components/webapps/isolated_web_apps/download/BUILD.gn
@@ -0,0 +1,37 @@
+# Copyright 2025 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("download") {
+  sources = [
+    "bundle_downloader.cc",
+    "bundle_downloader.h",
+  ]
+
+  deps = [
+    "//base",
+    "//net",
+    "//services/network/public/cpp",
+  ]
+
+  public_deps = [
+    "//base",
+    "//url",
+  ]
+}
+
+source_set("unit_tests") {
+  testonly = true
+  sources = [ "bundle_downloader_unittest.cc" ]
+  deps = [
+    ":download",
+    "//base",
+    "//base/test:test_support",
+    "//net",
+    "//net/traffic_annotation:test_support",
+    "//services/network:test_support",
+    "//services/network/public/cpp",
+    "//testing/gmock",
+    "//testing/gtest",
+  ]
+}
diff --git a/components/webapps/isolated_web_apps/download/DEPS b/components/webapps/isolated_web_apps/download/DEPS
new file mode 100644
index 0000000..bc72d8bb
--- /dev/null
+++ b/components/webapps/isolated_web_apps/download/DEPS
@@ -0,0 +1,6 @@
+specific_include_rules = {
+    "bundle_downloader_unittest.cc": [
+        "+services/network/test/test_url_loader_factory.h",
+        "+services/network/test/test_utils.h",
+    ],
+}
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader.cc b/components/webapps/isolated_web_apps/download/bundle_downloader.cc
similarity index 98%
rename from chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader.cc
rename to components/webapps/isolated_web_apps/download/bundle_downloader.cc
index d4cbfa5..7ed6bd2 100644
--- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader.cc
+++ b/components/webapps/isolated_web_apps/download/bundle_downloader.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader.h"
+#include "components/webapps/isolated_web_apps/download/bundle_downloader.h"
 
 #include <memory>
 #include <optional>
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader.h b/components/webapps/isolated_web_apps/download/bundle_downloader.h
similarity index 89%
rename from chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader.h
rename to components/webapps/isolated_web_apps/download/bundle_downloader.h
index 332b2f7..efe68ba 100644
--- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader.h
+++ b/components/webapps/isolated_web_apps/download/bundle_downloader.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_WEB_APPLICATIONS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_DOWNLOADER_H_
-#define CHROME_BROWSER_WEB_APPLICATIONS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_DOWNLOADER_H_
+#ifndef COMPONENTS_WEBAPPS_ISOLATED_WEB_APPS_DOWNLOAD_BUNDLE_DOWNLOADER_H_
+#define COMPONENTS_WEBAPPS_ISOLATED_WEB_APPS_DOWNLOAD_BUNDLE_DOWNLOADER_H_
 
 #include <memory>
 #include <optional>
@@ -12,7 +12,6 @@
 #include "base/files/scoped_temp_file.h"
 #include "base/functional/callback.h"
 #include "base/memory/scoped_refptr.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
 #include "url/gurl.h"
 
 namespace network {
@@ -20,6 +19,10 @@
 class SharedURLLoaderFactory;
 }  // namespace network
 
+namespace net {
+struct PartialNetworkTrafficAnnotationTag;
+}  // namespace net
+
 namespace web_app {
 
 class ScopedTempWebBundleFile {
@@ -94,4 +97,4 @@
 
 }  // namespace web_app
 
-#endif  // CHROME_BROWSER_WEB_APPLICATIONS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_DOWNLOADER_H_
+#endif  // COMPONENTS_WEBAPPS_ISOLATED_WEB_APPS_DOWNLOAD_BUNDLE_DOWNLOADER_H_
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader_unittest.cc b/components/webapps/isolated_web_apps/download/bundle_downloader_unittest.cc
similarity index 97%
rename from chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader_unittest.cc
rename to components/webapps/isolated_web_apps/download/bundle_downloader_unittest.cc
index ecef1542..71e2f18 100644
--- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader_unittest.cc
+++ b/components/webapps/isolated_web_apps/download/bundle_downloader_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader.h"
+#include "components/webapps/isolated_web_apps/download/bundle_downloader.h"
 
 #include <optional>
 #include <string>
diff --git a/content/browser/accessibility/accessibility_mode_browsertest.cc b/content/browser/accessibility/accessibility_mode_browsertest.cc
index 2fbc37d..06a55c2d 100644
--- a/content/browser/accessibility/accessibility_mode_browsertest.cc
+++ b/content/browser/accessibility/accessibility_mode_browsertest.cc
@@ -25,6 +25,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/accessibility/ax_mode.h"
 #include "ui/accessibility/platform/browser_accessibility.h"
+#include "ui/accessibility/platform/browser_accessibility_manager.h"
 
 namespace content {
 
diff --git a/content/browser/accessibility/ax_platform_node_textprovider_win_browsertest.cc b/content/browser/accessibility/ax_platform_node_textprovider_win_browsertest.cc
index 4716fa0d..e341261 100644
--- a/content/browser/accessibility/ax_platform_node_textprovider_win_browsertest.cc
+++ b/content/browser/accessibility/ax_platform_node_textprovider_win_browsertest.cc
@@ -30,6 +30,7 @@
 #include "ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h"
 #include "ui/accessibility/platform/browser_accessibility.h"
 #include "ui/accessibility/platform/browser_accessibility_com_win.h"
+#include "ui/accessibility/platform/browser_accessibility_manager.h"
 
 using Microsoft::WRL::ComPtr;
 
diff --git a/content/browser/accessibility/scoped_accessibility_mode_browsertest.cc b/content/browser/accessibility/scoped_accessibility_mode_browsertest.cc
index bf1d42eb..39f52156 100644
--- a/content/browser/accessibility/scoped_accessibility_mode_browsertest.cc
+++ b/content/browser/accessibility/scoped_accessibility_mode_browsertest.cc
@@ -31,6 +31,7 @@
 #include "ui/accessibility/ax_mode.h"
 #include "ui/accessibility/platform/ax_mode_observer.h"
 #include "ui/accessibility/platform/ax_platform.h"
+#include "ui/accessibility/platform/browser_accessibility_manager.h"
 
 namespace content {
 
diff --git a/content/browser/accessibility/snapshot_ax_tree_browsertest.cc b/content/browser/accessibility/snapshot_ax_tree_browsertest.cc
index 4d6e3121a..00bfc89 100644
--- a/content/browser/accessibility/snapshot_ax_tree_browsertest.cc
+++ b/content/browser/accessibility/snapshot_ax_tree_browsertest.cc
@@ -19,6 +19,7 @@
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/accessibility/ax_enum_util.h"
 #include "ui/accessibility/ax_node.h"
 #include "ui/accessibility/ax_tree.h"
 
diff --git a/content/browser/accessibility/touch_accessibility_aura_browsertest.cc b/content/browser/accessibility/touch_accessibility_aura_browsertest.cc
index 06626f74..686d21ed 100644
--- a/content/browser/accessibility/touch_accessibility_aura_browsertest.cc
+++ b/content/browser/accessibility/touch_accessibility_aura_browsertest.cc
@@ -21,6 +21,7 @@
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/accessibility/platform/browser_accessibility.h"
+#include "ui/accessibility/platform/browser_accessibility_manager.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
 #include "ui/events/event.h"
diff --git a/content/browser/back_forward_cache_internal_browsertest.cc b/content/browser/back_forward_cache_internal_browsertest.cc
index 8e70206..480b8b8 100644
--- a/content/browser/back_forward_cache_internal_browsertest.cc
+++ b/content/browser/back_forward_cache_internal_browsertest.cc
@@ -49,6 +49,7 @@
 #include "ui/accessibility/ax_location_and_scroll_updates.h"
 #include "ui/accessibility/ax_node_id_forward.h"
 #include "ui/accessibility/platform/browser_accessibility.h"
+#include "ui/accessibility/platform/browser_accessibility_manager.h"
 
 // This file contains back/forward-cache tests that test or use internal
 // features, e.g. cache-flushing, crashes, verifying proxies and other
@@ -4478,4 +4479,62 @@
                     FROM_HERE);
 }
 
+class BackForwardCacheBrowserTestReloadHiddenTabsWithActiveCrashedSubframes
+    : public BackForwardCacheBrowserTest {
+ protected:
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    IsolateAllSitesForTesting(base::CommandLine::ForCurrentProcess());
+    EnableFeatureAndSetParams(features::kReloadHiddenTabsWithCrashedSubframes, "", "");
+    EnableFeatureAndSetParams(features::kReloadHiddenTabsWithActiveCrashedSubframes, "", "");
+    BackForwardCacheBrowserTest::SetUpCommandLine(command_line);
+  }
+};
+
+// Test that a subframe renderer process crash does not cause a reload if the
+// subframe is in back-forward cache.
+IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestReloadHiddenTabsWithActiveCrashedSubframes,
+                       ReloadHiddenTabWithCrashedSubframe_BFCached) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+  GURL url_a(embedded_test_server()->GetURL(
+      "a.com", "/cross_site_iframe_factory.html?a(b)"));
+  GURL url_c(embedded_test_server()->GetURL("c.com", "/title1.html"));
+
+  // 1) Navigate to A(B).
+  EXPECT_TRUE(NavigateToURL(shell(), url_a));
+  RenderFrameHostImpl* rfh_a = current_frame_host();
+  RenderFrameHostImpl* rfh_b = rfh_a->child_at(0)->current_frame_host();
+  RenderProcessHost* process_b = rfh_b->GetProcess();
+
+  // 2) Navigate to C. A(B) is in BFCache.
+  EXPECT_TRUE(NavigateToURL(shell(), url_c));
+  EXPECT_TRUE(rfh_a->IsInBackForwardCache());
+  EXPECT_TRUE(rfh_b->IsInBackForwardCache());
+
+  // 3) Hide the tab.
+  web_contents()->UpdateWebContentsVisibility(Visibility::VISIBLE);
+  web_contents()->UpdateWebContentsVisibility(Visibility::HIDDEN);
+  EXPECT_EQ(Visibility::HIDDEN, web_contents()->GetVisibility());
+
+  // 4) Crash process B.
+  RenderProcessHostWatcher crash_observer(
+      process_b, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+  process_b->Shutdown(0);
+  crash_observer.Wait();
+  EXPECT_FALSE(rfh_b->IsRenderFrameLive());
+
+  // 5) The tab should not be marked for reload, because the crashed subframe
+  // was in a BFCached page, which is not considered "active".
+  EXPECT_FALSE(web_contents()->GetController().NeedsReload());
+
+  // 6) Show the tab again but no reload should happen.
+  {
+    base::HistogramTester histograms;
+    web_contents()->UpdateWebContentsVisibility(Visibility::VISIBLE);
+    EXPECT_TRUE(WaitForLoadStop(web_contents()));
+    histograms.ExpectUniqueSample(
+        "Navigation.LoadIfNecessaryType",
+        NavigationControllerImpl::NeedsReloadType::kCrashedSubframe, 0);
+  }
+}
+
 }  // namespace content
diff --git a/content/browser/background_fetch/background_fetch_test_base.cc b/content/browser/background_fetch/background_fetch_test_base.cc
index e197c7c..5f4974f4 100644
--- a/content/browser/background_fetch/background_fetch_test_base.cc
+++ b/content/browser/background_fetch/background_fetch_test_base.cc
@@ -166,7 +166,7 @@
   const GURL scope = GetScopeForId(kTestOrigin, service_worker_registration_id);
   embedded_worker_test_helper_.context()->UnregisterServiceWorker(
       scope, blink::StorageKey::CreateFirstParty(url::Origin::Create(scope)),
-      /*is_immediate=*/false,
+      /*is_immediate=*/false, ServiceWorkerRegistration::DeleteInitiator::kTest,
       base::BindOnce(&DidUnregisterServiceWorker, run_loop.QuitClosure()));
   run_loop.Run();
 }
diff --git a/content/browser/background_sync/background_sync_manager_unittest.cc b/content/browser/background_sync/background_sync_manager_unittest.cc
index 9bef449..539a82f 100644
--- a/content/browser/background_sync/background_sync_manager_unittest.cc
+++ b/content/browser/background_sync/background_sync_manager_unittest.cc
@@ -561,6 +561,7 @@
     helper_->context()->UnregisterServiceWorker(
         scope, blink::StorageKey::CreateFirstParty(url::Origin::Create(scope)),
         /*is_immediate=*/false,
+        ServiceWorkerRegistration::DeleteInitiator::kTest,
         base::BindOnce(&UnregisterServiceWorkerCallback, &called));
     base::RunLoop().RunUntilIdle();
     EXPECT_TRUE(called);
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc
index 4accb4a..289fcf7 100644
--- a/content/browser/indexed_db/indexed_db_browsertest.cc
+++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -21,6 +21,7 @@
 #include "base/rand_util.h"
 #include "base/run_loop.h"
 #include "base/strings/escape.h"
+#include "base/strings/strcat.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/sequenced_task_runner.h"
@@ -43,6 +44,7 @@
 #include "content/browser/blob_storage/chrome_blob_storage_context.h"
 #include "content/browser/browser_main_loop.h"
 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
+#include "content/browser/indexed_db/instance/bucket_context.h"
 #include "content/browser/indexed_db/instance/leveldb/cleanup_scheduler.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/public/browser/browser_context.h"
@@ -74,6 +76,18 @@
 #include "url/gurl.h"
 #include "url/origin.h"
 
+// These macros are used to temporarily disable specific tests for the SQLite
+// backing store.
+// TODO(crbug.com/419272072): Remove after implementing the missing pieces.
+#define DISABLED_FOR_SQLITE_PENDING_FAILURE_INJECTION() \
+  if (using_sqlite_) {                                  \
+    return;                                             \
+  }
+#define DISABLED_FOR_SQLITE_PENDING_USAGE_REPORTING() \
+  if (using_sqlite_) {                                \
+    return;                                           \
+  }
+
 using storage::QuotaManager;
 using storage::mojom::FailClass;
 using storage::mojom::FailMethod;
@@ -82,14 +96,19 @@
 
 namespace {
 
-// This browser test is aimed towards exercising the IndexedDB bindings and
-// the actual implementation that lives in the browser side.
-class IndexedDBBrowserTest : public ContentBrowserTest {
+// Abstract base class that provides common functionality. Tests should use one
+// of the concrete derived classes.
+class IndexedDBBrowserTestBase : public ContentBrowserTest {
  public:
-  IndexedDBBrowserTest() = default;
+  // Derived test classes should specify whether their tests will run on the
+  // SQLite backing store or LevelDB.
+  explicit IndexedDBBrowserTestBase(bool use_sqlite)
+      : using_sqlite_(use_sqlite),
+        sqlite_override_(
+            BucketContext::OverrideShouldUseSqliteForTesting(use_sqlite)) {}
 
-  IndexedDBBrowserTest(const IndexedDBBrowserTest&) = delete;
-  IndexedDBBrowserTest& operator=(const IndexedDBBrowserTest&) = delete;
+  IndexedDBBrowserTestBase(const IndexedDBBrowserTestBase&) = delete;
+  IndexedDBBrowserTestBase& operator=(const IndexedDBBrowserTestBase&) = delete;
 
   void SetUpOnMainThread() override {
     // Some tests need more space than the default used for browser tests.
@@ -197,7 +216,7 @@
                            scoped_refptr<QuotaManager> qm) {
     if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
       GetIOThreadTaskRunner({})->PostTask(
-          FROM_HERE, base::BindOnce(&IndexedDBBrowserTest::SetTempQuota,
+          FROM_HERE, base::BindOnce(&IndexedDBBrowserTestBase::SetTempQuota,
                                     per_host_quota_kilobytes, qm));
       return;
     }
@@ -273,13 +292,34 @@
   }
 
  protected:
+  bool using_sqlite_ = false;
+  base::AutoReset<std::optional<bool>> sqlite_override_;
   mojo::Remote<storage::mojom::MockFailureInjector> failure_injector_;
 };
 
-class IndexedDBIncognitoTest : public IndexedDBBrowserTest,
-                               public ::testing::WithParamInterface<bool> {
+// This browser test is aimed towards exercising the IndexedDB bindings and
+// the actual implementation that lives in the browser side.
+// The tests are parametrized to run with both the LevelDB (param = false) and
+// SQLite (param = true) backing stores.
+class IndexedDBBrowserTest : public IndexedDBBrowserTestBase,
+                             public ::testing::WithParamInterface<bool> {
  public:
-  IndexedDBIncognitoTest() = default;
+  IndexedDBBrowserTest()
+      : IndexedDBBrowserTestBase(/*use_sqlite=*/GetParam()) {}
+};
+
+// Tests that are applicable only to the LevelDB backing store.
+class IndexedDBLevelDBOnlyTest : public IndexedDBBrowserTestBase {
+ public:
+  IndexedDBLevelDBOnlyTest() : IndexedDBBrowserTestBase(/*use_sqlite=*/false) {}
+};
+
+class IndexedDBIncognitoTest
+    : public IndexedDBBrowserTestBase,
+      public ::testing::WithParamInterface<std::tuple<bool, bool>> {
+ public:
+  IndexedDBIncognitoTest()
+      : IndexedDBBrowserTestBase(/*use_sqlite=*/std::get<0>(GetParam())) {}
 
   void SetUpMockFailureInjector() override {
     if (IsIncognito()) {
@@ -287,16 +327,16 @@
       GetControlTest(shell_)->BindMockFailureSingletonForTesting(
           failure_injector_.BindNewPipeAndPassReceiver());
     } else {
-      IndexedDBBrowserTest::SetUpMockFailureInjector();
+      IndexedDBBrowserTestBase::SetUpMockFailureInjector();
     }
   }
 
   void TearDownOnMainThread() override {
     shell_ = nullptr;
-    IndexedDBBrowserTest::TearDownOnMainThread();
+    IndexedDBBrowserTestBase::TearDownOnMainThread();
   }
 
-  bool IsIncognito() { return GetParam(); }
+  bool IsIncognito() { return std::get<1>(GetParam()); }
 
  protected:
   raw_ptr<Shell> shell_ = nullptr;
@@ -306,27 +346,27 @@
   SimpleTest(GetTestUrl("indexeddb", "cursor_test.html"), shell_);
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CursorPrefetch) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, CursorPrefetch) {
   SimpleTest(GetTestUrl("indexeddb", "cursor_prefetch.html"));
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, IndexTest) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, IndexTest) {
   SimpleTest(GetTestUrl("indexeddb", "index_test.html"));
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, KeyPathTest) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, KeyPathTest) {
   SimpleTest(GetTestUrl("indexeddb", "key_path_test.html"));
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, TransactionGetTest) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, TransactionGetTest) {
   SimpleTest(GetTestUrl("indexeddb", "transaction_get_test.html"));
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, KeyTypesTest) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, KeyTypesTest) {
   SimpleTest(GetTestUrl("indexeddb", "key_types_test.html"));
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ObjectStoreTest) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, ObjectStoreTest) {
   base::HistogramTester tester;
 
   tester.ExpectTotalCount("WebCore.IndexedDB.RequestDuration2.Open", 0);
@@ -399,46 +439,46 @@
       "WebCore.IndexedDB.Transaction.VersionChange.TimeActive2", 2);
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DatabaseTest) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, DatabaseTest) {
   SimpleTest(GetTestUrl("indexeddb", "database_test.html"));
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, TransactionTest) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, TransactionTest) {
   SimpleTest(GetTestUrl("indexeddb", "transaction_test.html"));
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CallbackAccounting) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, CallbackAccounting) {
   SimpleTest(GetTestUrl("indexeddb", "callback_accounting.html"));
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DoesntHangTest) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, DoesntHangTest) {
   SimpleTest(GetTestUrl("indexeddb", "transaction_run_forever.html"));
   CrashTab(shell()->web_contents());
   SimpleTest(GetTestUrl("indexeddb", "transaction_not_blocked.html"));
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug84933Test) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, Bug84933Test) {
   const GURL url = GetTestUrl("indexeddb", "bug_84933.html");
 
   // Just navigate to the URL. Test will crash if it fails.
   NavigateToURLBlockUntilNavigationsComplete(shell(), url, 1);
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug106883Test) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, Bug106883Test) {
   const GURL url = GetTestUrl("indexeddb", "bug_106883.html");
 
   // Just navigate to the URL. Test will crash if it fails.
   NavigateToURLBlockUntilNavigationsComplete(shell(), url, 1);
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug109187Test) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, Bug109187Test) {
   const GURL url = GetTestUrl("indexeddb", "bug_109187.html");
 
   // Just navigate to the URL. Test will crash if it fails.
   NavigateToURLBlockUntilNavigationsComplete(shell(), url, 1);
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug941965Test) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, Bug941965Test) {
   // Double-open an incognito window to test that saving & reading a blob from
   // indexeddb works.
   Shell* incognito_browser = CreateOffTheRecordBrowser();
@@ -453,7 +493,7 @@
   incognito_browser->Close();
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, SchedulingPriority) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, SchedulingPriority) {
   // This test page just opens a connection.
   const GURL url = GetTestUrl("indexeddb", "simple_test.html");
   NavigateToURLBlockUntilNavigationsComplete(shell(), url, 1);
@@ -515,11 +555,13 @@
   }
 };
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithLowQuota, QuotaTest) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTestWithLowQuota, QuotaTest) {
+  DISABLED_FOR_SQLITE_PENDING_USAGE_REPORTING();
   SimpleTest(GetTestUrl("indexeddb", "quota_test.html"));
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithLowQuota, QuotaTestWithCommit) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTestWithLowQuota, QuotaTestWithCommit) {
+  DISABLED_FOR_SQLITE_PENDING_USAGE_REPORTING();
   SimpleTest(GetTestUrl("indexeddb", "bug_1203335.html"));
 }
 
@@ -538,17 +580,17 @@
   }
 };
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithGCExposed,
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTestWithGCExposed,
                        DatabaseCallbacksTest) {
   SimpleTest(GetTestUrl("indexeddb", "database_callbacks_first.html"));
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithGCExposed, Bug346955148Test) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTestWithGCExposed, Bug346955148Test) {
   SimpleTest(GetTestUrl("indexeddb", "bug_346955148.html"));
 }
 
 // Regression test for crbug.com/392376370
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithGCExposed, NestedBlob) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTestWithGCExposed, NestedBlob) {
   SimpleTest(GetTestUrl("indexeddb", "nested_blob.html"));
 }
 
@@ -595,7 +637,8 @@
 #endif
 }
 
-class IndexedDBBrowserTestWithPreexistingLevelDB : public IndexedDBBrowserTest {
+class IndexedDBBrowserTestWithPreexistingLevelDB
+    : public IndexedDBLevelDBOnlyTest {
  public:
   IndexedDBBrowserTestWithPreexistingLevelDB() = default;
 
@@ -686,7 +729,8 @@
   EXPECT_NE(original_size, new_size);
 }
 
-class IndexedDBBrowserTestsWithCleanupScheduler : public IndexedDBBrowserTest {
+class IndexedDBBrowserTestsWithCleanupScheduler
+    : public IndexedDBLevelDBOnlyTest {
  public:
   IndexedDBBrowserTestsWithCleanupScheduler() {
     scoped_feature_list_.InitAndEnableFeature(
@@ -800,7 +844,7 @@
   SimpleTest(kTestUrl);
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, LevelDBLogFileTest) {
+IN_PROC_BROWSER_TEST_F(IndexedDBLevelDBOnlyTest, LevelDBLogFileTest) {
   // Any page that opens an IndexedDB will work here.
   SimpleTest(GetTestUrl("indexeddb", "database_test.html"));
   base::FilePath leveldb_dir(FILE_PATH_LITERAL("file__0.indexeddb.leveldb"));
@@ -824,7 +868,8 @@
   }
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CanDeleteWhenOverQuotaTest) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, CanDeleteWhenOverQuotaTest) {
+  DISABLED_FOR_SQLITE_PENDING_USAGE_REPORTING();
   SetQuota(5);
   const GURL kTestUrl = GetTestUrl("indexeddb", "fill_quota.html");
   SimpleTest(kTestUrl);
@@ -832,7 +877,7 @@
   SimpleTest(GetTestUrl("indexeddb", "delete_over_quota.html"));
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, EmptyBlob) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, EmptyBlob) {
   // First delete all IDB's for the test storage_key
   const GURL kTestUrl = GetTestUrl("indexeddb", "empty_blob.html");
   const blink::StorageKey kTestStorageKey =
@@ -855,11 +900,13 @@
 #endif
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, BlobsCountAgainstQuota) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, BlobsCountAgainstQuota) {
+  DISABLED_FOR_SQLITE_PENDING_USAGE_REPORTING();
   SimpleTest(GetTestUrl("indexeddb", "blobs_use_quota.html"));
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DeleteBucketDataDeletesBlobs) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, DeleteBucketDataDeletesBlobs) {
+  DISABLED_FOR_SQLITE_PENDING_USAGE_REPORTING();
   const GURL kTestUrl = GetTestUrl("indexeddb", "write_4mb_blob.html");
   const blink::StorageKey kTestStorageKey =
       blink::StorageKey::CreateFirstParty(url::Origin::Create(kTestUrl));
@@ -881,7 +928,7 @@
 //   4. the page reads the same blob, reusing the IndexedDBDataItemReader
 //   5. the blob reference is dropped and GC'd again
 //   6. don't crash
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithGCExposed, ForceCloseWithBlob) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTestWithGCExposed, ForceCloseWithBlob) {
   const GURL kTestUrl = GetTestUrl("indexeddb", "write_and_read_blob.html");
   SimpleTest(kTestUrl);
   DeleteBucketData(
@@ -901,7 +948,8 @@
   }
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DeleteBucketDataIncognito) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, DeleteBucketDataIncognito) {
+  DISABLED_FOR_SQLITE_PENDING_USAGE_REPORTING();
   const GURL test_url = GetTestUrl("indexeddb", "fill_up_5k.html");
   const blink::StorageKey kTestStorageKey =
       blink::StorageKey::CreateFirstParty(url::Origin::Create(test_url));
@@ -916,7 +964,8 @@
   EXPECT_EQ(0, RequestUsage(browser));
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DiskFullOnCommit) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, DiskFullOnCommit) {
+  DISABLED_FOR_SQLITE_PENDING_FAILURE_INJECTION();
   // Ignore several preceding transactions:
   // * The test calls deleteDatabase() which opens the backing store:
   //   #1: Transaction::Commit - initial "versionchange" transaction
@@ -979,7 +1028,7 @@
     scoped_refptr<base::SequencedTaskRunner> task_runner,
     const storage::BucketLocator& bucket_locator,
     const std::string& path,
-    IndexedDBBrowserTest* test,
+    IndexedDBBrowserTestBase* test,
     const net::test_server::HttpRequest& request) {
   std::string request_path;
   if (path.find(s_corrupt_db_test_prefix) == std::string::npos)
@@ -1000,10 +1049,10 @@
     VLOG(0) << "Requested to corrupt IndexedDB: " << request_query;
 
     // BindControlTest must be called on the same sequence that
-    // IndexedDBBrowserTest lives on.
+    // IndexedDBBrowserTestBase lives on.
     mojo::Remote<storage::mojom::IndexedDBControlTest> control_test;
     task_runner->PostTask(
-        FROM_HERE, base::BindOnce(&IndexedDBBrowserTest::BindControlTest,
+        FROM_HERE, base::BindOnce(&IndexedDBBrowserTestBase::BindControlTest,
                                   base::Unretained(test), nullptr,
                                   control_test.BindNewPipeAndPassReceiver()));
 
@@ -1104,7 +1153,7 @@
     DCHECK_GE(call_num, 1);
 
     task_runner->PostTask(
-        FROM_HERE, base::BindOnce(&IndexedDBBrowserTest::FailOperation,
+        FROM_HERE, base::BindOnce(&IndexedDBBrowserTestBase::FailOperation,
                                   base::Unretained(test), failure_class,
                                   failure_method, instance_num, call_num));
 
@@ -1122,7 +1171,6 @@
 
 std::unique_ptr<net::test_server::HttpResponse> StaticFileRequestHandler(
     const std::string& path,
-    IndexedDBBrowserTest* test,
     const net::test_server::HttpRequest& request) {
   if (path.find(s_indexeddb_test_prefix) == std::string::npos)
     return nullptr;
@@ -1131,12 +1179,14 @@
   return ServePath(request_path);
 }
 
+// TODO(crbug.com/419272072): Adapt this test suite to also work with the SQLite
+// backing store.
 // See TODO in CorruptDBRequestHandler.  Windows does not support nested
 // message loops on the IO thread, so run this test on other platforms.
 // iOS runs into difficulty with the nested IO message loop as well.
 #if !BUILDFLAG(IS_WIN) && !BUILDFLAG(IS_IOS)
 class IndexedDBBrowserTestWithCorruption
-    : public IndexedDBBrowserTest,
+    : public IndexedDBLevelDBOnlyTest,
       public ::testing::WithParamInterface<const char*> {};
 
 INSTANTIATE_TEST_SUITE_P(/* no prefix */,
@@ -1188,7 +1238,7 @@
 #endif  // !BUILDFLAG(IS_WIN) && !BUILDFLAG(IS_IOS)
 
 // TODO: http://crbug.com/510520, flaky on all platforms
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest,
+IN_PROC_BROWSER_TEST_F(IndexedDBLevelDBOnlyTest,
                        DISABLED_DeleteCompactsBackingStore) {
   const GURL kTestUrl = GetTestUrl("indexeddb", "delete_compact.html");
   const blink::StorageKey kTestStorageKey =
@@ -1225,7 +1275,7 @@
 // to IndexedDB.  Regression test for crbug.com/369670458
 // Unfortunately this can't use SimpleTest because it requires user activation,
 // which is provided by `ExecJs()`.
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, LargeSlicedFile) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, LargeSlicedFile) {
   // Generate test file.
   base::ScopedAllowBlockingForTesting allow_blocking;
   base::ScopedTempDir temp_dir;
@@ -1258,13 +1308,13 @@
 // Complex multi-step (converted from pyauto) tests begin here.
 
 // Verify null key path persists after restarting browser.
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, PRE_NullKeyPathPersistence) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, PRE_NullKeyPathPersistence) {
   NavigateAndWaitForTitle(shell(), "bug_90635.html", "#part1",
                           "pass - first run");
 }
 
 // Verify null key path persists after restarting browser.
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, NullKeyPathPersistence) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, NullKeyPathPersistence) {
   NavigateAndWaitForTitle(shell(), "bug_90635.html", "#part2",
                           "pass - second run");
 }
@@ -1277,8 +1327,8 @@
 #define MAYBE_ConnectionsClosedOnTabClose ConnectionsClosedOnTabClose
 #endif
 // Verify that open DB connections are closed when a tab is destroyed.
-IN_PROC_BROWSER_TEST_F(
-    IndexedDBBrowserTest, MAYBE_ConnectionsClosedOnTabClose) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest,
+                       MAYBE_ConnectionsClosedOnTabClose) {
   NavigateAndWaitForTitle(shell(), "version_change_blocked.html", "#tab1",
                           "setVersion(2) complete");
 
@@ -1299,7 +1349,7 @@
 
 // Verify that a "close" event is fired at database connections when
 // the backing store is deleted.
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ForceCloseEventTest) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, ForceCloseEventTest) {
   constexpr char kFilename[] = "force_close_event.html";
   NavigateAndWaitForTitle(shell(), kFilename, nullptr, "connection ready");
   DeleteBucketData(blink::StorageKey::CreateFirstParty(
@@ -1310,18 +1360,21 @@
   EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
 }
 
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ShutdownWithRequests) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, ShutdownWithRequests) {
   SimpleTest(GetTestUrl("indexeddb", "shutdown_with_requests.html"));
 }
 
 // Regression test for https://crbug.com/429974682
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DeleteOpenUse) {
+IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTest, DeleteOpenUse) {
   SimpleTest(GetTestUrl("indexeddb", "delete_open_use.html"));
 }
 
 // Verifies that a "NotFound" DOMException is thrown on reading a large value
 // when the underlying blob file has been deleted but the record is not.
-IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, LargeValueReadBlobMissing) {
+// TODO(crbug.com/419264073): Adapt this test to run the second part (expecting
+// the right error when an "external" file is missing) on SQLite too if LevelDB
+// blob-files are migrated as-is.
+IN_PROC_BROWSER_TEST_F(IndexedDBLevelDBOnlyTest, LargeValueReadBlobMissing) {
   base::HistogramTester histogram_tester;
 
   // First write a large value that gets wrapped in a blob.
@@ -1377,7 +1430,7 @@
 // The blob key corruption test runs in a separate class to avoid corrupting
 // an IDB store that other tests use.
 // This test is for https://crbug.com/1039446.
-typedef IndexedDBBrowserTest IndexedDBBrowserTestBlobKeyCorruption;
+typedef IndexedDBLevelDBOnlyTest IndexedDBBrowserTestBlobKeyCorruption;
 
 // Verify the blob key corruption state recovery:
 // - Create a file that should be the 'first' blob file.
@@ -1387,8 +1440,8 @@
 IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestBlobKeyCorruption, LifecycleTest) {
   ASSERT_TRUE(embedded_test_server()->Started() ||
               embedded_test_server()->InitializeAndListen());
-  embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
-      &StaticFileRequestHandler, s_indexeddb_test_prefix, this));
+  embedded_test_server()->RegisterRequestHandler(
+      base::BindRepeating(&StaticFileRequestHandler, s_indexeddb_test_prefix));
   embedded_test_server()->StartAcceptingConnections();
 
   // Set up the IndexedDB instance so it contains our reference data.
@@ -1435,22 +1488,53 @@
 }
 
 IN_PROC_BROWSER_TEST_P(IndexedDBIncognitoTest, BucketDurabilityStrict) {
+  DISABLED_FOR_SQLITE_PENDING_FAILURE_INJECTION();
   FailOperation(FailClass::LEVELDB_TRANSACTION, FailMethod::COMMIT_SYNC, 2, 1);
   SimpleTest(GetTestUrl("indexeddb", "bucket_durability_strict.html"), shell_);
 }
 
 IN_PROC_BROWSER_TEST_P(IndexedDBIncognitoTest, BucketDurabilityRelaxed) {
+  DISABLED_FOR_SQLITE_PENDING_FAILURE_INJECTION();
   FailOperation(FailClass::LEVELDB_TRANSACTION, FailMethod::COMMIT_SYNC, 2, 1);
   SimpleTest(GetTestUrl("indexeddb", "bucket_durability_relaxed.html"), shell_);
 }
 
 IN_PROC_BROWSER_TEST_P(IndexedDBIncognitoTest, BucketDurabilityOverride) {
+  DISABLED_FOR_SQLITE_PENDING_FAILURE_INJECTION();
   FailOperation(FailClass::LEVELDB_TRANSACTION, FailMethod::COMMIT_SYNC, 2, 1);
   SimpleTest(GetTestUrl("indexeddb", "bucket_durability_override.html"),
              shell_);
 }
 
-INSTANTIATE_TEST_SUITE_P(All, IndexedDBIncognitoTest, testing::Bool());
+constexpr auto GetBackingStoreTestCaseName =
+    [](const testing::TestParamInfo<bool>& info) {
+      return info.param ? "WithSqlite" : "WithLevelDb";
+    };
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         IndexedDBBrowserTest,
+                         testing::Bool(),
+                         GetBackingStoreTestCaseName);
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         IndexedDBBrowserTestWithLowQuota,
+                         testing::Bool(),
+                         GetBackingStoreTestCaseName);
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         IndexedDBBrowserTestWithGCExposed,
+                         testing::Bool(),
+                         GetBackingStoreTestCaseName);
+
+INSTANTIATE_TEST_SUITE_P(
+    All,
+    IndexedDBIncognitoTest,
+    testing::Combine(testing::Bool(), testing::Bool()),
+    [](const testing::TestParamInfo<std::tuple<bool, bool>>& info) {
+      return base::StrCat(
+          {std::get<0>(info.param) ? "WithSqlite" : "WithLevelDb", "_",
+           std::get<1>(info.param) ? "Incognito" : "Regular"});
+    });
 
 }  // namespace
 }  // namespace content::indexed_db
diff --git a/content/browser/indexed_db/instance/bucket_context.cc b/content/browser/indexed_db/instance/bucket_context.cc
index ed6dde4..dd643615 100644
--- a/content/browser/indexed_db/instance/bucket_context.cc
+++ b/content/browser/indexed_db/instance/bucket_context.cc
@@ -871,6 +871,7 @@
 // static
 base::AutoReset<std::optional<bool>>
 BucketContext::OverrideShouldUseSqliteForTesting(bool use_sqlite) {
+  CHECK(!g_should_use_sqlite_for_testing.has_value());
   base::AutoReset<std::optional<bool>> scoped_override(
       &g_should_use_sqlite_for_testing, use_sqlite);
   return scoped_override;
@@ -912,7 +913,7 @@
     // to unimplemented functionality; in the future, we'll need to deal with
     // corruption. Unlike in the LevelDB case, an error in one database doesn't
     // indicate a problem with the entire bucket.
-    DCHECK(database);
+    CHECK(database);
     database->ForceCloseAndRunTasks(error_message);
   } else {
     if (status.IsCorruption()) {
diff --git a/content/browser/indexed_db/instance/connection.cc b/content/browser/indexed_db/instance/connection.cc
index e763b8c..9e0d711 100644
--- a/content/browser/indexed_db/instance/connection.cc
+++ b/content/browser/indexed_db/instance/connection.cc
@@ -804,7 +804,7 @@
     return {};
   }
 
-  DCHECK(database_);
+  CHECK(database_);
 
   // Finish up any transaction, in case there were any running.
   DatabaseError error(blink::mojom::IDBException::kUnknownError,
diff --git a/content/browser/network_service_browsertest.cc b/content/browser/network_service_browsertest.cc
index fddf99fc..5be89cfd 100644
--- a/content/browser/network_service_browsertest.cc
+++ b/content/browser/network_service_browsertest.cc
@@ -57,6 +57,7 @@
 #include "mojo/public/cpp/bindings/sync_call_restrictions.h"
 #include "net/base/features.h"
 #include "net/cookies/cookie_util.h"
+#include "net/disk_cache/backend_experiment.h"
 #include "net/disk_cache/disk_cache.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/http/http_response_headers.h"
@@ -308,8 +309,23 @@
 }
 
 #if BUILDFLAG(IS_ANDROID)
-IN_PROC_BROWSER_TEST_F(NetworkServiceBrowserTest,
+class NetworkServiceBrowserSimpleCacheTest : public NetworkServiceBrowserTest {
+ public:
+  NetworkServiceBrowserSimpleCacheTest() {
+    scoped_feature_list_.InitAndEnableFeatureWithParameters(
+        net::features::kDiskCacheBackendExperiment, {{"backend", "simple"}});
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+// `HttpCacheWrittenToDiskOnApplicationStateChange` test tests the behavior
+// specific to SimpleCache, so it is extracted to a dedicated test class that
+// enables DiskCacheBackendExperiment with simple backend.
+IN_PROC_BROWSER_TEST_F(NetworkServiceBrowserSimpleCacheTest,
                        HttpCacheWrittenToDiskOnApplicationStateChange) {
+  ASSERT_TRUE(disk_cache::InSimpleBackendExperimentGroup());
   base::ScopedAllowBlockingForTesting allow_blocking;
 
   // Create network context with cache pointing to the temp cache dir.
diff --git a/content/browser/notifications/notification_database_conversions_unittest.cc b/content/browser/notifications/notification_database_conversions_unittest.cc
index aa15ea83..9d6d040 100644
--- a/content/browser/notifications/notification_database_conversions_unittest.cc
+++ b/content/browser/notifications/notification_database_conversions_unittest.cc
@@ -60,16 +60,11 @@
     {kNotificationMetadataKey, kNotificationMetadataValue}};
 
 TEST(NotificationDatabaseConversionsTest, SerializeAndDeserializeData) {
-  std::vector<int> vibration_pattern(
-      kNotificationVibrationPattern,
-      UNSAFE_TODO(kNotificationVibrationPattern +
-                  std::size(kNotificationVibrationPattern)));
+  std::vector<int> vibration_pattern(std::begin(kNotificationVibrationPattern),
+                                     std::end(kNotificationVibrationPattern));
 
-  std::vector<char> developer_data(
-      kNotificationData.data(),
-      base::span<const unsigned char>(kNotificationData)
-          .subspan(std::size(kNotificationData))
-          .data());
+  std::vector<char> developer_data(kNotificationData.begin(),
+                                   kNotificationData.end());
 
   blink::PlatformNotificationData notification_data;
   notification_data.title = kNotificationTitle;
diff --git a/content/browser/notifications/platform_notification_context_unittest.cc b/content/browser/notifications/platform_notification_context_unittest.cc
index 863235c..08f17e05 100644
--- a/content/browser/notifications/platform_notification_context_unittest.cc
+++ b/content/browser/notifications/platform_notification_context_unittest.cc
@@ -645,7 +645,7 @@
   // Now drop the Service Worker registration which owns that notification.
   embedded_worker_test_helper->context()->UnregisterServiceWorker(
       origin, key,
-      /*is_immediate=*/false,
+      /*is_immediate=*/false, ServiceWorkerRegistration::DeleteInitiator::kTest,
       base::BindOnce(
           &PlatformNotificationContextTest::DidUnregisterServiceWorker,
           base::Unretained(this), &unregister_status));
diff --git a/content/browser/payments/payment_app_content_unittest_base.cc b/content/browser/payments/payment_app_content_unittest_base.cc
index f55a8752..5258c03 100644
--- a/content/browser/payments/payment_app_content_unittest_base.cc
+++ b/content/browser/payments/payment_app_content_unittest_base.cc
@@ -275,6 +275,7 @@
   bool called = false;
   worker_helper_->context()->UnregisterServiceWorker(
       scope_url, key, /*is_immediate=*/false,
+      ServiceWorkerRegistration::DeleteInitiator::kTest,
       base::BindOnce(&UnregisterServiceWorkerCallback, &called));
   base::RunLoop().RunUntilIdle();
   EXPECT_TRUE(called);
diff --git a/content/browser/preloading/prerender/prerender_host_registry.cc b/content/browser/preloading/prerender/prerender_host_registry.cc
index 3660d17..0aff665 100644
--- a/content/browser/preloading/prerender/prerender_host_registry.cc
+++ b/content/browser/preloading/prerender/prerender_host_registry.cc
@@ -807,6 +807,11 @@
     }
     base::UmaHistogramBoolean("Prerender.Experimental.FoundReusePrerenderHost",
                               reuse_host != nullptr);
+    if (!reuse_host) {
+      base::UmaHistogramCounts100(
+          "Prerender.Experimental.ReusePrerenderHost.PrerenderHostCount.Failed",
+          prerender_host_by_frame_tree_node_id_.size());
+    }
     // If we find a reusable prerender host under the same site. We will
     // take over its frame tree and initiate a new navigation to the new
     // prerender URL.
diff --git a/content/browser/renderer_host/back_forward_cache_impl.cc b/content/browser/renderer_host/back_forward_cache_impl.cc
index 571cdf9..786a92a 100644
--- a/content/browser/renderer_host/back_forward_cache_impl.cc
+++ b/content/browser/renderer_host/back_forward_cache_impl.cc
@@ -1882,8 +1882,7 @@
 BackForwardCacheCanStoreTreeResult::BackForwardCacheCanStoreTreeResult(
     bool is_same_origin,
     const GURL& url)
-    : document_result_(BackForwardCacheCanStoreDocumentResult()),
-      is_same_origin_(is_same_origin),
+    : is_same_origin_(is_same_origin),
       is_root_outermost_main_frame_(true),
       id_(""),
       name_(""),
diff --git a/content/browser/renderer_host/cross_process_frame_connector.cc b/content/browser/renderer_host/cross_process_frame_connector.cc
index b19e810..a5c68e62 100644
--- a/content/browser/renderer_host/cross_process_frame_connector.cc
+++ b/content/browser/renderer_host/cross_process_frame_connector.cc
@@ -149,12 +149,17 @@
     // "display:none"), since in that case the user wouldn't see a sad frame
     // anyway. Prerendering subframes do not enter this code since
     // RenderFrameHostImpl immediately cancels prerender if a render process
-    // exits.
+    // exits. We only mark the tab for reload for active subframes to exclude
+    // cases like crashed frames in the back/forward cache.
     bool did_mark_for_reload = false;
     if (current_child_rfh->delegate()->GetVisibility() != Visibility::VISIBLE &&
         visibility_ != blink::mojom::FrameVisibility::kNotRendered &&
         base::FeatureList::IsEnabled(
-            features::kReloadHiddenTabsWithCrashedSubframes)) {
+            features::kReloadHiddenTabsWithCrashedSubframes) && (
+              !base::FeatureList::IsEnabled(
+                  features::kReloadHiddenTabsWithActiveCrashedSubframes) ||
+              current_child_rfh->IsActive()
+            )) {
       frame_proxy_in_parent_renderer_->frame_tree_node()
           ->frame_tree()
           .controller()
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h
index e7258fc..8a1ee97 100644
--- a/content/browser/renderer_host/render_frame_host_impl.h
+++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -191,7 +191,6 @@
 #include "ui/accessibility/platform/ax_platform_tree_manager.h"
 #include "ui/accessibility/platform/ax_platform_tree_manager_delegate.h"
 #include "ui/accessibility/platform/ax_unique_id.h"
-#include "ui/accessibility/platform/browser_accessibility_manager.h"
 #include "ui/base/page_transition_types.h"
 #include "ui/gfx/geometry/rect.h"
 #include "url/gurl.h"
@@ -249,6 +248,10 @@
 class ResourceRequestBody;
 }  // namespace network
 
+namespace ui {
+class BrowserAccessibilityManager;
+}
+
 namespace ukm {
 class UkmRecorder;
 }
diff --git a/content/browser/service_worker/service_worker_context_core.cc b/content/browser/service_worker/service_worker_context_core.cc
index 23b2a32c..9b0373a7 100644
--- a/content/browser/service_worker/service_worker_context_core.cc
+++ b/content/browser/service_worker/service_worker_context_core.cc
@@ -213,6 +213,7 @@
       context->UnregisterServiceWorker(
           registration_info.scope, registration_info.key,
           /*is_immediate=*/false,
+          ServiceWorkerRegistration::DeleteInitiator::kDeleteForStorageKey,
           base::BindOnce(&ClearAllServiceWorkersHelper::OnResult, this));
     }
   }
@@ -600,6 +601,7 @@
     const GURL& scope,
     const blink::StorageKey& key,
     bool is_immediate,
+    ServiceWorkerRegistration::DeleteInitiator initiator,
     UnregistrationCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
@@ -612,7 +614,7 @@
   }
 
   job_coordinator_->Unregister(
-      scope, key, is_immediate,
+      scope, key, is_immediate, initiator,
       base::BindOnce(&ServiceWorkerContextCore::UnregistrationComplete,
                      AsWeakPtr(), scope, key, std::move(callback)));
 }
@@ -645,7 +647,8 @@
           registry().GetUninstallingRegistrationsForStorageKey(key);
   for (const auto& uninstalling_registration : uninstalling_registrations) {
     job_coordinator_->Abort(uninstalling_registration->scope(), key);
-    uninstalling_registration->DeleteAndClearImmediately();
+    uninstalling_registration->DeleteAndClearImmediately(
+        ServiceWorkerRegistration::DeleteInitiator::kDeleteForStorageKey);
   }
 
   if (registrations.empty()) {
@@ -688,8 +691,10 @@
       }
     }
     job_coordinator_->Abort(registration->scope(), key);
-    UnregisterServiceWorker(registration->scope(), key, /*is_immediate=*/true,
-                            barrier);
+    UnregisterServiceWorker(
+        registration->scope(), key, /*is_immediate=*/true,
+        ServiceWorkerRegistration::DeleteInitiator::kDeleteForStorageKey,
+        barrier);
   }
 }
 
diff --git a/content/browser/service_worker/service_worker_context_core.h b/content/browser/service_worker/service_worker_context_core.h
index 2fc8c15..6a64b5c 100644
--- a/content/browser/service_worker/service_worker_context_core.h
+++ b/content/browser/service_worker/service_worker_context_core.h
@@ -6,6 +6,7 @@
 #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_CORE_H_
 
 #include <stdint.h>
+
 #include <map>
 #include <memory>
 #include <optional>
@@ -23,6 +24,7 @@
 #include "components/services/storage/public/mojom/service_worker_storage_control.mojom.h"
 #include "content/browser/service_worker/service_worker_info.h"
 #include "content/browser/service_worker/service_worker_process_manager.h"
+#include "content/browser/service_worker/service_worker_registration.h"
 #include "content/browser/service_worker/service_worker_registration_status.h"
 #include "content/browser/service_worker/service_worker_registry.h"
 #include "content/common/content_export.h"
@@ -406,10 +408,12 @@
 
   // If `is_immediate` is true, unregister clears the active worker from the
   // registration without waiting for the controlled clients to unload.
-  void UnregisterServiceWorker(const GURL& scope,
-                               const blink::StorageKey& key,
-                               bool is_immediate,
-                               UnregistrationCallback callback);
+  void UnregisterServiceWorker(
+      const GURL& scope,
+      const blink::StorageKey& key,
+      bool is_immediate,
+      ServiceWorkerRegistration::DeleteInitiator initiator,
+      UnregistrationCallback callback);
 
   // Callback is called after all deletions occurred. The status code is
   // blink::ServiceWorkerStatusCode::kOk if all succeed, or
diff --git a/content/browser/service_worker/service_worker_context_core_unittest.cc b/content/browser/service_worker/service_worker_context_core_unittest.cc
index fcbd8b4e..b04f8ac1 100644
--- a/content/browser/service_worker/service_worker_context_core_unittest.cc
+++ b/content/browser/service_worker/service_worker_context_core_unittest.cc
@@ -119,6 +119,7 @@
     blink::ServiceWorkerStatusCode status;
     context()->UnregisterServiceWorker(
         scope, key, /*is_immediate=*/false,
+        ServiceWorkerRegistration::DeleteInitiator::kTest,
         base::BindLambdaForTesting(
             [&](blink::ServiceWorkerStatusCode result_status) {
               status = result_status;
diff --git a/content/browser/service_worker/service_worker_context_unittest.cc b/content/browser/service_worker/service_worker_context_unittest.cc
index b2e4b9e..6ebd334 100644
--- a/content/browser/service_worker/service_worker_context_unittest.cc
+++ b/content/browser/service_worker/service_worker_context_unittest.cc
@@ -829,8 +829,10 @@
   EXPECT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, registration_id);
 
   called = false;
-  context()->UnregisterServiceWorker(scope, key, /*is_immediate=*/false,
-                                     MakeUnregisteredCallback(&called));
+  context()->UnregisterServiceWorker(
+      scope, key, /*is_immediate=*/false,
+      ServiceWorkerRegistration::DeleteInitiator::kTest,
+      MakeUnregisteredCallback(&called));
 
   ASSERT_FALSE(called);
   base::RunLoop().RunUntilIdle();
diff --git a/content/browser/service_worker/service_worker_context_watcher_unittest.cc b/content/browser/service_worker/service_worker_context_watcher_unittest.cc
index cdd2693b..2673ce9b 100644
--- a/content/browser/service_worker/service_worker_context_watcher_unittest.cc
+++ b/content/browser/service_worker/service_worker_context_watcher_unittest.cc
@@ -174,6 +174,7 @@
         blink::ServiceWorkerStatusCode::kErrorFailed;
     context()->UnregisterServiceWorker(
         scope, key, /*is_immediate=*/false,
+        ServiceWorkerRegistration::DeleteInitiator::kTest,
         base::BindOnce(&DidUnregisterServiceWorker, &status));
     base::RunLoop().RunUntilIdle();
     return status;
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc
index b0be247..3202822 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.cc
+++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -649,9 +649,11 @@
                                   blink::ServiceWorkerStatusCode::kErrorAbort));
     return;
   }
-  context()->UnregisterServiceWorker(net::SimplifyUrlForRequest(scope), key,
-                                     /*is_immediate=*/false,
-                                     std::move(callback));
+  context()->UnregisterServiceWorker(
+      net::SimplifyUrlForRequest(scope), key,
+      /*is_immediate=*/false,
+      ServiceWorkerRegistration::DeleteInitiator::kContentPublicApi,
+      std::move(callback));
 }
 
 void ServiceWorkerContextWrapper::UnregisterServiceWorkerImmediatelyImpl(
@@ -659,16 +661,17 @@
     const blink::StorageKey& key,
     StatusCodeCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
   if (!context_core_) {
     GetUIThreadTaskRunner({})->PostTask(
         FROM_HERE, base::BindOnce(std::move(callback),
                                   blink::ServiceWorkerStatusCode::kErrorAbort));
     return;
   }
-  context()->UnregisterServiceWorker(net::SimplifyUrlForRequest(scope), key,
-                                     /*is_immediate=*/true,
-                                     std::move(callback));
+  context()->UnregisterServiceWorker(
+      net::SimplifyUrlForRequest(scope), key,
+      /*is_immediate=*/true,
+      ServiceWorkerRegistration::DeleteInitiator::kContentPublicApi,
+      std::move(callback));
 }
 
 ServiceWorkerExternalRequestResult
diff --git a/content/browser/service_worker/service_worker_hid_delegate_observer_unittest.cc b/content/browser/service_worker/service_worker_hid_delegate_observer_unittest.cc
index d4abc57a..99c57cf 100644
--- a/content/browser/service_worker/service_worker_hid_delegate_observer_unittest.cc
+++ b/content/browser/service_worker/service_worker_hid_delegate_observer_unittest.cc
@@ -629,9 +629,10 @@
   EXPECT_FALSE(hid_delegate().observer_list().empty());
 
   TestFuture<blink::ServiceWorkerStatusCode> unregister_future;
-  context()->UnregisterServiceWorker(registration->scope(), registration->key(),
-                                     /*is_immediate=*/true,
-                                     unregister_future.GetCallback());
+  context()->UnregisterServiceWorker(
+      registration->scope(), registration->key(),
+      /*is_immediate=*/true, ServiceWorkerRegistration::DeleteInitiator::kTest,
+      unregister_future.GetCallback());
   EXPECT_EQ(unregister_future.Get<0>(), blink::ServiceWorkerStatusCode::kOk);
   // Wait until all of the
   // ServiceWorkerDeviceDelegateObserver::OnRegistrationDeleted are called.
diff --git a/content/browser/service_worker/service_worker_internals_ui.cc b/content/browser/service_worker/service_worker_internals_ui.cc
index 57dd9c1..474e7d9e 100644
--- a/content/browser/service_worker/service_worker_internals_ui.cc
+++ b/content/browser/service_worker/service_worker_internals_ui.cc
@@ -742,9 +742,10 @@
 
   // ServiceWorkerContextWrapper::UnregisterServiceWorker doesn't work here
   // because that reduces a status code to boolean.
-  context->context()->UnregisterServiceWorker(scope, storage_key,
-                                              /*is_immediate=*/false,
-                                              std::move(callback));
+  context->context()->UnregisterServiceWorker(
+      scope, storage_key,
+      /*is_immediate=*/false,
+      ServiceWorkerRegistration::DeleteInitiator::kWebUI, std::move(callback));
 }
 
 }  // namespace content
diff --git a/content/browser/service_worker/service_worker_job_coordinator.cc b/content/browser/service_worker/service_worker_job_coordinator.cc
index a8110d8..32369e7 100644
--- a/content/browser/service_worker/service_worker_job_coordinator.cc
+++ b/content/browser/service_worker/service_worker_job_coordinator.cc
@@ -95,9 +95,11 @@
     const GURL& scope,
     const blink::StorageKey& key,
     bool is_immediate,
+    ServiceWorkerRegistration::DeleteInitiator initiator,
     ServiceWorkerUnregisterJob::UnregistrationCallback callback) {
   std::unique_ptr<ServiceWorkerRegisterJobBase> job(
-      new ServiceWorkerUnregisterJob(context_, scope, key, is_immediate));
+      new ServiceWorkerUnregisterJob(context_, scope, key, is_immediate,
+                                     initiator));
   ServiceWorkerUnregisterJob* queued_job =
       static_cast<ServiceWorkerUnregisterJob*>(
           job_queues_[UniqueRegistrationKey(scope, key)].Push(std::move(job)));
diff --git a/content/browser/service_worker/service_worker_job_coordinator.h b/content/browser/service_worker/service_worker_job_coordinator.h
index 5d2aa84..6404240 100644
--- a/content/browser/service_worker/service_worker_job_coordinator.h
+++ b/content/browser/service_worker/service_worker_job_coordinator.h
@@ -50,6 +50,7 @@
   void Unregister(const GURL& scope,
                   const blink::StorageKey& key,
                   bool is_immediate,
+                  ServiceWorkerRegistration::DeleteInitiator initiator,
                   ServiceWorkerUnregisterJob::UnregistrationCallback callback);
 
   void Update(ServiceWorkerRegistration* registration,
diff --git a/content/browser/service_worker/service_worker_job_unittest.cc b/content/browser/service_worker/service_worker_job_unittest.cc
index 2a9c2e4..80af9c9 100644
--- a/content/browser/service_worker/service_worker_job_unittest.cc
+++ b/content/browser/service_worker/service_worker_job_unittest.cc
@@ -284,6 +284,7 @@
   base::RunLoop run_loop;
   job_coordinator()->Unregister(
       scope, key, /*is_immediate=*/false,
+      ServiceWorkerRegistration::DeleteInitiator::kTest,
       SaveUnregistration(expected_status, run_loop.QuitClosure()));
   run_loop.Run();
 }
@@ -572,7 +573,7 @@
   base::RunLoop run_loop;
   job_coordinator()->Unregister(
       scope, GetTestStorageKey(scope),
-      /*is_immediate=*/true,
+      /*is_immediate=*/true, ServiceWorkerRegistration::DeleteInitiator::kTest,
       SaveUnregistration(blink::ServiceWorkerStatusCode::kOk,
                          run_loop.QuitClosure()));
 
@@ -841,13 +842,13 @@
       base::BarrierClosure(2, run_loop.QuitClosure());
   job_coordinator()->Unregister(
       scope1, GetTestStorageKey(scope1),
-      /*is_immediate=*/false,
+      /*is_immediate=*/false, ServiceWorkerRegistration::DeleteInitiator::kTest,
       SaveUnregistration(blink::ServiceWorkerStatusCode::kErrorAbort,
                          barrier_closure));
 
   job_coordinator()->Unregister(
       scope2, GetTestStorageKey(scope2),
-      /*is_immediate=*/false,
+      /*is_immediate=*/false, ServiceWorkerRegistration::DeleteInitiator::kTest,
       SaveUnregistration(blink::ServiceWorkerStatusCode::kErrorAbort,
                          barrier_closure));
 
@@ -876,6 +877,7 @@
 
   job_coordinator()->Unregister(
       options.scope, key, /*is_immediate=*/false,
+      ServiceWorkerRegistration::DeleteInitiator::kTest,
       SaveUnregistration(blink::ServiceWorkerStatusCode::kErrorAbort,
                          barrier_closure));
 
@@ -2217,7 +2219,7 @@
   base::RunLoop run_loop;
   job_coordinator()->Unregister(
       scope, GetTestStorageKey(scope),
-      /*is_immediate=*/false,
+      /*is_immediate=*/false, ServiceWorkerRegistration::DeleteInitiator::kTest,
       SaveUnregistration(blink::ServiceWorkerStatusCode::kOk,
                          run_loop.QuitClosure()));
 
diff --git a/content/browser/service_worker/service_worker_register_job.cc b/content/browser/service_worker/service_worker_register_job.cc
index 97a71db..608245c 100644
--- a/content/browser/service_worker/service_worker_register_job.cc
+++ b/content/browser/service_worker/service_worker_register_job.cc
@@ -839,7 +839,8 @@
   if (status != blink::ServiceWorkerStatusCode::kOk) {
     if (registration()) {
       if (should_uninstall_on_failure_) {
-        registration()->DeleteAndClearWhenReady();
+        registration()->DeleteAndClearWhenReady(
+            ServiceWorkerRegistration::DeleteInitiator::kRegistrationFailure);
       }
       if (new_version()) {
         if (status == blink::ServiceWorkerStatusCode::kErrorExists) {
diff --git a/content/browser/service_worker/service_worker_registration.cc b/content/browser/service_worker/service_worker_registration.cc
index 6f065a1c..2feaa34 100644
--- a/content/browser/service_worker/service_worker_registration.cc
+++ b/content/browser/service_worker/service_worker_registration.cc
@@ -6,9 +6,12 @@
 
 #include <utility>
 
+#include "base/check_is_test.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/observer_list.h"
+#include "base/strings/strcat.h"
 #include "base/strings/stringprintf.h"
 #include "base/task/single_thread_task_runner.h"
 #include "content/browser/service_worker/service_worker_client.h"
@@ -354,7 +357,8 @@
   }
 }
 
-void ServiceWorkerRegistration::DeleteAndClearWhenReady() {
+void ServiceWorkerRegistration::DeleteAndClearWhenReady(
+    DeleteInitiator initiator) {
   DCHECK(context_);
   if (is_deleted()) {
     // We already deleted and are waiting to clear, or the registration is
@@ -363,18 +367,20 @@
   }
 
   context_->registry().DeleteRegistration(
-      this, base::BindOnce(&ServiceWorkerRegistration::OnDeleteFinished, this));
+      this, base::BindOnce(&ServiceWorkerRegistration::OnDeleteFinished, this,
+                           initiator));
 
   if (!active_version() || !active_version()->HasControllee())
     Clear();
 }
 
-void ServiceWorkerRegistration::DeleteAndClearImmediately() {
+void ServiceWorkerRegistration::DeleteAndClearImmediately(
+    DeleteInitiator initiator) {
   DCHECK(context_);
   if (!is_deleted()) {
     context_->registry().DeleteRegistration(
-        this,
-        base::BindOnce(&ServiceWorkerRegistration::OnDeleteFinished, this));
+        this, base::BindOnce(&ServiceWorkerRegistration::OnDeleteFinished, this,
+                             initiator));
   }
 
   if (is_uninstalling())
@@ -614,8 +620,8 @@
   // Delete the registration and its state from storage.
   if (status() == Status::kIntact) {
     context_->registry().DeleteRegistration(
-        this,
-        base::BindOnce(&ServiceWorkerRegistration::OnDeleteFinished, protect));
+        this, base::BindOnce(&ServiceWorkerRegistration::OnDeleteFinished,
+                             protect, DeleteInitiator::kForceDelete));
   }
   DCHECK(is_uninstalling());
   context_->registry().NotifyDoneUninstallingRegistration(this,
@@ -718,7 +724,41 @@
 }
 
 void ServiceWorkerRegistration::OnDeleteFinished(
+    DeleteInitiator initiator,
     blink::ServiceWorkerStatusCode status) {
+  base::UmaHistogramEnumeration("ServiceWorker.Registration.Delete.Initiator",
+                                initiator);
+
+  const char* initiator_string = nullptr;
+  switch (initiator) {
+    case DeleteInitiator::kUnregister:
+      initiator_string = ".ByUnregister";
+      break;
+    case DeleteInitiator::kDeleteForStorageKey:
+      initiator_string = ".ByDeleteForStorageKey";
+      break;
+    case DeleteInitiator::kForceDelete:
+      initiator_string = ".ByForceDelete";
+      break;
+    case DeleteInitiator::kRegistrationFailure:
+      initiator_string = ".ByRegistrationFailure";
+      break;
+    case DeleteInitiator::kContentPublicApi:
+      initiator_string = ".ByContentPublicApi";
+      break;
+    case DeleteInitiator::kWebUI:
+      initiator_string = ".ByWebUI";
+      break;
+    case DeleteInitiator::kTest:
+      initiator_string = ".ByTest";
+      CHECK_IS_TEST();
+      break;
+  }
+  base::UmaHistogramEnumeration(
+      base::StrCat(
+          {"ServiceWorker.Registration.Delete.Result", initiator_string}),
+      status);
+
   for (auto& listener : listeners_)
     listener.OnRegistrationDeleted(this);
 }
diff --git a/content/browser/service_worker/service_worker_registration.h b/content/browser/service_worker/service_worker_registration.h
index 2a3c1ff..cb036641 100644
--- a/content/browser/service_worker/service_worker_registration.h
+++ b/content/browser/service_worker/service_worker_registration.h
@@ -39,6 +39,22 @@
   using StatusCallback =
       base::OnceCallback<void(blink::ServiceWorkerStatusCode status)>;
 
+  // These values are persisted to logs. Entries should not be renumbered and
+  // numeric values should never be reused.
+  //
+  // LINT.IfChange(DeleteInitiator)
+  enum class DeleteInitiator {
+    kUnregister = 0,
+    kDeleteForStorageKey = 1,
+    kForceDelete = 2,
+    kRegistrationFailure = 3,
+    kContentPublicApi = 4,
+    kWebUI = 5,
+    kTest = 6,
+    kMaxValue = kTest,
+  };
+  // LINT.ThenChange(//tools/metrics/histograms/metadata/service/enums.xml:ServiceWorkerRegistrationDeleteInitiator)
+
   class CONTENT_EXPORT Listener {
    public:
     virtual void OnVersionAttributesChanged(
@@ -179,11 +195,11 @@
   // Deletes this registration from storage immediately. Triggers the
   // [[ClearRegistration]] algorithm when the currently active version has no
   // controllees.
-  void DeleteAndClearWhenReady();
+  void DeleteAndClearWhenReady(DeleteInitiator initiator);
 
   // Deletes this registration from storage immediately and then triggers the
   // [[ClearRegistration]] algorithm.
-  void DeleteAndClearImmediately();
+  void DeleteAndClearImmediately(DeleteInitiator initiator);
 
   // Restores this registration in storage and cancels the pending
   // [[ClearRegistration]] algorithm.
@@ -276,7 +292,8 @@
       scoped_refptr<ServiceWorkerVersion> activating_version,
       blink::ServiceWorkerStatusCode status);
 
-  void OnDeleteFinished(blink::ServiceWorkerStatusCode status);
+  void OnDeleteFinished(DeleteInitiator initiator,
+                        blink::ServiceWorkerStatusCode status);
 
   // This method corresponds to the [[ClearRegistration]] algorithm.
   void Clear();
diff --git a/content/browser/service_worker/service_worker_registration_object_host.cc b/content/browser/service_worker/service_worker_registration_object_host.cc
index c339c2d..146c23e 100644
--- a/content/browser/service_worker/service_worker_registration_object_host.cc
+++ b/content/browser/service_worker/service_worker_registration_object_host.cc
@@ -153,6 +153,7 @@
   context_->UnregisterServiceWorker(
       registration_->scope(), registration_->key(),
       /*is_immediate=*/false,
+      ServiceWorkerRegistration::DeleteInitiator::kUnregister,
       base::BindOnce(
           &ServiceWorkerRegistrationObjectHost::UnregistrationComplete,
           weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
diff --git a/content/browser/service_worker/service_worker_unregister_job.cc b/content/browser/service_worker/service_worker_unregister_job.cc
index a903336..726363e 100644
--- a/content/browser/service_worker/service_worker_unregister_job.cc
+++ b/content/browser/service_worker/service_worker_unregister_job.cc
@@ -22,8 +22,13 @@
     ServiceWorkerContextCore* context,
     const GURL& scope,
     const blink::StorageKey& key,
-    bool is_immediate)
-    : context_(context), scope_(scope), key_(key), is_immediate_(is_immediate) {
+    bool is_immediate,
+    ServiceWorkerRegistration::DeleteInitiator initiator)
+    : context_(context),
+      scope_(scope),
+      key_(key),
+      is_immediate_(is_immediate),
+      initiator_(initiator) {
   DCHECK(context_);
 }
 
@@ -75,10 +80,11 @@
 
   ResolvePromise(registration->id(), blink::ServiceWorkerStatusCode::kOk);
 
-  if (is_immediate_)
-    registration->DeleteAndClearImmediately();
-  else
-    registration->DeleteAndClearWhenReady();
+  if (is_immediate_) {
+    registration->DeleteAndClearImmediately(initiator_);
+  } else {
+    registration->DeleteAndClearWhenReady(initiator_);
+  }
 
   Complete(registration->id(), blink::ServiceWorkerStatusCode::kOk);
 }
diff --git a/content/browser/service_worker/service_worker_unregister_job.h b/content/browser/service_worker/service_worker_unregister_job.h
index 8a977d2..ec2bbd1 100644
--- a/content/browser/service_worker/service_worker_unregister_job.h
+++ b/content/browser/service_worker/service_worker_unregister_job.h
@@ -13,6 +13,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "content/browser/service_worker/service_worker_register_job_base.h"
+#include "content/browser/service_worker/service_worker_registration.h"
 #include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
 #include "third_party/blink/public/common/storage_key/storage_key.h"
 #include "url/gurl.h"
@@ -35,10 +36,12 @@
 
   // If |is_immediate| is true, unregister clears the active worker from the
   // registration without waiting for the controlled clients to unload.
-  ServiceWorkerUnregisterJob(ServiceWorkerContextCore* context,
-                             const GURL& scope,
-                             const blink::StorageKey& key,
-                             bool is_immediate);
+  ServiceWorkerUnregisterJob(
+      ServiceWorkerContextCore* context,
+      const GURL& scope,
+      const blink::StorageKey& key,
+      bool is_immediate,
+      ServiceWorkerRegistration::DeleteInitiator initiator);
 
   ServiceWorkerUnregisterJob(const ServiceWorkerUnregisterJob&) = delete;
   ServiceWorkerUnregisterJob& operator=(const ServiceWorkerUnregisterJob&) =
@@ -71,6 +74,7 @@
   const GURL scope_;
   const blink::StorageKey key_;
   const bool is_immediate_;
+  const ServiceWorkerRegistration::DeleteInitiator initiator_;
   std::vector<UnregistrationCallback> callbacks_;
   bool is_promise_resolved_ = false;
   base::WeakPtrFactory<ServiceWorkerUnregisterJob> weak_factory_{this};
diff --git a/content/browser/service_worker/service_worker_usb_delegate_observer_unittest.cc b/content/browser/service_worker/service_worker_usb_delegate_observer_unittest.cc
index 6634da25..7c8a490 100644
--- a/content/browser/service_worker/service_worker_usb_delegate_observer_unittest.cc
+++ b/content/browser/service_worker/service_worker_usb_delegate_observer_unittest.cc
@@ -509,9 +509,10 @@
   EXPECT_FALSE(usb_delegate().observer_list().empty());
 
   TestFuture<blink::ServiceWorkerStatusCode> unregister_future;
-  context()->UnregisterServiceWorker(registration->scope(), registration->key(),
-                                     /*is_immediate=*/true,
-                                     unregister_future.GetCallback());
+  context()->UnregisterServiceWorker(
+      registration->scope(), registration->key(),
+      /*is_immediate=*/true, ServiceWorkerRegistration::DeleteInitiator::kTest,
+      unregister_future.GetCallback());
   EXPECT_EQ(unregister_future.Get<0>(), blink::ServiceWorkerStatusCode::kOk);
   // Wait until all of the
   // ServiceWorkerDeviceDelegateObserver::OnRegistrationDeleted are called.
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 00fdcbef..e289daf 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -210,6 +210,7 @@
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/accessibility/ax_tree_combiner.h"
 #include "ui/accessibility/platform/browser_accessibility.h"
+#include "ui/accessibility/platform/browser_accessibility_manager.h"
 #include "ui/base/ime/mojom/virtual_keyboard_types.mojom.h"
 #include "ui/base/mojom/window_show_state.mojom.h"
 #include "ui/base/pointer/pointer_device.h"
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc
index cd63666e..1ffb73b 100644
--- a/content/browser/web_contents/web_contents_view_aura.cc
+++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -1530,8 +1530,12 @@
 }
 
 void WebContentsViewAura::OnDragExited() {
-  if (web_contents_->ShouldIgnoreInputEvents())
+  if (web_contents_->ShouldIgnoreInputEvents()) {
+    // Don't compute the results of exiting, but clean up the flag to avoid
+    // hanging the renderer process. See crbug.com/434130454.
+    drag_in_progress_ = false;
     return;
+  }
   CompleteDragExit();
 }
 
@@ -1614,7 +1618,7 @@
     std::unique_ptr<ui::OSExchangeData> data,
     base::WeakPtr<RenderWidgetHostViewBase> target,
     std::optional<gfx::PointF> transformed_pt) {
-  // Exit callback to make sure |drag_in_pregress_| is flipped on exit and
+  // Exit callback to make sure |drag_in_progress_| is flipped on exit and
   // |end_drag_runner_| is run after OnGotVirtualFilesAsTempFiles finishes.
   base::ScopedClosureRunner drop_exit_cleanup(base::BindOnce(
       &WebContentsViewAura::OnDropExit, weak_ptr_factory_.GetWeakPtr(),
diff --git a/content/browser/web_contents/web_contents_view_aura.h b/content/browser/web_contents/web_contents_view_aura.h
index e9b2101a..e064e1b 100644
--- a/content/browser/web_contents/web_contents_view_aura.h
+++ b/content/browser/web_contents/web_contents_view_aura.h
@@ -172,6 +172,8 @@
       EmptyTextWithUrlInDropDataIsEmptyInOSExchangeDataGetString);
   FRIEND_TEST_ALL_PREFIXES(WebContentsViewAuraTest,
                            UrlInDropDataReturnsUrlInOSExchangeDataGetString);
+  FRIEND_TEST_ALL_PREFIXES(WebContentsViewAuraTest,
+                           IgnoreInputs_OngoingDropGetsCleared);
 
   class WindowObserver;
 
diff --git a/content/browser/web_contents/web_contents_view_aura_browsertest.cc b/content/browser/web_contents/web_contents_view_aura_browsertest.cc
index 80f74bb28..5cdaf451 100644
--- a/content/browser/web_contents/web_contents_view_aura_browsertest.cc
+++ b/content/browser/web_contents/web_contents_view_aura_browsertest.cc
@@ -1101,6 +1101,32 @@
   EXPECT_TRUE(drag_dest_delegate_.GetOnDragLeaveCalled());
 }
 
+// This test simulates a drag and drop scenario where input events start being
+// ignored after the drag started. When this happens, we still need to keep
+// track of whether or not a drag and drop is ongoing in the window irrespective
+// of our intentions for the result of the drop.
+IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
+                       IgnoreInputs_OngoingDropGetsCleared) {
+  StartTestWithPage("/simple_page.html");
+  WebContentsImpl* contents = GetWebContentsImpl();
+  WebContentsViewAura* view = GetWebContentsViewAura();
+
+  base::RunLoop run_loop;
+  async_drop_closure_ = run_loop.QuitClosure();
+
+  PrepareWebContentsViewForDropTest(/*delegate_allows_drop=*/true);
+  SimulateDragEnterAndDrop(/*document_is_handling_drag=*/false);
+  EXPECT_TRUE(view->drag_in_progress_);
+  std::optional<WebContents::ScopedIgnoreInputEvents> ignore_inputs =
+      contents->IgnoreInputEvents(std::nullopt);
+  view->OnDragExited();
+  // Even though input events are being ignored, the flag should still be
+  // cleared.
+  EXPECT_FALSE(view->drag_in_progress_);
+  EXPECT_EQ(0, drag_dest_delegate_.GetOnDropCalledCount());
+  ignore_inputs.reset();
+}
+
 // Tests that the content is not focusable when inputs are ignored, and that it
 // is focusable when inputs are not ignored.
 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, IgnoreInputs_Focus) {
diff --git a/content/common/features.cc b/content/common/features.cc
index 2c2e441..0da587c 100644
--- a/content/common/features.cc
+++ b/content/common/features.cc
@@ -478,6 +478,15 @@
 #endif
 );
 
+// ReloadHiddenTabsWithCrashedSubframes feature reloads the WebContents
+// regardless of the crashed frame's state. This feature restricts the reload
+// to only happen for active subframes.
+// This is a bug fix but being launched as a feature to see the impact.
+// This will be removed once this is launched.
+BASE_FEATURE(kReloadHiddenTabsWithActiveCrashedSubframes,
+             "ReloadHiddenTabsWithActiveCrashedSubframes",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 #if BUILDFLAG(IS_ANDROID)
 // If enabled, then orientation lock won't claim to work on anything but phone
 // form factors.  Tablets already do unpredictable things, such as letterboxing
diff --git a/content/common/features.h b/content/common/features.h
index 6e56b5cf..a206971 100644
--- a/content/common/features.h
+++ b/content/common/features.h
@@ -132,6 +132,7 @@
 CONTENT_EXPORT BASE_DECLARE_FEATURE_PARAM(ProgressiveAccessibilityMode,
                                           kProgressiveAccessibilityModeParam);
 CONTENT_EXPORT BASE_DECLARE_FEATURE(kReloadHiddenTabsWithCrashedSubframes);
+CONTENT_EXPORT BASE_DECLARE_FEATURE(kReloadHiddenTabsWithActiveCrashedSubframes);
 #if BUILDFLAG(IS_ANDROID)
 CONTENT_EXPORT BASE_DECLARE_FEATURE(kRestrictOrientationLockToPhones);
 CONTENT_EXPORT BASE_DECLARE_FEATURE(kContinueGestureOnLosingFocus);
diff --git a/content/public/browser/keep_alive_request_tracker.cc b/content/public/browser/keep_alive_request_tracker.cc
index e691684e..8f69773 100644
--- a/content/public/browser/keep_alive_request_tracker.cc
+++ b/content/public/browser/keep_alive_request_tracker.cc
@@ -80,132 +80,6 @@
     const RequestStageType& next_stage_type,
     std::optional<network::URLLoaderCompletionStatus> next_stage_status) {
   RequestStage next_stage(next_stage_type, next_stage_status);
-#if DCHECK_IS_ON()
-  static const base::NoDestructor<base::StateTransitions<RequestStageType>>
-      transitions(base::StateTransitions<RequestStageType>({
-          {RequestStageType::kLoaderCreated,
-           {
-               RequestStageType::kRequestStarted,
-               RequestStageType::kLoaderDisconnectedFromRenderer,
-               RequestStageType::kRequestCancelledByRenderer,
-               RequestStageType::kBrowserShutdown,
-           }},
-          {RequestStageType::kRequestStarted,
-           {
-               RequestStageType::kFirstRedirectReceived,
-               RequestStageType::kResponseReceived,
-               RequestStageType::kRequestFailed,
-               RequestStageType::kLoaderDisconnectedFromRenderer,
-               RequestStageType::kRequestCancelledByRenderer,
-               RequestStageType::kRequestCancelledAfterTimeLimit,
-               RequestStageType::kBrowserShutdown,
-               RequestStageType::kLoaderCompleted,
-           }},
-          {RequestStageType::kFirstRedirectReceived,
-           {
-               RequestStageType::kSecondRedirectReceived,
-               RequestStageType::kResponseReceived,
-               RequestStageType::kRequestFailed,
-               RequestStageType::kLoaderDisconnectedFromRenderer,
-               RequestStageType::kRequestCancelledByRenderer,
-               RequestStageType::kRequestCancelledAfterTimeLimit,
-               RequestStageType::kBrowserShutdown,
-               RequestStageType::kLoaderCompleted,
-           }},
-          {RequestStageType::kSecondRedirectReceived,
-           {
-               RequestStageType::kThirdOrLaterRedirectReceived,
-               RequestStageType::kResponseReceived,
-               RequestStageType::kRequestFailed,
-               RequestStageType::kLoaderDisconnectedFromRenderer,
-               RequestStageType::kRequestCancelledByRenderer,
-               RequestStageType::kRequestCancelledAfterTimeLimit,
-               RequestStageType::kBrowserShutdown,
-               RequestStageType::kLoaderCompleted,
-           }},
-          {RequestStageType::kThirdOrLaterRedirectReceived,
-           {
-               RequestStageType::kResponseReceived,
-               RequestStageType::kRequestFailed,
-               RequestStageType::kLoaderDisconnectedFromRenderer,
-               RequestStageType::kRequestCancelledByRenderer,
-               RequestStageType::kRequestCancelledAfterTimeLimit,
-               RequestStageType::kBrowserShutdown,
-               RequestStageType::kLoaderCompleted,
-           }},
-          {RequestStageType::kResponseReceived,
-           {
-               RequestStageType::kRequestFailed,
-               RequestStageType::kLoaderDisconnectedFromRenderer,
-               RequestStageType::kRequestCancelledByRenderer,
-               RequestStageType::kRequestCancelledAfterTimeLimit,
-               RequestStageType::kBrowserShutdown,
-               RequestStageType::kLoaderCompleted,
-           }},
-          {RequestStageType::kRequestFailed,
-           {
-               RequestStageType::kLoaderDisconnectedFromRenderer,
-               RequestStageType::kRequestCancelledByRenderer,
-               RequestStageType::kRequestCancelledAfterTimeLimit,
-               RequestStageType::kBrowserShutdown,
-               RequestStageType::kLoaderCompleted,
-           }},
-          {RequestStageType::kLoaderDisconnectedFromRenderer,
-           {
-               RequestStageType::kRequestStarted,
-               RequestStageType::kFirstRedirectReceived,
-               RequestStageType::kSecondRedirectReceived,
-               RequestStageType::kThirdOrLaterRedirectReceived,
-               RequestStageType::kResponseReceived,
-               RequestStageType::kRequestFailed,
-               RequestStageType::kRequestCancelledByRenderer,
-               RequestStageType::kRequestCancelledAfterTimeLimit,
-               RequestStageType::kBrowserShutdown,
-               RequestStageType::kLoaderCompleted,
-           }},
-          {RequestStageType::kRequestCancelledByRenderer,
-           {
-               RequestStageType::kRequestStarted,
-               RequestStageType::kFirstRedirectReceived,
-               RequestStageType::kSecondRedirectReceived,
-               RequestStageType::kThirdOrLaterRedirectReceived,
-               RequestStageType::kResponseReceived,
-               RequestStageType::kRequestFailed,
-               RequestStageType::kLoaderDisconnectedFromRenderer,
-               RequestStageType::kRequestCancelledAfterTimeLimit,
-               RequestStageType::kBrowserShutdown,
-               RequestStageType::kLoaderCompleted,
-           }},
-          {RequestStageType::kRequestCancelledAfterTimeLimit,
-           {
-               RequestStageType::kRequestStarted,
-               RequestStageType::kFirstRedirectReceived,
-               RequestStageType::kSecondRedirectReceived,
-               RequestStageType::kThirdOrLaterRedirectReceived,
-               RequestStageType::kResponseReceived,
-               RequestStageType::kRequestFailed,
-               RequestStageType::kLoaderDisconnectedFromRenderer,
-               RequestStageType::kRequestCancelledByRenderer,
-               RequestStageType::kBrowserShutdown,
-               RequestStageType::kLoaderCompleted,
-           }},
-          {RequestStageType::kBrowserShutdown,
-           {
-               RequestStageType::kRequestStarted,
-               RequestStageType::kFirstRedirectReceived,
-               RequestStageType::kSecondRedirectReceived,
-               RequestStageType::kThirdOrLaterRedirectReceived,
-               RequestStageType::kResponseReceived,
-               RequestStageType::kRequestFailed,
-               RequestStageType::kLoaderDisconnectedFromRenderer,
-               RequestStageType::kRequestCancelledByRenderer,
-               RequestStageType::kRequestCancelledAfterTimeLimit,
-               RequestStageType::kLoaderCompleted,
-           }},
-      }));
-
-  DCHECK_STATE_TRANSITION(transitions, current_stage_.type, next_stage.type);
-#endif  // DCHECK_IS_ON()
   // kLoaderCreated is the initial stage set in ctor.
   CHECK_NE(next_stage.type, RequestStageType::kLoaderCreated);
 
@@ -246,6 +120,9 @@
     case RequestStageType::kLoaderCompleted:
       CHECK(next_stage.status.has_value());
       break;
+    case RequestStageType::kRequestRetried:
+      CHECK(next_stage.status.has_value());
+      break;
   }
 
   AddStageMetrics(next_stage);
@@ -288,4 +165,12 @@
   ++num_redirects_;
 }
 
+uint32_t KeepAliveRequestTracker::GetNumRetries() const {
+  return num_retries_;
+}
+
+void KeepAliveRequestTracker::IncreaseNumRetries() {
+  ++num_retries_;
+}
+
 }  // namespace content
diff --git a/content/public/browser/keep_alive_request_tracker.h b/content/public/browser/keep_alive_request_tracker.h
index 8a92a54..6ea0cbf4 100644
--- a/content/public/browser/keep_alive_request_tracker.h
+++ b/content/public/browser/keep_alive_request_tracker.h
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include "base/functional/callback.h"
-#include "base/state_transitions.h"
 #include "content/common/content_export.h"
 #include "services/network/public/cpp/url_loader_completion_status.h"
 
@@ -87,10 +86,12 @@
     // The browser-side loader completes loading the request.
     kLoaderCompleted = 11,
 
-    kMaxValue = kLoaderCompleted,
+    // The browser-side loader has retried the request from the beginning.
+    kRequestRetried = 12,
+
+    kMaxValue = kRequestRetried,
   };
   // LINT.ThenChange(//tools/metrics/histograms/enums.xml:FetchKeepAliveRequestStage)
-  friend base::StateTransitions<RequestStageType>;
   friend std::ostream& operator<<(std::ostream&, const RequestStageType&);
 
   // RequestStage stores the stage-related info.
@@ -129,6 +130,9 @@
   uint32_t GetNumRedirects() const;
   void IncreaseNumRedirects();
 
+  uint32_t GetNumRetries() const;
+  void IncreaseNumRetries();
+
  private:
   RequestType request_type_;
 
@@ -140,6 +144,10 @@
   // Records the number of redrects the tracked fetch keepalive request has
   // experienced so far.
   uint32_t num_redirects_ = 0;
+
+  // Records the number of retries the tracked fetch keepalive request has
+  // experienced so far.
+  uint32_t num_retries_ = 0;
 };
 
 }  // namespace content
diff --git a/content/public/test/browser_task_environment_unittest.cc b/content/public/test/browser_task_environment_unittest.cc
index 95b7c786..1cbf21cb 100644
--- a/content/public/test/browser_task_environment_unittest.cc
+++ b/content/public/test/browser_task_environment_unittest.cc
@@ -4,9 +4,9 @@
 
 #include "content/public/test/browser_task_environment.h"
 
+#include <atomic>
 #include <string>
 
-#include "base/atomicops.h"
 #include "base/dcheck_is_on.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
@@ -35,12 +35,12 @@
 
 const char kDeathMatcher[] = "DCHECK failed:.*\n*.*BrowserTaskEnvironment";
 
-void PostTaskToUIThread(int iteration, base::subtle::Atomic32* tasks_run);
+void PostTaskToUIThread(int iteration, std::atomic<int32_t>* tasks_run);
 
-void PostToThreadPool(int iteration, base::subtle::Atomic32* tasks_run) {
+void PostToThreadPool(int iteration, std::atomic<int32_t>* tasks_run) {
   // All iterations but the first come from a task that was posted.
   if (iteration > 0)
-    base::subtle::NoBarrier_AtomicIncrement(tasks_run, 1);
+    tasks_run->fetch_add(1, std::memory_order_relaxed);
 
   if (iteration == kNumHops)
     return;
@@ -49,10 +49,10 @@
       FROM_HERE, base::BindOnce(&PostTaskToUIThread, iteration + 1, tasks_run));
 }
 
-void PostTaskToUIThread(int iteration, base::subtle::Atomic32* tasks_run) {
+void PostTaskToUIThread(int iteration, std::atomic<int32_t>* tasks_run) {
   // All iterations but the first come from a task that was posted.
   if (iteration > 0)
-    base::subtle::NoBarrier_AtomicIncrement(tasks_run, 1);
+    tasks_run->fetch_add(1, std::memory_order_relaxed);
 
   if (iteration == kNumHops)
     return;
@@ -66,7 +66,7 @@
 TEST(BrowserTaskEnvironmentTest, RunUntilIdle) {
   BrowserTaskEnvironment task_environment;
 
-  base::subtle::Atomic32 tasks_run = 0;
+  std::atomic<int32_t> tasks_run = 0;
 
   // Post half the tasks on ThreadPool and the other half on the UI thread
   // so they cross and the last hops aren't all on the same task runner.
@@ -80,7 +80,7 @@
 
   task_environment.RunUntilIdle();
 
-  EXPECT_EQ(kNumTasks * kNumHops, base::subtle::NoBarrier_Load(&tasks_run));
+  EXPECT_EQ(kNumTasks * kNumHops, tasks_run.load(std::memory_order_relaxed));
 }
 
 namespace {
diff --git a/content/public/test/keep_alive_url_loader_utils.cc b/content/public/test/keep_alive_url_loader_utils.cc
index 00316f1..9dab640 100644
--- a/content/public/test/keep_alive_url_loader_utils.cc
+++ b/content/public/test/keep_alive_url_loader_utils.cc
@@ -44,6 +44,7 @@
       "TimeDelta.LoaderDisconnectedFromRenderer",
       "TimeDelta.BrowserShutdown",
       "TimeDelta.LoaderCompleted",
+      "TimeDelta.RequestRetried",
       "TimeDelta.EventLogged",
   });
   return *names;
@@ -292,6 +293,7 @@
     KeepAliveRequestTracker::RequestType request_type,
     size_t category_id,
     size_t num_redirects,
+    size_t num_retries,
     bool is_context_detached,
     KeepAliveRequestTracker::RequestStageType end_stage,
     std::optional<KeepAliveRequestTracker::RequestStageType> previous_stage,
@@ -299,10 +301,13 @@
     std::optional<int64_t> failed_error_code,
     std::optional<int64_t> failed_extended_error_code,
     std::optional<int64_t> completed_error_code,
-    std::optional<int64_t> completed_extended_error_code)
+    std::optional<int64_t> completed_extended_error_code,
+    std::optional<int64_t> retried_error_code,
+    std::optional<int64_t> retried_extended_error_code)
     : request_type(request_type),
       category_id(category_id),
       num_redirects(num_redirects),
+      num_retries(num_retries),
       is_context_detached(is_context_detached),
       end_stage(end_stage),
       previous_stage(previous_stage),
@@ -310,7 +315,9 @@
       failed_error_code(failed_error_code),
       failed_extended_error_code(failed_extended_error_code),
       completed_error_code(completed_error_code),
-      completed_extended_error_code(completed_extended_error_code) {}
+      completed_extended_error_code(completed_extended_error_code),
+      retried_error_code(retried_error_code),
+      retried_extended_error_code(retried_extended_error_code) {}
 
 KeepAliveRequestUkmMatcher::CommonUkm::CommonUkm(const CommonUkm& other) =
     default;
@@ -333,6 +340,7 @@
     KeepAliveRequestTracker::RequestType request_type,
     size_t category_id,
     size_t num_redirects,
+    size_t num_retries,
     bool is_context_detached,
     KeepAliveRequestTracker::RequestStageType end_stage,
     std::optional<KeepAliveRequestTracker::RequestStageType> previous_stage,
@@ -340,7 +348,9 @@
     std::optional<int64_t> failed_error_code,
     std::optional<int64_t> failed_extended_error_code,
     std::optional<int64_t> completed_error_code,
-    std::optional<int64_t> completed_extended_error_code) {
+    std::optional<int64_t> completed_extended_error_code,
+    std::optional<int64_t> retried_error_code,
+    std::optional<int64_t> retried_extended_error_code) {
   EXPECT_TRUE(ukm_recorder().EntryHasMetric(entry, "Id.Low"));
   EXPECT_TRUE(ukm_recorder().EntryHasMetric(entry, "Id.High"));
   if (keepalive_token.has_value()) {
@@ -355,6 +365,8 @@
   ukm_recorder().ExpectEntryMetric(entry, "Category", category_id);
   ukm_recorder().ExpectEntryMetric(entry, "NumRedirects",
                                    static_cast<int64_t>(num_redirects));
+  ukm_recorder().ExpectEntryMetric(entry, "NumRetries",
+                                   static_cast<int64_t>(num_retries));
   ukm_recorder().ExpectEntryMetric(entry, "IsContextDetached",
                                    static_cast<int64_t>(is_context_detached));
   ukm_recorder().ExpectEntryMetric(entry, "EndStage",
@@ -401,12 +413,30 @@
     EXPECT_FALSE(ukm_recorder().EntryHasMetric(
         entry, "LoaderCompleted.ExtendedErrorCode"));
   }
+
+  if (retried_error_code.has_value()) {
+    ukm_recorder().ExpectEntryMetric(entry, "RequestRetried.ErrorCode",
+                                     static_cast<int64_t>(*retried_error_code));
+  } else {
+    EXPECT_FALSE(
+        ukm_recorder().EntryHasMetric(entry, "RequestRetried.ErrorCode"));
+  }
+
+  if (retried_extended_error_code.has_value()) {
+    ukm_recorder().ExpectEntryMetric(
+        entry, "RequestRetried.ExtendedErrorCode",
+        static_cast<int64_t>(*retried_extended_error_code));
+  } else {
+    EXPECT_FALSE(ukm_recorder().EntryHasMetric(
+        entry, "RequestRetried.ExtendedErrorCode"));
+  }
 }
 
 void KeepAliveRequestUkmMatcher::ExpectCommonUkm(
     KeepAliveRequestTracker::RequestType request_type,
     size_t category_id,
     size_t num_redirects,
+    size_t num_retries,
     bool is_context_detached,
     KeepAliveRequestTracker::RequestStageType end_stage,
     std::optional<KeepAliveRequestTracker::RequestStageType> previous_stage,
@@ -414,13 +444,16 @@
     std::optional<int64_t> failed_error_code,
     std::optional<int64_t> failed_extended_error_code,
     std::optional<int64_t> completed_error_code,
-    std::optional<int64_t> completed_extended_error_code) {
+    std::optional<int64_t> completed_extended_error_code,
+    std::optional<int64_t> retried_error_code,
+    std::optional<int64_t> retried_extended_error_code) {
   const ukm::mojom::UkmEntry* entry = GetUkmEntry();
-  ExpectCommonUkm(entry, request_type, category_id, num_redirects,
+  ExpectCommonUkm(entry, request_type, category_id, num_redirects, num_retries,
                   is_context_detached, end_stage, previous_stage,
                   keepalive_token, failed_error_code,
                   failed_extended_error_code, completed_error_code,
-                  completed_extended_error_code);
+                  completed_extended_error_code, retried_error_code,
+                  retried_extended_error_code);
 }
 
 void KeepAliveRequestUkmMatcher::ExpectCommonUkms(
@@ -434,10 +467,11 @@
   for (size_t i = 0; i < entries.size(); ++i) {
     ExpectCommonUkm(
         entries[i], ukms[i].request_type, ukms[i].category_id,
-        ukms[i].num_redirects, ukms[i].is_context_detached, ukms[i].end_stage,
-        ukms[i].previous_stage, ukms[i].keepalive_token,
+        ukms[i].num_redirects, ukms[i].num_retries, ukms[i].is_context_detached,
+        ukms[i].end_stage, ukms[i].previous_stage, ukms[i].keepalive_token,
         ukms[i].failed_error_code, ukms[i].failed_extended_error_code,
-        ukms[i].completed_error_code, ukms[i].completed_extended_error_code);
+        ukms[i].completed_error_code, ukms[i].completed_extended_error_code,
+        ukms[i].retried_error_code, ukms[i].retried_extended_error_code);
   }
 }
 
diff --git a/content/public/test/keep_alive_url_loader_utils.h b/content/public/test/keep_alive_url_loader_utils.h
index c6a037d..144da2f4 100644
--- a/content/public/test/keep_alive_url_loader_utils.h
+++ b/content/public/test/keep_alive_url_loader_utils.h
@@ -105,6 +105,7 @@
     KeepAliveRequestTracker::RequestType request_type;
     size_t category_id;
     size_t num_redirects;
+    size_t num_retries;
     bool is_context_detached;
     KeepAliveRequestTracker::RequestStageType end_stage;
     std::optional<KeepAliveRequestTracker::RequestStageType> previous_stage =
@@ -114,11 +115,14 @@
     std::optional<int64_t> failed_extended_error_code = std::nullopt;
     std::optional<int64_t> completed_error_code = std::nullopt;
     std::optional<int64_t> completed_extended_error_code = std::nullopt;
+    std::optional<int64_t> retried_error_code = std::nullopt;
+    std::optional<int64_t> retried_extended_error_code = std::nullopt;
 
     CommonUkm(
         KeepAliveRequestTracker::RequestType request_type,
         size_t category_id,
         size_t num_redirects,
+        size_t num_retries,
         bool is_context_detached,
         KeepAliveRequestTracker::RequestStageType end_stage,
         std::optional<KeepAliveRequestTracker::RequestStageType>
@@ -128,7 +132,9 @@
         std::optional<int64_t> failed_error_code = std::nullopt,
         std::optional<int64_t> failed_extended_error_code = std::nullopt,
         std::optional<int64_t> completed_error_code = std::nullopt,
-        std::optional<int64_t> completed_extended_error_code = std::nullopt);
+        std::optional<int64_t> completed_extended_error_code = std::nullopt,
+        std::optional<int64_t> retried_error_code = std::nullopt,
+        std::optional<int64_t> retried_extended_error_code = std::nullopt);
     CommonUkm(const CommonUkm& other);
   };
 
@@ -140,6 +146,7 @@
       KeepAliveRequestTracker::RequestType request_type,
       size_t category_id,
       size_t num_redirects,
+      size_t num_retries,
       bool is_context_detached,
       KeepAliveRequestTracker::RequestStageType end_stage,
       std::optional<KeepAliveRequestTracker::RequestStageType> previous_stage =
@@ -149,7 +156,9 @@
       std::optional<int64_t> failed_error_code = std::nullopt,
       std::optional<int64_t> failed_extended_error_code = std::nullopt,
       std::optional<int64_t> completed_error_code = std::nullopt,
-      std::optional<int64_t> completed_extended_error_code = std::nullopt);
+      std::optional<int64_t> completed_extended_error_code = std::nullopt,
+      std::optional<int64_t> retried_error_code = std::nullopt,
+      std::optional<int64_t> retried_extended_error_code = std::nullopt);
   void ExpectCommonUkms(const std::vector<CommonUkm>& ukms);
 
   // Verifies that UKM TimeDelta.* listed in `time_sorted_metric_names` are all
@@ -169,6 +178,7 @@
       KeepAliveRequestTracker::RequestType request_type,
       size_t category_id,
       size_t num_redirects,
+      size_t num_retries,
       bool is_context_detached,
       KeepAliveRequestTracker::RequestStageType end_stage,
       std::optional<KeepAliveRequestTracker::RequestStageType> previous_stage =
@@ -178,7 +188,9 @@
       std::optional<int64_t> failed_error_code = std::nullopt,
       std::optional<int64_t> failed_extended_error_code = std::nullopt,
       std::optional<int64_t> completed_error_code = std::nullopt,
-      std::optional<int64_t> completed_extended_error_code = std::nullopt);
+      std::optional<int64_t> completed_extended_error_code = std::nullopt,
+      std::optional<int64_t> retried_error_code = std::nullopt,
+      std::optional<int64_t> retried_extended_error_code = std::nullopt);
 };
 
 // `NavigationKeepAliveRequestUkmMatcher` provides common matchers and
diff --git a/device/base/synchronization/one_writer_seqlock_unittest.cc b/device/base/synchronization/one_writer_seqlock_unittest.cc
index 175ab5a..b5eac00 100644
--- a/device/base/synchronization/one_writer_seqlock_unittest.cc
+++ b/device/base/synchronization/one_writer_seqlock_unittest.cc
@@ -46,7 +46,7 @@
 
     for (unsigned i = 0; i < 1000; ++i) {
       TestData copy;
-      base::subtle::Atomic32 version;
+      int32_t version;
       do {
         version = seqlock_->ReadBegin();
         OneWriterSeqLock::AtomicReaderMemcpy(&copy, data_.get(),
@@ -84,7 +84,7 @@
     }
 
     for (unsigned i = 0; i < 10; ++i) {
-      base::subtle::Atomic32 version;
+      int32_t version;
       version = seqlock_->ReadBegin(100);
 
       EXPECT_NE(version & 1, 0);
diff --git a/device/gamepad/gamepad_provider_unittest.cc b/device/gamepad/gamepad_provider_unittest.cc
index a7e8c1e..64d311c 100644
--- a/device/gamepad/gamepad_provider_unittest.cc
+++ b/device/gamepad/gamepad_provider_unittest.cc
@@ -68,8 +68,8 @@
   // the buffer is not in a consistent state, so we also require that the value
   // is even before continuing.
   void WaitForData(const GamepadHardwareBuffer* buffer) {
-    const base::subtle::Atomic32 initial_version = buffer->seqlock.ReadBegin();
-    base::subtle::Atomic32 current_version;
+    const int32_t initial_version = buffer->seqlock.ReadBegin();
+    int32_t current_version;
     do {
       base::PlatformThread::Sleep(base::Milliseconds(10));
       current_version = buffer->seqlock.ReadBegin();
@@ -87,7 +87,7 @@
   void ReadGamepadHardwareBuffer(const GamepadHardwareBuffer* buffer,
                                  Gamepads* output) {
     memset(output, 0, sizeof(Gamepads));
-    base::subtle::Atomic32 version;
+    int32_t version;
     do {
       version = buffer->seqlock.ReadBegin();
       memcpy(output, &buffer->data, sizeof(Gamepads));
diff --git a/device/gamepad/wgi_data_fetcher_win_unittest.cc b/device/gamepad/wgi_data_fetcher_win_unittest.cc
index 230e66e..ec4ef2ea 100644
--- a/device/gamepad/wgi_data_fetcher_win_unittest.cc
+++ b/device/gamepad/wgi_data_fetcher_win_unittest.cc
@@ -288,8 +288,8 @@
   // the buffer is not in a consistent state, so we also require that the value
   // is even before continuing.
   void WaitForData(const GamepadHardwareBuffer* buffer) {
-    const base::subtle::Atomic32 initial_version = buffer->seqlock.ReadBegin();
-    base::subtle::Atomic32 current_version;
+    const int32_t initial_version = buffer->seqlock.ReadBegin();
+    int32_t current_version;
     do {
       base::PlatformThread::Sleep(base::Milliseconds(10));
       current_version = buffer->seqlock.ReadBegin();
@@ -307,7 +307,7 @@
   void ReadGamepadHardwareBuffer(const GamepadHardwareBuffer* buffer,
                                  Gamepads* output) {
     memset(output, 0, sizeof(Gamepads));
-    base::subtle::Atomic32 version;
+    int32_t version;
     do {
       version = buffer->seqlock.ReadBegin();
       memcpy(output, &buffer->data, sizeof(Gamepads));
diff --git a/extensions/browser/api/declarative_net_request/ruleset_manager.h b/extensions/browser/api/declarative_net_request/ruleset_manager.h
index cb00b79..7e0a3ad 100644
--- a/extensions/browser/api/declarative_net_request/ruleset_manager.h
+++ b/extensions/browser/api/declarative_net_request/ruleset_manager.h
@@ -28,6 +28,10 @@
 class RenderFrameHost;
 }
 
+namespace net {
+class HttpResponseHeaders;
+}
+
 namespace extensions {
 class ExtensionPrefs;
 class PermissionHelper;
diff --git a/extensions/browser/api/web_request/web_request_info_unittest.cc b/extensions/browser/api/web_request/web_request_info_unittest.cc
index fb6d9a7..50ad265d 100644
--- a/extensions/browser/api/web_request/web_request_info_unittest.cc
+++ b/extensions/browser/api/web_request/web_request_info_unittest.cc
@@ -11,6 +11,7 @@
 #include "extensions/browser/extension_navigation_ui_data.h"
 #include "services/network/public/cpp/resource_request_body.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
 
 #include "base/json/json_writer.h"
 
diff --git a/extensions/browser/api/web_request/web_request_resource_type.cc b/extensions/browser/api/web_request/web_request_resource_type.cc
index 87a8ed02..c9bbb8d 100644
--- a/extensions/browser/api/web_request/web_request_resource_type.cc
+++ b/extensions/browser/api/web_request/web_request_resource_type.cc
@@ -10,6 +10,7 @@
 #include "base/check_op.h"
 #include "base/notreached.h"
 #include "base/numerics/safe_conversions.h"
+#include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/mojom/fetch_api.mojom-shared.h"
 
 namespace extensions {
diff --git a/extensions/browser/api/web_request/web_request_resource_type.h b/extensions/browser/api/web_request/web_request_resource_type.h
index e740a6d..e56b6d63 100644
--- a/extensions/browser/api/web_request/web_request_resource_type.h
+++ b/extensions/browser/api/web_request/web_request_resource_type.h
@@ -9,8 +9,9 @@
 
 #include <string_view>
 
-#include "services/network/public/cpp/resource_request.h"
-#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
+namespace network {
+struct ResourceRequest;
+}
 
 namespace extensions {
 
diff --git a/extensions/browser/core_browser_context_keyed_service_factories.cc b/extensions/browser/core_browser_context_keyed_service_factories.cc
index 776b1b5..4276189 100644
--- a/extensions/browser/core_browser_context_keyed_service_factories.cc
+++ b/extensions/browser/core_browser_context_keyed_service_factories.cc
@@ -10,6 +10,7 @@
 #include "extensions/browser/event_router_factory.h"
 #include "extensions/browser/extension_action_manager.h"
 #include "extensions/browser/extension_function.h"
+#include "extensions/browser/extension_navigation_registry.h"
 #include "extensions/browser/extension_prefs_factory.h"
 #include "extensions/browser/extension_prefs_helper_factory.h"
 #include "extensions/browser/extension_protocols.h"
@@ -26,10 +27,6 @@
 #include "extensions/browser/user_script_world_configuration_manager.h"
 #include "extensions/buildflags/buildflags.h"
 
-#if BUILDFLAG(ENABLE_EXTENSIONS)
-#include "extensions/browser/extension_navigation_registry.h"
-#endif
-
 #if BUILDFLAG(ENABLE_GUEST_VIEW)
 #include "extensions/browser/guest_view/mime_handler_view/mime_handler_stream_manager.h"
 #endif
@@ -52,6 +49,7 @@
   ExtensionActionManager::GetFactory();
   ExtensionFunction::EnsureShutdownNotifierFactoryBuilt();
   ExtensionPrefsFactory::GetInstance();
+  ExtensionNavigationRegistry::GetFactoryInstance();
   ExtensionPrefsHelperFactory::GetInstance();
   ExtensionRegistrarFactory::GetInstance();
   ImageLoaderFactory::GetInstance();
@@ -67,9 +65,6 @@
   ServiceWorkerTaskQueueFactory::GetInstance();
   UpdateServiceFactory::GetInstance();
   UserScriptWorldConfigurationManager::GetFactory();
-#if BUILDFLAG(ENABLE_EXTENSIONS)
-  ExtensionNavigationRegistry::GetFactoryInstance();
-#endif
   WebRequestEventRouterFactory::GetInstance();
 }
 
diff --git a/gpu/ipc/service/gpu_channel_manager.cc b/gpu/ipc/service/gpu_channel_manager.cc
index 45374fc..5ac16ab 100644
--- a/gpu/ipc/service/gpu_channel_manager.cc
+++ b/gpu/ipc/service/gpu_channel_manager.cc
@@ -571,13 +571,6 @@
   }
 }
 
-void GpuChannelManager::DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
-                                               int client_id) {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
-  gpu_memory_buffer_factory_->DestroyGpuMemoryBuffer(id, client_id);
-}
-
 void GpuChannelManager::PopulateCache(const gpu::GpuDiskCacheHandle& handle,
                                       const std::string& key,
                                       const std::string& data) {
diff --git a/gpu/ipc/service/gpu_channel_manager.h b/gpu/ipc/service/gpu_channel_manager.h
index 3fbaf33..f8bfd4d 100644
--- a/gpu/ipc/service/gpu_channel_manager.h
+++ b/gpu/ipc/service/gpu_channel_manager.h
@@ -131,7 +131,6 @@
   void PopulateCache(const gpu::GpuDiskCacheHandle& handle,
                      const std::string& key,
                      const std::string& program);
-  void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, int client_id);
 #if BUILDFLAG(IS_ANDROID)
   void WakeUpGpu();
 #endif
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory.cc b/gpu/ipc/service/gpu_memory_buffer_factory.cc
index b01c0d0d..482a3c78 100644
--- a/gpu/ipc/service/gpu_memory_buffer_factory.cc
+++ b/gpu/ipc/service/gpu_memory_buffer_factory.cc
@@ -37,17 +37,13 @@
 
   // GpuMemoryBufferFactory:
   gfx::GpuMemoryBufferHandle CreateGpuMemoryBuffer(
-      gfx::GpuMemoryBufferId id,
       const gfx::Size& size,
       const gfx::Size& framebuffer_size,
       gfx::BufferFormat format,
       gfx::BufferUsage usage,
-      int client_id,
       SurfaceHandle surface_handle) override {
     return gfx::GpuMemoryBufferHandle();
   }
-  void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
-                              int client_id) override {}
   bool FillSharedMemoryRegionWithBufferContents(
       gfx::GpuMemoryBufferHandle buffer_handle,
       base::UnsafeSharedMemoryRegion shared_memory) override {
@@ -86,26 +82,8 @@
     const gfx::Size& size,
     gfx::BufferFormat format,
     gfx::BufferUsage usage) {
-  // Note that |gmb_id| is used as a cache key in GpuMemoryBufferFactory but
-  // since we immediately call DestroyGpuMemoryBuffer here, this value does not
-  // matter. Hence its kept as constant for every client calling this method
-  // instead of always increasing id. kMappableSIClientId and |gmb_id| will
-  // ensure that the cache key is always unique and does not clash with
-  // non-mappable GMB cases.
-  auto gmb_id = gfx::GpuMemoryBufferId(static_cast<int>(id));
-  auto handle = CreateGpuMemoryBuffer(gmb_id, size, /*framebuffer_size=*/size,
-                                      format, usage, kMappableSIClientId,
-                                      gpu::kNullSurfaceHandle);
-
-  // Note that this removes the handle from the cache in
-  // GpuMemoryBufferFactory. Shared image backings caches the handle and still
-  // has the ref. So the handle is still alive until the mailbox is destroyed.
-  // This is only needed since we are currently using GpuMemoryBufferFactory.
-  // TODO(crbug.com/40283108) : Once we remove the GMB abstraction and starts
-  // using a separate factory to create the native buffers, we can stop
-  // caching the handles in them, remove using gmb_id and also remove the
-  // destroy api.
-  DestroyGpuMemoryBuffer(gmb_id, kMappableSIClientId);
+  auto handle = CreateGpuMemoryBuffer(size, /*framebuffer_size=*/size, format,
+                                      usage, gpu::kNullSurfaceHandle);
   return handle;
 }
 
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory.h b/gpu/ipc/service/gpu_memory_buffer_factory.h
index 8ad6128..1e220c85 100644
--- a/gpu/ipc/service/gpu_memory_buffer_factory.h
+++ b/gpu/ipc/service/gpu_memory_buffer_factory.h
@@ -63,19 +63,12 @@
   // particular GpuMemoryBufferFactory implementation supports it (for example,
   // when creating a buffer for scanout using the Ozone/DRM backend).
   virtual gfx::GpuMemoryBufferHandle CreateGpuMemoryBuffer(
-      gfx::GpuMemoryBufferId id,
       const gfx::Size& size,
       const gfx::Size& framebuffer_size,
       gfx::BufferFormat format,
       gfx::BufferUsage usage,
-      int client_id,
       SurfaceHandle surface_handle) = 0;
 
-  // Destroys GPU memory buffer identified by |id|. It can be called on any
-  // thread.
-  virtual void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
-                                      int client_id) = 0;
-
   // Fills |shared_memory| with the contents of the provided |buffer_handle|
   virtual bool FillSharedMemoryRegionWithBufferContents(
       gfx::GpuMemoryBufferHandle buffer_handle,
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.cc b/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.cc
index a2c7228..b85c1de 100644
--- a/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.cc
+++ b/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.cc
@@ -92,12 +92,10 @@
 
 gfx::GpuMemoryBufferHandle
 GpuMemoryBufferFactoryDXGI::CreateGpuMemoryBufferOnIO(
-    gfx::GpuMemoryBufferId id,
     const gfx::Size& size,
     const gfx::Size& framebuffer_size,
     gfx::BufferFormat format,
     gfx::BufferUsage usage,
-    int client_id,
     SurfaceHandle surface_handle) {
   DCHECK(io_runner_);
 
@@ -109,18 +107,16 @@
       base::BindOnce(
           [](gfx::GpuMemoryBufferHandle* out_gmb_handle,
              base::WaitableEvent* waitable_event,
-             GpuMemoryBufferFactoryDXGI* factory, gfx::GpuMemoryBufferId id,
-             const gfx::Size& size, const gfx::Size& framebuffer_size,
-             gfx::BufferFormat format, gfx::BufferUsage usage, int client_id,
-             SurfaceHandle surface_handle) {
+             GpuMemoryBufferFactoryDXGI* factory, const gfx::Size& size,
+             const gfx::Size& framebuffer_size, gfx::BufferFormat format,
+             gfx::BufferUsage usage, SurfaceHandle surface_handle) {
             *out_gmb_handle = factory->CreateGpuMemoryBuffer(
-                id, size, framebuffer_size, format, usage, client_id,
-                surface_handle);
+                size, framebuffer_size, format, usage, surface_handle);
 
             waitable_event->Signal();
           },
-          &result, &event, this, id, size, framebuffer_size, format, usage,
-          client_id, surface_handle));
+          &result, &event, this, size, framebuffer_size, format, usage,
+          surface_handle));
 
   event.Wait();
 
@@ -128,17 +124,15 @@
 }
 
 gfx::GpuMemoryBufferHandle GpuMemoryBufferFactoryDXGI::CreateGpuMemoryBuffer(
-    gfx::GpuMemoryBufferId id,
     const gfx::Size& size,
     const gfx::Size& framebuffer_size,
     gfx::BufferFormat format,
     gfx::BufferUsage usage,
-    int client_id,
     SurfaceHandle surface_handle) {
   if (io_runner_ && !io_runner_->BelongsToCurrentThread()) {
     // Thread-hop is required!
-    return CreateGpuMemoryBufferOnIO(id, size, framebuffer_size, format, usage,
-                                     client_id, surface_handle);
+    return CreateGpuMemoryBufferOnIO(size, framebuffer_size, format, usage,
+                                     surface_handle);
   }
 
   TRACE_EVENT0("gpu", "GpuMemoryBufferFactoryDXGI::CreateGpuMemoryBuffer");
@@ -218,10 +212,6 @@
   return handle;
 }
 
-void GpuMemoryBufferFactoryDXGI::DestroyGpuMemoryBuffer(
-    gfx::GpuMemoryBufferId id,
-    int client_id) {}
-
 bool GpuMemoryBufferFactoryDXGI::FillSharedMemoryRegionWithBufferContents(
     gfx::GpuMemoryBufferHandle buffer_handle,
     base::UnsafeSharedMemoryRegion shared_memory) {
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.h b/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.h
index 3c49bac..72f75555d 100644
--- a/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.h
+++ b/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.h
@@ -37,15 +37,11 @@
 
   // Overridden from GpuMemoryBufferFactory:
   gfx::GpuMemoryBufferHandle CreateGpuMemoryBuffer(
-      gfx::GpuMemoryBufferId id,
       const gfx::Size& size,
       const gfx::Size& framebuffer_size,
       gfx::BufferFormat format,
       gfx::BufferUsage usage,
-      int client_id,
       SurfaceHandle surface_handle) override;
-  void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
-                              int client_id) override;
   bool FillSharedMemoryRegionWithBufferContents(
       gfx::GpuMemoryBufferHandle buffer_handle,
       base::UnsafeSharedMemoryRegion shared_memory) override;
@@ -54,12 +50,10 @@
   Microsoft::WRL::ComPtr<ID3D11Device> GetOrCreateD3D11Device();
 
   gfx::GpuMemoryBufferHandle CreateGpuMemoryBufferOnIO(
-      gfx::GpuMemoryBufferId id,
       const gfx::Size& size,
       const gfx::Size& framebuffer_size,
       gfx::BufferFormat format,
       gfx::BufferUsage usage,
-      int client_id,
       SurfaceHandle surface_handle);
 
   Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device_
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_io_surface.cc b/gpu/ipc/service/gpu_memory_buffer_factory_io_surface.cc
index da03c8d0..1b9786b 100644
--- a/gpu/ipc/service/gpu_memory_buffer_factory_io_surface.cc
+++ b/gpu/ipc/service/gpu_memory_buffer_factory_io_surface.cc
@@ -18,26 +18,16 @@
 
 namespace gpu {
 
-namespace {
-
-// A GpuMemoryBuffer with client_id = 0 behaves like anonymous shared memory.
-const int kAnonymousClientId = 0;
-
-}  // namespace
-
 GpuMemoryBufferFactoryIOSurface::GpuMemoryBufferFactoryIOSurface() = default;
 GpuMemoryBufferFactoryIOSurface::~GpuMemoryBufferFactoryIOSurface() = default;
 
 gfx::GpuMemoryBufferHandle
 GpuMemoryBufferFactoryIOSurface::CreateGpuMemoryBuffer(
-    gfx::GpuMemoryBufferId id,
     const gfx::Size& size,
     const gfx::Size& framebuffer_size,
     gfx::BufferFormat format,
     gfx::BufferUsage usage,
-    int client_id,
     SurfaceHandle surface_handle) {
-  DCHECK_NE(client_id, kAnonymousClientId);
   DCHECK_EQ(framebuffer_size, size);
 
   bool should_clear = true;
@@ -51,10 +41,6 @@
   return gfx::GpuMemoryBufferHandle(std::move(io_surface));
 }
 
-void GpuMemoryBufferFactoryIOSurface::DestroyGpuMemoryBuffer(
-    gfx::GpuMemoryBufferId id,
-    int client_id) {}
-
 bool GpuMemoryBufferFactoryIOSurface::FillSharedMemoryRegionWithBufferContents(
     gfx::GpuMemoryBufferHandle buffer_handle,
     base::UnsafeSharedMemoryRegion shared_memory) {
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_io_surface.h b/gpu/ipc/service/gpu_memory_buffer_factory_io_surface.h
index 8fc24c0..2a254ad 100644
--- a/gpu/ipc/service/gpu_memory_buffer_factory_io_surface.h
+++ b/gpu/ipc/service/gpu_memory_buffer_factory_io_surface.h
@@ -23,15 +23,11 @@
 
   // Overridden from GpuMemoryBufferFactory:
   gfx::GpuMemoryBufferHandle CreateGpuMemoryBuffer(
-      gfx::GpuMemoryBufferId id,
       const gfx::Size& size,
       const gfx::Size& framebuffer_size,
       gfx::BufferFormat format,
       gfx::BufferUsage usage,
-      int client_id,
       SurfaceHandle surface_handle) override;
-  void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
-                              int client_id) override;
   bool FillSharedMemoryRegionWithBufferContents(
       gfx::GpuMemoryBufferHandle buffer_handle,
       base::UnsafeSharedMemoryRegion shared_memory) override;
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap.cc b/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap.cc
index 2a45722..c600495 100644
--- a/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap.cc
+++ b/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap.cc
@@ -34,28 +34,18 @@
 
 gfx::GpuMemoryBufferHandle
 GpuMemoryBufferFactoryNativePixmap::CreateGpuMemoryBuffer(
-    gfx::GpuMemoryBufferId id,
     const gfx::Size& size,
     const gfx::Size& framebuffer_size,
     gfx::BufferFormat format,
     gfx::BufferUsage usage,
-    int client_id,
     SurfaceHandle surface_handle) {
   scoped_refptr<gfx::NativePixmap> pixmap =
       ui::OzonePlatform::GetInstance()
           ->GetSurfaceFactoryOzone()
           ->CreateNativePixmap(surface_handle, GetVulkanDeviceQueue(), size,
                                format, usage, framebuffer_size);
-  return CreateGpuMemoryBufferFromNativePixmap(id, size, format, usage,
-                                               client_id, std::move(pixmap));
-}
-
-void GpuMemoryBufferFactoryNativePixmap::DestroyGpuMemoryBuffer(
-    gfx::GpuMemoryBufferId id,
-    int client_id) {
-  base::AutoLock lock(native_pixmaps_lock_);
-  NativePixmapMapKey key(id.id, client_id);
-  native_pixmaps_.erase(key);
+  return CreateGpuMemoryBufferFromNativePixmap(size, format, usage,
+                                               std::move(pixmap));
 }
 
 bool GpuMemoryBufferFactoryNativePixmap::
@@ -76,11 +66,9 @@
 
 gfx::GpuMemoryBufferHandle
 GpuMemoryBufferFactoryNativePixmap::CreateGpuMemoryBufferFromNativePixmap(
-    gfx::GpuMemoryBufferId id,
     const gfx::Size& size,
     gfx::BufferFormat format,
     gfx::BufferUsage usage,
-    int client_id,
     scoped_refptr<gfx::NativePixmap> pixmap) {
   if (!pixmap.get()) {
     DLOG(ERROR) << "Failed to create pixmap " << size.ToString() << ",  "
@@ -94,17 +82,7 @@
     return gfx::GpuMemoryBufferHandle();
   }
 
-  gfx::GpuMemoryBufferHandle new_handle(std::move(native_pixmap_handle));
-
-  // TODO(reveman): Remove this once crbug.com/628334 has been fixed.
-  {
-    base::AutoLock lock(native_pixmaps_lock_);
-    NativePixmapMapKey key(id.id, client_id);
-    DCHECK(native_pixmaps_.find(key) == native_pixmaps_.end());
-    native_pixmaps_[key] = pixmap;
-  }
-
-  return new_handle;
+  return gfx::GpuMemoryBufferHandle(std::move(native_pixmap_handle));
 }
 
 }  // namespace gpu
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap.h b/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap.h
index bcc77d5b..749051c63 100644
--- a/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap.h
+++ b/gpu/ipc/service/gpu_memory_buffer_factory_native_pixmap.h
@@ -7,11 +7,6 @@
 
 #include <vulkan/vulkan_core.h>
 
-#include <unordered_map>
-#include <utility>
-
-#include "base/hash/hash.h"
-#include "base/synchronization/lock.h"
 #include "gpu/ipc/service/gpu_ipc_service_export.h"
 #include "gpu/ipc/service/gpu_memory_buffer_factory.h"
 #include "ui/gfx/native_pixmap.h"
@@ -36,41 +31,26 @@
 
   // Overridden from GpuMemoryBufferFactory:
   gfx::GpuMemoryBufferHandle CreateGpuMemoryBuffer(
-      gfx::GpuMemoryBufferId id,
       const gfx::Size& size,
       const gfx::Size& framebuffer_size,
       gfx::BufferFormat format,
       gfx::BufferUsage usage,
-      int client_id,
       SurfaceHandle surface_handle) override;
-  void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
-                              int client_id) override;
   bool FillSharedMemoryRegionWithBufferContents(
       gfx::GpuMemoryBufferHandle buffer_handle,
       base::UnsafeSharedMemoryRegion shared_memory) override;
 
  private:
-  using NativePixmapMapKey = std::pair<int, int>;
-  using NativePixmapMapKeyHash = base::IntPairHash<NativePixmapMapKey>;
-  using NativePixmapMap = std::unordered_map<NativePixmapMapKey,
-                                             scoped_refptr<gfx::NativePixmap>,
-                                             NativePixmapMapKeyHash>;
-
   gfx::GpuMemoryBufferHandle CreateGpuMemoryBufferFromNativePixmap(
-      gfx::GpuMemoryBufferId id,
       const gfx::Size& size,
       gfx::BufferFormat format,
       gfx::BufferUsage usage,
-      int client_id,
       scoped_refptr<gfx::NativePixmap> pixmap);
 
   VulkanDeviceQueue* GetVulkanDeviceQueue();
 
   scoped_refptr<viz::VulkanContextProvider> vulkan_context_provider_;
 
-  NativePixmapMap native_pixmaps_;
-  base::Lock native_pixmaps_lock_;
-
   base::WeakPtrFactory<GpuMemoryBufferFactoryNativePixmap> weak_factory_{this};
 };
 
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_test_template.h b/gpu/ipc/service/gpu_memory_buffer_factory_test_template.h
index 5d4bd647..c215d56 100644
--- a/gpu/ipc/service/gpu_memory_buffer_factory_test_template.h
+++ b/gpu/ipc/service/gpu_memory_buffer_factory_test_template.h
@@ -53,11 +53,6 @@
 TYPED_TEST_SUITE_P(GpuMemoryBufferFactoryTest);
 
 TYPED_TEST_P(GpuMemoryBufferFactoryTest, CreateGpuMemoryBuffer) {
-  const gfx::GpuMemoryBufferId kBufferId(1);
-  const int kClientId = 1;
-
-  gfx::Size buffer_size(2, 2);
-
   for (auto format : gfx::GetBufferFormatsForTesting()) {
     gfx::BufferUsage usages[] = {
         gfx::BufferUsage::GPU_READ,
@@ -81,11 +76,10 @@
       }
 
       gfx::GpuMemoryBufferHandle handle =
-          TestFixture::factory_.CreateGpuMemoryBuffer(
-              kBufferId, buffer_size, /*framebuffer_size=*/buffer_size, format,
-              usage, kClientId, gpu::kNullSurfaceHandle);
+          TestFixture::factory_.CreateNativeGmbHandle(
+              gpu::MappableSIClientGmbId::kGpuServiceImpl, gfx::Size(2, 2),
+              format, usage);
       EXPECT_NE(handle.type, gfx::EMPTY_BUFFER);
-      TestFixture::factory_.DestroyGpuMemoryBuffer(kBufferId, kClientId);
     }
   }
 }
diff --git a/gpu/vulkan/vulkan_image_unittest.cc b/gpu/vulkan/vulkan_image_unittest.cc
index d5ced76..f076a5c8 100644
--- a/gpu/vulkan/vulkan_image_unittest.cc
+++ b/gpu/vulkan/vulkan_image_unittest.cc
@@ -160,12 +160,10 @@
       {gfx::BufferFormat::RGBA_1010102, VK_FORMAT_A2B10G10R10_UNORM_PACK32},
   };
   for (const auto format : formats) {
-    gfx::GpuMemoryBufferId id(1);
     gfx::BufferUsage buffer_usage = gfx::BufferUsage::SCANOUT;
-    int client_id = 1;
-    auto gmb_handle = factory->CreateGpuMemoryBuffer(
-        id, size, /*framebuffer_size=*/size, format.buffer, buffer_usage,
-        client_id, kNullSurfaceHandle);
+    auto gmb_handle = factory->CreateNativeGmbHandle(
+        gpu::MappableSIClientGmbId::kGpuServiceImpl, size, format.buffer,
+        buffer_usage);
     EXPECT_TRUE(!gmb_handle.is_null());
     EXPECT_EQ(gmb_handle.type,
               gfx::GpuMemoryBufferType::ANDROID_HARDWARE_BUFFER);
@@ -182,7 +180,6 @@
     EXPECT_NE(image->device_memory(),
               static_cast<VkDeviceMemory>(VK_NULL_HANDLE));
     image->Destroy();
-    factory->DestroyGpuMemoryBuffer(id, client_id);
   }
 }
 #endif
diff --git a/internal b/internal
index c839822..084cdb5 160000
--- a/internal
+++ b/internal
@@ -1 +1 @@
-Subproject commit c839822533995cd97f48192847ba454aa0957927
+Subproject commit 084cdb580c74879a21896f9edc873f29e11803a4
diff --git a/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.mm b/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.mm
index 5ec376f3..ea9f08e 100644
--- a/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.mm
+++ b/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.mm
@@ -176,7 +176,9 @@
 #import "ios/chrome/browser/push_notification/ui_bundled/notifications_opt_in_coordinator_delegate.h"
 #import "ios/chrome/browser/qr_scanner/ui_bundled/qr_scanner_legacy_coordinator.h"
 #import "ios/chrome/browser/reader_mode/coordinator/reader_mode_coordinator.h"
+#import "ios/chrome/browser/reader_mode/model/features.h"
 #import "ios/chrome/browser/reader_mode/model/reader_mode_browser_agent.h"
+#import "ios/chrome/browser/reader_mode/model/reader_mode_browser_agent_delegate.h"
 #import "ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.h"
 #import "ios/chrome/browser/reading_list/model/reading_list_browser_agent.h"
 #import "ios/chrome/browser/reading_list/ui_bundled/reading_list_coordinator.h"
@@ -397,6 +399,7 @@
     PolicyChangeCommands,
     PreloadControllerDelegate,
     QuickDeleteCommands,
+    ReaderModeBrowserAgentDelegate,
     ReaderModeCommands,
     ReadingListCoordinatorDelegate,
     RecentTabsCoordinatorDelegate,
@@ -726,6 +729,28 @@
   WelcomeBackCoordinator* _welcomeBackCoordinator;
 }
 
+#pragma mark - ReaderModeBrowserAgentDelegate
+
+- (void)showReaderModeContentFromBrowserAgent:
+    (ReaderModeBrowserAgent*)browserAgent {
+  if (_readerModeCoordinator) {
+    return;
+  }
+  _readerModeCoordinator = [[ReaderModeCoordinator alloc]
+      initWithBaseViewController:self.viewController
+                         browser:self.browser];
+  [_readerModeCoordinator start];
+}
+
+- (void)hideReaderModeContentFromBrowserAgent:
+    (ReaderModeBrowserAgent*)browserAgent {
+  if (!_readerModeCoordinator) {
+    return;
+  }
+  [_readerModeCoordinator stop];
+  _readerModeCoordinator = nil;
+}
+
 #pragma mark - ChromeCoordinator
 
 - (void)start {
@@ -2730,26 +2755,14 @@
 
 #pragma mark - ReaderModeCommands
 
-- (void)showReaderMode {
+- (void)showReaderModeFromAccessPoint:(ReaderModeAccessPoint)accessPoint {
   web::WebState* activeWebState = self.activeWebState;
   if (!activeWebState) {
     return;
   }
   ReaderModeTabHelper* readerModeTabHelper =
       ReaderModeTabHelper::FromWebState(activeWebState);
-  if (!readerModeTabHelper->IsActive()) {
-    readerModeTabHelper->SetActive(true);
-    return;
-  }
-
-  if (_readerModeCoordinator) {
-    // If the Reader mode UI is already presented then there is nothing to do.
-    return;
-  }
-  _readerModeCoordinator = [[ReaderModeCoordinator alloc]
-      initWithBaseViewController:self.browserContainerCoordinator.viewController
-                         browser:self.browser];
-  [_readerModeCoordinator start];
+  readerModeTabHelper->ActivateReader(accessPoint);
 }
 
 - (void)hideReaderMode {
@@ -2759,17 +2772,7 @@
   }
   ReaderModeTabHelper* readerModeTabHelper =
       ReaderModeTabHelper::FromWebState(activeWebState);
-  if (readerModeTabHelper->IsActive()) {
-    readerModeTabHelper->SetActive(false);
-    return;
-  }
-
-  if (!_readerModeCoordinator) {
-    // If the Reader mode UI is already dismissed then there is nothing to do.
-    return;
-  }
-  [_readerModeCoordinator stop];
-  _readerModeCoordinator = nil;
+  readerModeTabHelper->DeactivateReader();
 }
 
 #pragma mark - FindInPageCommands
@@ -3343,12 +3346,7 @@
   ReaderModeBrowserAgent* readerModeBrowserAgent =
       ReaderModeBrowserAgent::FromBrowser(self.browser);
   if (readerModeBrowserAgent) {
-    readerModeBrowserAgent->SetReaderModeHandler(HandlerForProtocol(
-        self.browser->GetCommandDispatcher(), ReaderModeCommands));
-    readerModeBrowserAgent->SetReaderModeChipHandler(HandlerForProtocol(
-        self.browser->GetCommandDispatcher(), ReaderModeChipCommands));
-    readerModeBrowserAgent->SetSnackbarHandler(
-        static_cast<id<SnackbarCommands>>(commandDispatcher));
+    readerModeBrowserAgent->SetDelegate(self);
   }
 }
 
@@ -3389,9 +3387,7 @@
   ReaderModeBrowserAgent* readerModeBrowserAgent =
       ReaderModeBrowserAgent::FromBrowser(self.browser);
   if (readerModeBrowserAgent) {
-    readerModeBrowserAgent->SetReaderModeHandler(nil);
-    readerModeBrowserAgent->SetReaderModeChipHandler(nil);
-    readerModeBrowserAgent->SetSnackbarHandler(nil);
+    readerModeBrowserAgent->SetDelegate(nil);
   }
 }
 
diff --git a/ios/chrome/browser/browser_view/ui_bundled/key_commands_provider_unittest.mm b/ios/chrome/browser/browser_view/ui_bundled/key_commands_provider_unittest.mm
index e41ce1f..27c6ac7 100644
--- a/ios/chrome/browser/browser_view/ui_bundled/key_commands_provider_unittest.mm
+++ b/ios/chrome/browser/browser_view/ui_bundled/key_commands_provider_unittest.mm
@@ -1069,7 +1069,7 @@
   EXPECT_TRUE(CanPerform(@"keyCommand_addToReadingList"));
   EXPECT_TRUE(CanPerform(@"keyCommand_addToBookmarks"));
 
-  tab_helper->SetActive(true);
+  tab_helper->ActivateReader(ReaderModeAccessPoint::kAIHub);
   EXPECT_FALSE(CanPerform(@"keyCommand_addToReadingList"));
   EXPECT_FALSE(CanPerform(@"keyCommand_addToBookmarks"));
 }
diff --git a/ios/chrome/browser/crash_report/model/crash_helper.mm b/ios/chrome/browser/crash_report/model/crash_helper.mm
index 62f16525..d709336b 100644
--- a/ios/chrome/browser/crash_report/model/crash_helper.mm
+++ b/ios/chrome/browser/crash_report/model/crash_helper.mm
@@ -76,7 +76,7 @@
 // currently calls crash_helper::HasReportToUpload() before Crashpad calls
 // ProcessIntermediateDumps. Experiment with instead calling this later during
 // startup, but after Crashpad can process intermediate dumps.
-MobileSessionShutdownType GetLastShutdownType() {
+MobileSessionShutdownType GetLastShutdownType(bool has_reports_to_upload) {
   if ([[PreviousSessionInfo sharedInstance] isFirstSessionAfterUpgrade]) {
     return FIRST_LAUNCH_AFTER_UPGRADE;
   }
@@ -87,7 +87,7 @@
     return SHUTDOWN_IN_BACKGROUND;
   }
 
-  if (crash_helper::HasReportToUpload()) {
+  if (has_reports_to_upload) {
     // The cause of the crash is known.
     if ([[PreviousSessionInfo sharedInstance]
             didSeeMemoryWarningShortlyBeforeTerminating]) {
@@ -146,6 +146,8 @@
   // Remove this after a few milestones.
   ClearMainThreadFreezeDetectorCache();
 
+  bool has_reports_to_upload = HasReportToUpload();
+
   // Wait until after processing intermediate dumps to record last shutdown
   // type.
   dispatch_async(dispatch_get_main_queue(), ^{
@@ -153,9 +155,10 @@
     // appear in the initial stability log. Because of this, the stability flag
     // on this histogram doesn't matter. It will be reported like any other
     // metric.
-    UMA_STABILITY_HISTOGRAM_ENUMERATION("Stability.MobileSessionShutdownType2",
-                                        GetLastShutdownType(),
-                                        MOBILE_SESSION_SHUTDOWN_TYPE_COUNT);
+    UMA_STABILITY_HISTOGRAM_ENUMERATION(
+        "Stability.MobileSessionShutdownType2",
+        GetLastShutdownType(has_reports_to_upload),
+        MOBILE_SESSION_SHUTDOWN_TYPE_COUNT);
   });
 }
 
diff --git a/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_view_controller.mm b/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_view_controller.mm
index 692512fa..41fe263 100644
--- a/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_view_controller.mm
+++ b/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_view_controller.mm
@@ -368,9 +368,20 @@
   RecordAIHubAction(IOSAIHubAction::kReaderMode);
   PageActionMenuViewController* __weak weakSelf = self;
   [self.pageActionMenuHandler dismissPageActionMenuWithCompletion:^{
-    weakSelf.readerModeActive ? [weakSelf.readerModeHandler hideReaderMode]
-                              : [weakSelf.readerModeHandler showReaderMode];
+    [weakSelf toggleReaderModeVisibility];
   }];
 }
 
+#pragma mark - Private
+
+// Toggles the visibility of the Reading mode UI on the current page.
+- (void)toggleReaderModeVisibility {
+  if (self.readerModeActive) {
+    [self.readerModeHandler hideReaderMode];
+  } else {
+    [self.readerModeHandler
+        showReaderModeFromAccessPoint:ReaderModeAccessPoint::kAIHub];
+  }
+}
+
 @end
diff --git a/ios/chrome/browser/main/model/browser_agent_util.mm b/ios/chrome/browser/main/model/browser_agent_util.mm
index cfc70b5..79a73bc 100644
--- a/ios/chrome/browser/main/model/browser_agent_util.mm
+++ b/ios/chrome/browser/main/model/browser_agent_util.mm
@@ -106,11 +106,14 @@
   AppLauncherBrowserAgent::CreateForBrowser(browser);
   OmniboxPositionBrowserAgent::CreateForBrowser(browser);
 
-  // Only create the FullscreenBrowserAgent for regular and incognito
-  // Browser (since the other Browser do not present the WebStates,
-  // and may not create the tab helpers which would lead to crashes).
+  // Only create the FullscreenBrowserAgent and ReaderModeBrowserAgent for
+  // regular and incognito Browser (since the other Browser do not present the
+  // WebStates, and may not create the tab helpers which would lead to crashes).
   if (!browser_is_inactive && !browser_is_temporary) {
     FullscreenController::CreateForBrowser(browser);
+    if (IsReaderModeAvailable()) {
+      ReaderModeBrowserAgent::CreateForBrowser(browser);
+    }
   }
 
   // LensBrowserAgent must be created before WebNavigationBrowserAgent.
@@ -150,11 +153,6 @@
   WebStateListMetricsBrowserAgent::CreateForBrowser(
       browser, SessionMetrics::FromProfile(browser->GetProfile()));
 
-  if (IsReaderModeAvailable()) {
-    ReaderModeBrowserAgent::CreateForBrowser(browser,
-                                             browser->GetWebStateList());
-  }
-
   // Normal profiles are the only ones to get tab usage recorder.
   if (!browser_is_off_record) {
     TabUsageRecorderBrowserAgent::CreateForBrowser(browser);
diff --git a/ios/chrome/browser/omnibox/eg_tests/BUILD.gn b/ios/chrome/browser/omnibox/eg_tests/BUILD.gn
index 23c9c0a6..cd241e0 100644
--- a/ios/chrome/browser/omnibox/eg_tests/BUILD.gn
+++ b/ios/chrome/browser/omnibox/eg_tests/BUILD.gn
@@ -86,6 +86,7 @@
     "//components/omnibox/common",
     "//components/strings:components_strings_grit",
     "//ios/chrome/app/strings",
+    "//ios/chrome/browser/browser_container/ui_bundled:eg_test_support+eg2",
     "//ios/chrome/browser/content_suggestions/ui_bundled:content_suggestions_constant",
     "//ios/chrome/browser/omnibox/public:constants",
     "//ios/chrome/browser/omnibox/public:features",
diff --git a/ios/chrome/browser/omnibox/eg_tests/omnibox_egtest.mm b/ios/chrome/browser/omnibox/eg_tests/omnibox_egtest.mm
index 68a4a984..75aa9039 100644
--- a/ios/chrome/browser/omnibox/eg_tests/omnibox_egtest.mm
+++ b/ios/chrome/browser/omnibox/eg_tests/omnibox_egtest.mm
@@ -13,6 +13,7 @@
 #import "build/build_config.h"
 #import "components/feature_engagement/public/feature_constants.h"
 #import "components/strings/grit/components_strings.h"
+#import "ios/chrome/browser/browser_container/ui_bundled/edit_menu_app_interface.h"
 #import "ios/chrome/browser/content_suggestions/ui_bundled/ntp_home_constant.h"
 #import "ios/chrome/browser/omnibox/eg_tests/omnibox_app_interface.h"
 #import "ios/chrome/browser/omnibox/eg_tests/omnibox_earl_grey.h"
@@ -358,16 +359,28 @@
   [[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()]
       performAction:grey_longPress()];
 
+  NSError* error = nil;
+  [[EarlGrey
+      selectElementWithMatcher:[EditMenuAppInterface editMenuNextButtonMatcher]]
+      assertWithMatcher:grey_sufficientlyVisible()
+                  error:&error];
+  if (error == nil) {
+    // Tap the forward button if it's visible. It depends on the device size.
+    [[EarlGrey selectElementWithMatcher:[EditMenuAppInterface
+                                            editMenuNextButtonMatcher]]
+        performAction:grey_tap()];
+  }
+
   // Wait for UIMenuController to appear or timeout after 2 seconds.
   GREYCondition* SearchTextButtonIsDisplayed = [GREYCondition
       conditionWithName:@"Search Copied Text button display condition"
                   block:^BOOL {
-                    NSError* error = nil;
+                    NSError* e = nil;
                     [[EarlGrey
                         selectElementWithMatcher:SearchCopiedTextButton()]
                         assertWithMatcher:grey_notNil()
-                                    error:&error];
-                    return error == nil;
+                                    error:&e];
+                    return e == nil;
                   }];
   GREYAssertTrue([SearchTextButtonIsDisplayed
                      waitWithTimeout:kWaitForUIElementTimeout.InSecondsF()],
diff --git a/ios/chrome/browser/policy/model/status_provider/user_cloud_policy_status_provider_unittest.mm b/ios/chrome/browser/policy/model/status_provider/user_cloud_policy_status_provider_unittest.mm
index e161a4a..5fe6f66 100644
--- a/ios/chrome/browser/policy/model/status_provider/user_cloud_policy_status_provider_unittest.mm
+++ b/ios/chrome/browser/policy/model/status_provider/user_cloud_policy_status_provider_unittest.mm
@@ -67,7 +67,7 @@
 
     user_store_ = std::make_unique<policy::MockUserCloudPolicyStore>();
     user_core_ = std::make_unique<policy::CloudPolicyCore>(
-        policy::dm_protocol::kChromeUserPolicyType, std::string(),
+        policy::dm_protocol::GetChromeUserPolicyType(), std::string(),
         user_store_.get(), base::SingleThreadTaskRunner::GetCurrentDefault(),
         network::TestNetworkConnectionTracker::CreateGetter());
 
diff --git a/ios/chrome/browser/policy/model/user_policy_egtest.mm b/ios/chrome/browser/policy/model/user_policy_egtest.mm
index 5fff9d7..157588a65 100644
--- a/ios/chrome/browser/policy/model/user_policy_egtest.mm
+++ b/ios/chrome/browser/policy/model/user_policy_egtest.mm
@@ -95,8 +95,9 @@
       ->mutable_policy_options()
       ->set_mode(enterprise_management::PolicyOptions::MANDATORY);
   settings.mutable_incognitomodeavailability()->set_value(1);
-  policy_storage->SetPolicyPayload(policy::dm_protocol::kChromeUserPolicyType,
-                                   settings.SerializeAsString());
+  policy_storage->SetPolicyPayload(
+      policy::dm_protocol::GetChromeUserPolicyType(),
+      settings.SerializeAsString());
 
   policy_storage->add_managed_user("*");
   policy_storage->set_policy_user(GetTestEmail());
diff --git a/ios/chrome/browser/popup_menu/ui_bundled/overflow_menu/overflow_menu_mediator.mm b/ios/chrome/browser/popup_menu/ui_bundled/overflow_menu/overflow_menu_mediator.mm
index a6a5e1f..2ffe76b 100644
--- a/ios/chrome/browser/popup_menu/ui_bundled/overflow_menu/overflow_menu_mediator.mm
+++ b/ios/chrome/browser/popup_menu/ui_bundled/overflow_menu/overflow_menu_mediator.mm
@@ -2504,7 +2504,12 @@
 
 // Sets the Reader mode UI visibility.
 - (void)setReaderModeVisibility:(BOOL)visible {
-  ReaderModeTabHelper::FromWebState(self.webState)->SetActive(visible);
+  if (visible) {
+    [self.readerModeHandler
+        showReaderModeFromAccessPoint:ReaderModeAccessPoint::kToolsMenu];
+  } else {
+    [self.readerModeHandler hideReaderMode];
+  }
   [self dismissMenu];
 }
 
diff --git a/ios/chrome/browser/popup_menu/ui_bundled/overflow_menu/overflow_menu_mediator_unittest.mm b/ios/chrome/browser/popup_menu/ui_bundled/overflow_menu/overflow_menu_mediator_unittest.mm
index ee35bb3..458d6939 100644
--- a/ios/chrome/browser/popup_menu/ui_bundled/overflow_menu/overflow_menu_mediator_unittest.mm
+++ b/ios/chrome/browser/popup_menu/ui_bundled/overflow_menu/overflow_menu_mediator_unittest.mm
@@ -325,7 +325,11 @@
           web_state_, DistillerServiceFactory::GetForProfile(profile_.get()));
       tab_helper = ReaderModeTabHelper::FromWebState(web_state_);
     }
-    tab_helper->SetActive(active);
+    if (active) {
+      tab_helper->ActivateReader(ReaderModeAccessPoint::kToolsMenu);
+    } else {
+      tab_helper->DeactivateReader();
+    }
   }
 
   void InsertNewWebState(int index) {
diff --git a/ios/chrome/browser/popup_menu/ui_bundled/popup_menu_coordinator.mm b/ios/chrome/browser/popup_menu/ui_bundled/popup_menu_coordinator.mm
index 29a50f5..88e44d27 100644
--- a/ios/chrome/browser/popup_menu/ui_bundled/popup_menu_coordinator.mm
+++ b/ios/chrome/browser/popup_menu/ui_bundled/popup_menu_coordinator.mm
@@ -307,7 +307,7 @@
         HandlerForProtocol(dispatcher, BrowserCoordinatorCommands);
     mediator.findInPageHandler =
         HandlerForProtocol(dispatcher, FindInPageCommands);
-    if (IsReaderModeSnackbarEnabled()) {
+    if (IsReaderModeAvailable()) {
       mediator.readerModeHandler =
           HandlerForProtocol(dispatcher, ReaderModeCommands);
     }
diff --git a/ios/chrome/browser/reader_mode/coordinator/reader_mode_options_coordinator.mm b/ios/chrome/browser/reader_mode/coordinator/reader_mode_options_coordinator.mm
index eebffdc..ffcba5c 100644
--- a/ios/chrome/browser/reader_mode/coordinator/reader_mode_options_coordinator.mm
+++ b/ios/chrome/browser/reader_mode/coordinator/reader_mode_options_coordinator.mm
@@ -11,6 +11,7 @@
 #import "ios/chrome/browser/reader_mode/ui/reader_mode_options_view_controller.h"
 #import "ios/chrome/browser/shared/model/browser/browser.h"
 #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
+#import "ios/chrome/browser/shared/public/commands/reader_mode_commands.h"
 #import "ios/chrome/browser/shared/public/commands/reader_mode_options_commands.h"
 
 namespace {
@@ -43,6 +44,8 @@
   _mediator = [[ReaderModeOptionsMediator alloc]
       initWithDistilledPagePrefs:distillerService->GetDistilledPagePrefs()
                     webStateList:self.browser->GetWebStateList()];
+  _mediator.readerModeHandler = HandlerForProtocol(
+      self.browser->GetCommandDispatcher(), ReaderModeCommands);
   _viewController.mutator = _mediator;
   _viewController.controlsView.mutator = _mediator;
   _mediator.consumer = _viewController.controlsView;
diff --git a/ios/chrome/browser/reader_mode/coordinator/reader_mode_options_mediator.h b/ios/chrome/browser/reader_mode/coordinator/reader_mode_options_mediator.h
index 0e155b9..53179be5 100644
--- a/ios/chrome/browser/reader_mode/coordinator/reader_mode_options_mediator.h
+++ b/ios/chrome/browser/reader_mode/coordinator/reader_mode_options_mediator.h
@@ -8,6 +8,7 @@
 #import <Foundation/Foundation.h>
 
 #import "ios/chrome/browser/reader_mode/ui/reader_mode_options_mutator.h"
+#import "ios/chrome/browser/shared/public/commands/reader_mode_commands.h"
 
 class WebStateList;
 
@@ -22,6 +23,8 @@
 
 @property(nonatomic, weak) id<ReaderModeOptionsConsumer> consumer;
 
+@property(nonatomic, weak) id<ReaderModeCommands> readerModeHandler;
+
 // Initializer.
 - (instancetype)initWithDistilledPagePrefs:
                     (dom_distiller::DistilledPagePrefs*)distilledPagePrefs
diff --git a/ios/chrome/browser/reader_mode/coordinator/reader_mode_options_mediator.mm b/ios/chrome/browser/reader_mode/coordinator/reader_mode_options_mediator.mm
index f145f935..109f8c40 100644
--- a/ios/chrome/browser/reader_mode/coordinator/reader_mode_options_mediator.mm
+++ b/ios/chrome/browser/reader_mode/coordinator/reader_mode_options_mediator.mm
@@ -74,10 +74,7 @@
 }
 
 - (void)hideReaderMode {
-  web::WebState* webState = _webStateList->GetActiveWebState();
-  if (webState) {
-    ReaderModeTabHelper::FromWebState(webState)->SetActive(false);
-  }
+  [self.readerModeHandler hideReaderMode];
 }
 
 #pragma mark - Public
diff --git a/ios/chrome/browser/reader_mode/model/BUILD.gn b/ios/chrome/browser/reader_mode/model/BUILD.gn
index d6992a4..b57f1f9 100644
--- a/ios/chrome/browser/reader_mode/model/BUILD.gn
+++ b/ios/chrome/browser/reader_mode/model/BUILD.gn
@@ -8,6 +8,7 @@
   sources = [
     "reader_mode_browser_agent.h",
     "reader_mode_browser_agent.mm",
+    "reader_mode_browser_agent_delegate.h",
     "reader_mode_content_delegate.h",
     "reader_mode_content_tab_helper.h",
     "reader_mode_content_tab_helper.mm",
diff --git a/ios/chrome/browser/reader_mode/model/constants.h b/ios/chrome/browser/reader_mode/model/constants.h
index 57b0502..d31449b 100644
--- a/ios/chrome/browser/reader_mode/model/constants.h
+++ b/ios/chrome/browser/reader_mode/model/constants.h
@@ -92,6 +92,17 @@
 };
 // LINT.ThenChange(/tools/metrics/histograms/metadata/ios/enums.xml:ReaderModeFontFamily)
 
+// Recorded for IOS.ReaderMode.AccessPoint. Entries should not be renumbered and
+// numeric values should never be reused.
+// LINT.IfChange(ReaderModeAccessPoint)
+enum class ReaderModeAccessPoint {
+  kContextualChip = 0,
+  kToolsMenu = 1,
+  kAIHub = 2,
+  kMaxValue = kAIHub,
+};
+// LINT.ThenChange(/tools/metrics/histograms/metadata/ios/enums.xml:ReaderModeAccessPoint)
+
 // Default delay in seconds for triggering Reader Mode distiller heuristic.
 // This allows the page to react to the DOM loading and ensures minimal
 // interference with the JavaScript execution.
@@ -129,6 +140,9 @@
 // Histogram name for time spent in Reader Mode.
 extern const char kReaderModeTimeSpentHistogram[];
 
+// Histogram name for Reader Mode access point for starting distillation.
+extern const char kReaderModeAccessPointHistogram[];
+
 // Returns the Reader mode symbol name.
 NSString* GetReaderModeSymbolName();
 
diff --git a/ios/chrome/browser/reader_mode/model/constants.mm b/ios/chrome/browser/reader_mode/model/constants.mm
index 691050d..1977fb9b 100644
--- a/ios/chrome/browser/reader_mode/model/constants.mm
+++ b/ios/chrome/browser/reader_mode/model/constants.mm
@@ -29,6 +29,8 @@
 
 const char kReaderModeTimeSpentHistogram[] = "IOS.ReaderMode.TimeSpent";
 
+const char kReaderModeAccessPointHistogram[] = "IOS.ReaderMode.AccessPoint";
+
 NSString* GetReaderModeSymbolName() {
   if (@available(iOS 18, *)) {
     return kReaderModeSymbolPostIOS18;
diff --git a/ios/chrome/browser/reader_mode/model/reader_mode_browser_agent.h b/ios/chrome/browser/reader_mode/model/reader_mode_browser_agent.h
index bc0f406..52fa1899 100644
--- a/ios/chrome/browser/reader_mode/model/reader_mode_browser_agent.h
+++ b/ios/chrome/browser/reader_mode/model/reader_mode_browser_agent.h
@@ -6,6 +6,7 @@
 #define IOS_CHROME_BROWSER_READER_MODE_MODEL_READER_MODE_BROWSER_AGENT_H_
 
 #import "base/scoped_observation.h"
+#import "ios/chrome/browser/reader_mode/model/reader_mode_browser_agent_delegate.h"
 #import "ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.h"
 #import "ios/chrome/browser/shared/model/browser/browser_user_data.h"
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_list_observer.h"
@@ -29,18 +30,13 @@
 
   ~ReaderModeBrowserAgent() override;
 
-  // Sets the Reader mode UI handlers.
-  void SetReaderModeHandler(id<ReaderModeCommands> reader_mode_handler);
-  void SetReaderModeChipHandler(
-      id<ReaderModeChipCommands> reader_mode_chip_handler);
-  // Sets the snackbar handler.
-  void SetSnackbarHandler(id<SnackbarCommands> snackbar_handler);
+  // Sets the `delegate_`.
+  void SetDelegate(id<ReaderModeBrowserAgentDelegate> delegate);
 
  private:
   friend class BrowserUserData<ReaderModeBrowserAgent>;
 
-  explicit ReaderModeBrowserAgent(Browser* browser,
-                                  WebStateList* web_state_list);
+  explicit ReaderModeBrowserAgent(Browser* browser);
 
   // Show/hide the Reader mode UI.
   void ShowReaderModeUI(bool animated);
@@ -67,9 +63,8 @@
   base::ScopedObservation<WebStateList, WebStateListObserver>
       web_state_list_scoped_observation_{this};
 
-  __weak id<ReaderModeCommands> reader_mode_handler_ = nil;
-  __weak id<ReaderModeChipCommands> reader_mode_chip_handler_ = nil;
-  __weak id<SnackbarCommands> snackbar_handler_ = nil;
+  // The delegate for this agent.
+  id<ReaderModeBrowserAgentDelegate> delegate_;
 };
 
 #endif  // IOS_CHROME_BROWSER_READER_MODE_MODEL_READER_MODE_BROWSER_AGENT_H_
diff --git a/ios/chrome/browser/reader_mode/model/reader_mode_browser_agent.mm b/ios/chrome/browser/reader_mode/model/reader_mode_browser_agent.mm
index a7bcba9..08066b8 100644
--- a/ios/chrome/browser/reader_mode/model/reader_mode_browser_agent.mm
+++ b/ios/chrome/browser/reader_mode/model/reader_mode_browser_agent.mm
@@ -31,34 +31,24 @@
 
 ReaderModeBrowserAgent::~ReaderModeBrowserAgent() = default;
 
-void ReaderModeBrowserAgent::SetReaderModeHandler(
-    id<ReaderModeCommands> reader_mode_handler) {
-  reader_mode_handler_ = reader_mode_handler;
-}
-
-void ReaderModeBrowserAgent::SetReaderModeChipHandler(
-    id<ReaderModeChipCommands> reader_mode_chip_handler) {
-  reader_mode_chip_handler_ = reader_mode_chip_handler;
-}
-
-void ReaderModeBrowserAgent::SetSnackbarHandler(
-    id<SnackbarCommands> snackbar_handler) {
-  snackbar_handler_ = snackbar_handler;
+void ReaderModeBrowserAgent::SetDelegate(
+    id<ReaderModeBrowserAgentDelegate> delegate) {
+  delegate_ = delegate;
 }
 
 #pragma mark - Private
 
-ReaderModeBrowserAgent::ReaderModeBrowserAgent(Browser* browser,
-                                               WebStateList* web_state_list)
+ReaderModeBrowserAgent::ReaderModeBrowserAgent(Browser* browser)
     : BrowserUserData(browser) {
-  web_state_list_scoped_observation_.Observe(web_state_list);
+  web_state_list_scoped_observation_.Observe(browser->GetWebStateList());
 }
 
 void ReaderModeBrowserAgent::ShowReaderModeUI(bool animated) {
-  [reader_mode_handler_ showReaderMode];
+  [delegate_ showReaderModeContentFromBrowserAgent:this];
 
-  __weak __typeof(reader_mode_chip_handler_) weak_reader_mode_chip_handler =
-      reader_mode_chip_handler_;
+  __weak id<ReaderModeChipCommands> weak_reader_mode_chip_handler =
+      HandlerForProtocol(browser_->GetCommandDispatcher(),
+                         ReaderModeChipCommands);
   auto show_reader_mode_chip = base::BindOnce(^{
     [weak_reader_mode_chip_handler showReaderModeChip];
   });
@@ -74,8 +64,11 @@
 }
 
 void ReaderModeBrowserAgent::HideReaderModeUI() {
-  [reader_mode_chip_handler_ hideReaderModeChip];
-  [reader_mode_handler_ hideReaderMode];
+  id<ReaderModeChipCommands> reader_mode_chip_handler = HandlerForProtocol(
+      browser_->GetCommandDispatcher(), ReaderModeChipCommands);
+  [reader_mode_chip_handler hideReaderModeChip];
+  [delegate_ hideReaderModeContentFromBrowserAgent:this];
+
   UpdateHandlersOnActiveWebState();
 }
 
@@ -156,7 +149,9 @@
 void ReaderModeBrowserAgent::ReaderModeDistillationFailed(
     ReaderModeTabHelper* tab_helper) {
   // Show distillation failure snackbar.
-  [snackbar_handler_
+  id<SnackbarCommands> snackbar_handler =
+      static_cast<id<SnackbarCommands>>(browser_->GetCommandDispatcher());
+  [snackbar_handler
       showSnackbarWithMessage:l10n_util::GetNSString(
                                   IDS_IOS_READER_MODE_SNACKBAR_FAILURE_MESSAGE)
                    buttonText:l10n_util::GetNSString(IDS_DONE)
diff --git a/ios/chrome/browser/reader_mode/model/reader_mode_browser_agent_delegate.h b/ios/chrome/browser/reader_mode/model/reader_mode_browser_agent_delegate.h
new file mode 100644
index 0000000..6e9e100f
--- /dev/null
+++ b/ios/chrome/browser/reader_mode/model/reader_mode_browser_agent_delegate.h
@@ -0,0 +1,23 @@
+// Copyright 2025 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_READER_MODE_MODEL_READER_MODE_BROWSER_AGENT_DELEGATE_H_
+#define IOS_CHROME_BROWSER_READER_MODE_MODEL_READER_MODE_BROWSER_AGENT_DELEGATE_H_
+
+class ReaderModeBrowserAgent;
+
+// Delegate for ReaderModeBrowserAgent.
+@protocol ReaderModeBrowserAgentDelegate
+
+// Shows the reader mode content.
+- (void)showReaderModeContentFromBrowserAgent:
+    (ReaderModeBrowserAgent*)browserAgent;
+
+// Hides the reader mode content.
+- (void)hideReaderModeContentFromBrowserAgent:
+    (ReaderModeBrowserAgent*)browserAgent;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_READER_MODE_MODEL_READER_MODE_BROWSER_AGENT_DELEGATE_H_
diff --git a/ios/chrome/browser/reader_mode/model/reader_mode_browser_agent_unittest.mm b/ios/chrome/browser/reader_mode/model/reader_mode_browser_agent_unittest.mm
index 87adc14..8e2483867 100644
--- a/ios/chrome/browser/reader_mode/model/reader_mode_browser_agent_unittest.mm
+++ b/ios/chrome/browser/reader_mode/model/reader_mode_browser_agent_unittest.mm
@@ -4,6 +4,7 @@
 
 #import "ios/chrome/browser/reader_mode/model/reader_mode_browser_agent.h"
 
+#import "ios/chrome/browser/reader_mode/model/reader_mode_browser_agent_delegate.h"
 #import "ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.h"
 #import "ios/chrome/browser/reader_mode/model/reader_mode_test.h"
 #import "ios/chrome/browser/shared/model/browser/test/test_browser.h"
@@ -11,9 +12,10 @@
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
 #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
 #import "ios/chrome/browser/shared/public/commands/page_side_swipe_commands.h"
-#import "ios/chrome/browser/shared/public/commands/reader_mode_commands.h"
+#import "ios/chrome/browser/shared/public/commands/reader_mode_chip_commands.h"
 #import "ios/web/public/test/fakes/fake_web_state.h"
 #import "ios/web/public/test/web_task_environment.h"
+#import "testing/gmock/include/gmock/gmock.h"
 #import "testing/platform_test.h"
 #import "third_party/ocmock/OCMock/OCMock.h"
 #import "third_party/ocmock/gtest_support.h"
@@ -29,18 +31,23 @@
     ReaderModeTest::SetUp();
 
     test_browser_ = std::make_unique<TestBrowser>(profile());
-    ReaderModeBrowserAgent::CreateForBrowser(test_browser_.get(),
-                                             test_browser_->GetWebStateList());
-    fake_reader_mode_handler_ =
-        OCMStrictProtocolMock(@protocol(ReaderModeCommands));
-    GetReaderModeBrowserAgent()->SetReaderModeHandler(
-        fake_reader_mode_handler_);
+    ReaderModeBrowserAgent::CreateForBrowser(test_browser_.get());
+
+    delegate_ =
+        OCMStrictProtocolMock(@protocol(ReaderModeBrowserAgentDelegate));
+    GetReaderModeBrowserAgent()->SetDelegate(delegate_);
 
     side_swipe_handler_ = OCMProtocolMock(@protocol(PageSideSwipeCommands));
     [test_browser_->GetCommandDispatcher()
         startDispatchingToTarget:side_swipe_handler_
                      forProtocol:@protocol(PageSideSwipeCommands)];
 
+    fake_reader_mode_chip_handler_ =
+        OCMProtocolMock(@protocol(ReaderModeChipCommands));
+    [test_browser_->GetCommandDispatcher()
+        startDispatchingToTarget:fake_reader_mode_chip_handler_
+                     forProtocol:@protocol(ReaderModeChipCommands)];
+
     // Initialize the WebStateList.
     InsertWebState();
     InsertWebState();
@@ -48,16 +55,16 @@
     InsertWebState();
     GetWebStateList()->ActivateWebStateAt(0);
 
-    EnableReaderMode(GetWebStateList()->GetWebStateAt(1));
+    EnableReaderMode(GetWebStateList()->GetWebStateAt(1),
+                     ReaderModeAccessPoint::kContextualChip);
     WaitForReaderModeContentReady();
 
-    EnableReaderMode(GetWebStateList()->GetWebStateAt(3));
+    EnableReaderMode(GetWebStateList()->GetWebStateAt(3),
+                     ReaderModeAccessPoint::kContextualChip);
     WaitForReaderModeContentReady();
   }
 
-  void TearDown() override {
-    GetReaderModeBrowserAgent()->SetReaderModeHandler(nil);
-  }
+  void TearDown() override { GetReaderModeBrowserAgent()->SetDelegate(nil); }
 
   // Inserts a FakeWebState with a ReaderModeTabHelper in the WebStateList.
   void InsertWebState() {
@@ -86,51 +93,70 @@
 
  protected:
   std::unique_ptr<TestBrowser> test_browser_;
-  id fake_reader_mode_handler_;
+  id fake_reader_mode_chip_handler_;
   id side_swipe_handler_;
+  id delegate_;
 };
 
 // Tests that the Reader mode UI is shown/dismissed when changing the current
 // active WebState in the WebStateList.
 TEST_F(ReaderModeBrowserAgentTest, ChangingActiveWebState) {
-  OCMExpect([fake_reader_mode_handler_ showReaderMode]);
+  OCMExpect([delegate_
+      showReaderModeContentFromBrowserAgent:GetReaderModeBrowserAgent()]);
+  OCMExpect([fake_reader_mode_chip_handler_ showReaderModeChip]);
   GetWebStateList()->ActivateWebStateAt(1);
-  EXPECT_OCMOCK_VERIFY(fake_reader_mode_handler_);
+  EXPECT_OCMOCK_VERIFY(delegate_);
+  EXPECT_OCMOCK_VERIFY(fake_reader_mode_chip_handler_);
 
-  OCMExpect([fake_reader_mode_handler_ hideReaderMode]);
+  OCMExpect([delegate_
+      hideReaderModeContentFromBrowserAgent:GetReaderModeBrowserAgent()]);
+  OCMExpect([fake_reader_mode_chip_handler_ hideReaderModeChip]);
   GetWebStateList()->ActivateWebStateAt(0);
-  EXPECT_OCMOCK_VERIFY(fake_reader_mode_handler_);
+  EXPECT_OCMOCK_VERIFY(delegate_);
+  EXPECT_OCMOCK_VERIFY(fake_reader_mode_chip_handler_);
 
-  OCMExpect([fake_reader_mode_handler_ showReaderMode]);
+  OCMExpect([delegate_
+      showReaderModeContentFromBrowserAgent:GetReaderModeBrowserAgent()]);
+  OCMExpect([fake_reader_mode_chip_handler_ showReaderModeChip]);
   GetWebStateList()->ActivateWebStateAt(3);
-  EXPECT_OCMOCK_VERIFY(fake_reader_mode_handler_);
+  EXPECT_OCMOCK_VERIFY(delegate_);
+  EXPECT_OCMOCK_VERIFY(fake_reader_mode_chip_handler_);
 
-  OCMExpect([fake_reader_mode_handler_ hideReaderMode]);
+  OCMExpect([delegate_
+      hideReaderModeContentFromBrowserAgent:GetReaderModeBrowserAgent()]);
+  OCMExpect([fake_reader_mode_chip_handler_ hideReaderModeChip]);
   GetWebStateList()->ActivateWebStateAt(WebStateList::kInvalidIndex);
-  EXPECT_OCMOCK_VERIFY(fake_reader_mode_handler_);
+  EXPECT_OCMOCK_VERIFY(delegate_);
+  EXPECT_OCMOCK_VERIFY(fake_reader_mode_chip_handler_);
 }
 
 // Tests that the Reader mode UI is not dismissed when moving the active
 // WebState while the Reader mode UI is presented.
 TEST_F(ReaderModeBrowserAgentTest, MovingActiveWebState) {
-  OCMExpect([fake_reader_mode_handler_ showReaderMode]);
+  OCMExpect([delegate_
+      showReaderModeContentFromBrowserAgent:GetReaderModeBrowserAgent()]);
+  OCMExpect([fake_reader_mode_chip_handler_ showReaderModeChip]);
   GetWebStateList()->ActivateWebStateAt(1);
-  EXPECT_OCMOCK_VERIFY(fake_reader_mode_handler_);
+  EXPECT_OCMOCK_VERIFY(delegate_);
+  EXPECT_OCMOCK_VERIFY(fake_reader_mode_chip_handler_);
 
   // No call to `hideReaderMode` is expected.
   GetWebStateList()->MoveWebStateAt(1, 0);
-  EXPECT_OCMOCK_VERIFY(fake_reader_mode_handler_);
+  EXPECT_OCMOCK_VERIFY(delegate_);
+  EXPECT_OCMOCK_VERIFY(fake_reader_mode_chip_handler_);
 }
 
 // Tests that the Reader mode UI is shown/dismissed when Reader mode is
 // activated/deactivated in the currently active WebState.
 TEST_F(ReaderModeBrowserAgentTest, ChangingReaderModeStatus) {
-  OCMExpect([fake_reader_mode_handler_ showReaderMode]);
-  EnableReaderMode(GetActiveWebState());
+  OCMExpect([delegate_
+      showReaderModeContentFromBrowserAgent:GetReaderModeBrowserAgent()]);
+  EnableReaderMode(GetActiveWebState(), ReaderModeAccessPoint::kContextualChip);
   WaitForReaderModeContentReady();
-  EXPECT_OCMOCK_VERIFY(fake_reader_mode_handler_);
+  EXPECT_OCMOCK_VERIFY(delegate_);
 
-  OCMExpect([fake_reader_mode_handler_ hideReaderMode]);
+  OCMExpect([delegate_
+      hideReaderModeContentFromBrowserAgent:GetReaderModeBrowserAgent()]);
   DisableReaderMode(GetActiveWebState());
-  EXPECT_OCMOCK_VERIFY(fake_reader_mode_handler_);
+  EXPECT_OCMOCK_VERIFY(delegate_);
 }
diff --git a/ios/chrome/browser/reader_mode/model/reader_mode_metrics_helper.h b/ios/chrome/browser/reader_mode/model/reader_mode_metrics_helper.h
index 0b59b82..abf209b 100644
--- a/ios/chrome/browser/reader_mode/model/reader_mode_metrics_helper.h
+++ b/ios/chrome/browser/reader_mode/model/reader_mode_metrics_helper.h
@@ -39,7 +39,7 @@
   bool ReaderModeIsRecentlyUsed();
 
   // Records histograms for the Reading Mode distillation event.
-  void RecordReaderDistillerTriggered();
+  void RecordReaderDistillerTriggered(ReaderModeAccessPoint access_point);
   void RecordReaderDistillerCompleted(ReaderModeDistillerResult result);
 
   // Records the distillation timeout and resets state for the next event.
diff --git a/ios/chrome/browser/reader_mode/model/reader_mode_metrics_helper.mm b/ios/chrome/browser/reader_mode/model/reader_mode_metrics_helper.mm
index b3a4d9f..9f0edfb 100644
--- a/ios/chrome/browser/reader_mode/model/reader_mode_metrics_helper.mm
+++ b/ios/chrome/browser/reader_mode/model/reader_mode_metrics_helper.mm
@@ -115,9 +115,11 @@
   }
 }
 
-void ReaderModeMetricsHelper::RecordReaderDistillerTriggered() {
+void ReaderModeMetricsHelper::RecordReaderDistillerTriggered(
+    ReaderModeAccessPoint access_point) {
   distiller_timer_ = std::make_unique<base::ElapsedTimer>();
   last_reader_mode_state_ = ReaderModeState::kDistillationStarted;
+  base::UmaHistogramEnumeration(kReaderModeAccessPointHistogram, access_point);
 }
 
 void ReaderModeMetricsHelper::RecordReaderDistillerTimedOut() {
diff --git a/ios/chrome/browser/reader_mode/model/reader_mode_metrics_helper_unittest.mm b/ios/chrome/browser/reader_mode/model/reader_mode_metrics_helper_unittest.mm
index 0d5fb24..94e3e7a3 100644
--- a/ios/chrome/browser/reader_mode/model/reader_mode_metrics_helper_unittest.mm
+++ b/ios/chrome/browser/reader_mode/model/reader_mode_metrics_helper_unittest.mm
@@ -166,18 +166,21 @@
 // Tests that recording the distillation trigger updates the recorded Reading
 // mode state.
 TEST_F(ReaderModeMetricsHelperTest, ReaderDistillerTriggered) {
-  metrics_helper()->RecordReaderDistillerTriggered();
+  metrics_helper()->RecordReaderDistillerTriggered(
+      ReaderModeAccessPoint::kContextualChip);
   metrics_helper()->Flush();
 
   EXPECT_THAT(histogram_tester_.GetAllSamples(kReaderModeStateHistogram),
               BucketsAre(Bucket(ReaderModeState::kDistillationStarted, 1)));
   histogram_tester_.ExpectTotalCount(kReaderModeDistillerLatencyHistogram, 0);
+  histogram_tester_.ExpectTotalCount(kReaderModeAccessPointHistogram, 1);
 }
 
 // Tests that recording the distillation completion updates the recorded Reading
 // mode state.
 TEST_F(ReaderModeMetricsHelperTest, ReaderDistillerCompleted) {
-  metrics_helper()->RecordReaderDistillerTriggered();
+  metrics_helper()->RecordReaderDistillerTriggered(
+      ReaderModeAccessPoint::kContextualChip);
   task_environment_.AdvanceClock(base::Seconds(1));
 
   metrics_helper()->RecordReaderDistillerCompleted(
@@ -188,6 +191,7 @@
               BucketsAre(Bucket(ReaderModeState::kDistillationCompleted, 1)));
   histogram_tester_.ExpectUniqueTimeSample(kReaderModeDistillerLatencyHistogram,
                                            base::Seconds(1), 1);
+  histogram_tester_.ExpectTotalCount(kReaderModeAccessPointHistogram, 1);
 
   std::vector<int64_t> ukm_entries = test_ukm_recorder_.GetMetricsEntryValues(
       IOS_ReaderMode_Distiller_Result::kEntryName,
@@ -247,7 +251,8 @@
 
 // Tests that canceling distillation records latency and reader mode state.
 TEST_F(ReaderModeMetricsHelperTest, DistillationCanceledOnTimeout) {
-  metrics_helper()->RecordReaderDistillerTriggered();
+  metrics_helper()->RecordReaderDistillerTriggered(
+      ReaderModeAccessPoint::kAIHub);
   task_environment_.AdvanceClock(base::Seconds(1));
 
   // Cancelation triggers a metrics flush.
@@ -259,6 +264,18 @@
                                            base::Seconds(1), 1);
 }
 
+// Tests that Reader Mode access point is recorded when a value is set.
+TEST_F(ReaderModeMetricsHelperTest, ReaderModeAccessPointRecorded) {
+  metrics_helper()->RecordReaderDistillerTriggered(
+      ReaderModeAccessPoint::kAIHub);
+  metrics_helper()->Flush();
+
+  EXPECT_THAT(histogram_tester_.GetAllSamples(kReaderModeStateHistogram),
+              BucketsAre(Bucket(ReaderModeState::kDistillationStarted, 1)));
+  EXPECT_THAT(histogram_tester_.GetAllSamples(kReaderModeAccessPointHistogram),
+              BucketsAre(Bucket(ReaderModeAccessPoint::kAIHub, 1)));
+}
+
 // Tests metrics functionality based on the heuristic result.
 class ReaderModeMetricsHelperWithEligibilityTest
     : public ReaderModeMetricsHelperTest,
diff --git a/ios/chrome/browser/reader_mode/model/reader_mode_panel_item_configuration.h b/ios/chrome/browser/reader_mode/model/reader_mode_panel_item_configuration.h
index ba20637..fcba62f 100644
--- a/ios/chrome/browser/reader_mode/model/reader_mode_panel_item_configuration.h
+++ b/ios/chrome/browser/reader_mode/model/reader_mode_panel_item_configuration.h
@@ -33,9 +33,13 @@
   void ReaderModeDistillationFailed(ReaderModeTabHelper* tab_helper) override;
 
   // web::WebStateObserver
+  void WasHidden(web::WebState* web_state) override;
   void WebStateDestroyed(web::WebState* web_state) override;
 
  private:
+  // Invalidates this configuration.
+  void Invalidate();
+
   base::ScopedObservation<web::WebState, web::WebStateObserver>
       web_state_observation_{this};
   base::ScopedObservation<ReaderModeTabHelper, ReaderModeTabHelper::Observer>
diff --git a/ios/chrome/browser/reader_mode/model/reader_mode_panel_item_configuration.mm b/ios/chrome/browser/reader_mode/model/reader_mode_panel_item_configuration.mm
index 43a1dba8..c5c68ec 100644
--- a/ios/chrome/browser/reader_mode/model/reader_mode_panel_item_configuration.mm
+++ b/ios/chrome/browser/reader_mode/model/reader_mode_panel_item_configuration.mm
@@ -29,10 +29,22 @@
   ReaderModeTabHelper* reader_mode_tab_helper =
       ReaderModeTabHelper::FromWebState(web_state.get());
   if (reader_mode_tab_helper) {
-    reader_mode_tab_helper->SetActive(true);
+    reader_mode_tab_helper->ActivateReader(
+        ReaderModeAccessPoint::kContextualChip);
   }
 }
 
+// Helper which returns whether BWG is available in `web_state`.
+bool IsBwgAvailableForWebState(web::WebState* web_state) {
+  if (!web_state || web_state->IsBeingDestroyed()) {
+    return false;
+  }
+  ProfileIOS* profile =
+      ProfileIOS::FromBrowserState(web_state->GetBrowserState());
+  BwgService* bwg_service = BwgServiceFactory::GetForProfile(profile);
+  return bwg_service && bwg_service->IsBwgAvailableForWebState(web_state);
+}
+
 }  // namespace
 
 ReaderModePanelItemConfiguration::ReaderModePanelItemConfiguration(
@@ -63,21 +75,8 @@
 #pragma mark - ContextualPanelItemConfiguration
 
 void ReaderModePanelItemConfiguration::DidTransitionToSmallEntrypoint() {
-  web::WebState* web_state = web_state_observation_.GetSource();
-  if (!web_state || web_state->IsBeingDestroyed()) {
-    return;
-  }
-  ProfileIOS* profile =
-      ProfileIOS::FromBrowserState(web_state->GetBrowserState());
-  BwgService* bwg_service = BwgServiceFactory::GetForProfile(profile);
-  if (!bwg_service || !bwg_service->IsBwgAvailableForWebState(web_state)) {
-    return;
-  }
-  ContextualPanelTabHelper* contextual_panel_tab_helper =
-      ContextualPanelTabHelper::FromWebState(web_state);
-  if (contextual_panel_tab_helper) {
-    contextual_panel_tab_helper->InvalidateContextualPanelItemConfiguration(
-        this);
+  if (IsBwgAvailableForWebState(web_state_observation_.GetSource())) {
+    Invalidate();
   }
 }
 
@@ -89,13 +88,36 @@
 }
 
 void ReaderModePanelItemConfiguration::ReaderModeWebStateDidLoadContent(
-    ReaderModeTabHelper* tab_helper) {}
+    ReaderModeTabHelper* tab_helper) {
+  if (IsBwgAvailableForWebState(web_state_observation_.GetSource())) {
+    Invalidate();
+  }
+}
 
 void ReaderModePanelItemConfiguration::ReaderModeWebStateWillBecomeUnavailable(
     ReaderModeTabHelper* tab_helper) {}
 
 void ReaderModePanelItemConfiguration::ReaderModeDistillationFailed(
     ReaderModeTabHelper* tab_helper) {
+  Invalidate();
+}
+
+#pragma mark - web::WebStateObserver
+
+void ReaderModePanelItemConfiguration::WebStateDestroyed(
+    web::WebState* web_state) {
+  web_state_observation_.Reset();
+}
+
+void ReaderModePanelItemConfiguration::WasHidden(web::WebState* web_state) {
+  if (IsBwgAvailableForWebState(web_state_observation_.GetSource())) {
+    Invalidate();
+  }
+}
+
+#pragma mark - Private
+
+void ReaderModePanelItemConfiguration::Invalidate() {
   web::WebState* web_state = web_state_observation_.GetSource();
   if (!web_state || web_state->IsBeingDestroyed()) {
     return;
@@ -107,10 +129,3 @@
         this);
   }
 }
-
-#pragma mark - web::WebStateObserver
-
-void ReaderModePanelItemConfiguration::WebStateDestroyed(
-    web::WebState* web_state) {
-  web_state_observation_.Reset();
-}
diff --git a/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.h b/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.h
index 3491db0..4745654 100644
--- a/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.h
+++ b/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.h
@@ -62,7 +62,8 @@
   // mode UI should be presented. GetReaderModeWebState() may still return null.
   bool IsActive() const;
   // Activates/deactivates Reader mode in the current tab.
-  void SetActive(bool active);
+  void ActivateReader(ReaderModeAccessPoint access_point);
+  void DeactivateReader();
 
   // Returns the Reader mode content WebState if it is available. This can be
   // null if Reader mode is active, or non-null while Reader mode is inactive.
diff --git a/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.mm b/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.mm
index 71e106e..6cce7b3c 100644
--- a/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.mm
+++ b/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.mm
@@ -79,7 +79,7 @@
 }
 
 ReaderModeTabHelper::~ReaderModeTabHelper() {
-  SetActive(false);
+  DeactivateReader();
   for (auto& observer : observers_) {
     observer.ReaderModeTabHelperDestroyed(this);
   }
@@ -97,20 +97,26 @@
   return active_;
 }
 
-void ReaderModeTabHelper::SetActive(bool active) {
-  if (active_ == active) {
+void ReaderModeTabHelper::ActivateReader(ReaderModeAccessPoint access_point) {
+  if (active_) {
     return;
   }
-  active_ = active;
-  if (active) {
-    // If Reader mode is being activated, create the secondary WebState where
-    // the content will be rendered and start distillation.
-    CreateReaderModeWebState();
-  } else {
-    // If Reader mode is being deactivated, destroy the secondary WebState and
-    // ensure the Reader mode UI is dismissed.
-    DestroyReaderModeWebState();
+  active_ = true;
+  metrics_helper_.RecordReaderDistillerTriggered(access_point);
+
+  // If Reader mode is being activated, create the secondary WebState where
+  // the content will be rendered and start distillation.
+  CreateReaderModeWebState();
+}
+
+void ReaderModeTabHelper::DeactivateReader() {
+  if (!active_) {
+    return;
   }
+  active_ = false;
+  // If Reader mode is being deactivated, destroy the secondary WebState and
+  // ensure the Reader mode UI is dismissed.
+  DestroyReaderModeWebState();
 }
 
 web::WebState* ReaderModeTabHelper::GetReaderModeWebState() {
@@ -181,7 +187,7 @@
     web::NavigationContext* navigation_context) {
   if (!navigation_context->IsSameDocument() ||
       navigation_context->HasUserGesture()) {
-    SetActive(false);
+    DeactivateReader();
   }
 
   SetLastCommittedUrl(web_state->GetLastCommittedURL());
@@ -189,7 +195,7 @@
 
 void ReaderModeTabHelper::WebStateDestroyed(web::WebState* web_state) {
   CHECK_EQ(web_state_, web_state);
-  SetActive(false);
+  DeactivateReader();
   web_state_observation_.Reset();
   web_state_ = nullptr;
 }
@@ -350,7 +356,7 @@
           ->LoadContent(page_url, content_data);
     } else {
       // If the page could not be distilled, deactivate Reader mode in this tab.
-      SetActive(false);
+      DeactivateReader();
       for (auto& observer : observers_) {
         observer.ReaderModeDistillationFailed(this);
       }
@@ -359,8 +365,6 @@
 }
 
 void ReaderModeTabHelper::CreateReaderModeWebState() {
-  metrics_helper_.RecordReaderDistillerTriggered();
-
   web::WebState::CreateParams create_params = web::WebState::CreateParams(
       ProfileIOS::FromBrowserState(web_state_->GetBrowserState())
           ->GetOffTheRecordProfile());
@@ -431,7 +435,7 @@
 
 void ReaderModeTabHelper::CancelDistillation() {
   metrics_helper_.RecordReaderDistillerTimedOut();
-  SetActive(false);
+  DeactivateReader();
   for (auto& observer : observers_) {
     observer.ReaderModeDistillationFailed(this);
   }
diff --git a/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper_unittest.mm b/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper_unittest.mm
index c3887687..7d39e17 100644
--- a/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper_unittest.mm
+++ b/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper_unittest.mm
@@ -266,19 +266,20 @@
   // Initially, no observer methods should be called.
   WaitForReaderModeContentReady();
 
-  // When SetActive(true) is called and distillation completes,
+  // When ActivateReader() is called and distillation completes,
   // ReaderModeWebStateDidLoadContent should be called.
   EXPECT_CALL(mock_observer,
               ReaderModeWebStateDidLoadContent(reader_mode_tab_helper()));
-  reader_mode_tab_helper()->SetActive(true);
+  reader_mode_tab_helper()->ActivateReader(
+      ReaderModeAccessPoint::kContextualChip);
   WaitForReaderModeContentReady();
   testing::Mock::VerifyAndClearExpectations(&mock_observer);
 
-  // When SetActive(false) is called,
+  // When DeactivateReader() is called,
   // ReaderModeWebStateWillBecomeUnavailable should be called.
   EXPECT_CALL(mock_observer, ReaderModeWebStateWillBecomeUnavailable(
                                  reader_mode_tab_helper()));
-  reader_mode_tab_helper()->SetActive(false);
+  reader_mode_tab_helper()->DeactivateReader();
   testing::Mock::VerifyAndClearExpectations(&mock_observer);
 }
 
@@ -316,13 +317,18 @@
   // Initially, no observer methods should be called.
   WaitForReaderModeContentReady();
 
-  // When SetActive(true) is called and distillation fails,
+  // When ActivateReader() is called and distillation fails,
   // ReaderModeDistillationFailed should be called.
   EXPECT_CALL(mock_observer,
               ReaderModeDistillationFailed(reader_mode_tab_helper()));
-  reader_mode_tab_helper()->SetActive(true);
+  reader_mode_tab_helper()->ActivateReader(
+      ReaderModeAccessPoint::kContextualChip);
   WaitForReaderModeContentReady();
   testing::Mock::VerifyAndClearExpectations(&mock_observer);
+
+  // Access point metric should still be triggered on distillation failure.
+  EXPECT_THAT(histogram_tester_.GetAllSamples(kReaderModeAccessPointHistogram),
+              BucketsAre(Bucket(ReaderModeAccessPoint::kContextualChip, 1)));
 }
 
 // Tests that the WebViewProxy is updated when reader mode is toggled.
@@ -348,7 +354,8 @@
 
   EXPECT_CALL(mock_observer,
               ReaderModeWebStateDidLoadContent(reader_mode_tab_helper()));
-  reader_mode_tab_helper()->SetActive(true);
+  reader_mode_tab_helper()->ActivateReader(
+      ReaderModeAccessPoint::kContextualChip);
   WaitForReaderModeContentReady();
   testing::Mock::VerifyAndClearExpectations(&mock_observer);
 
@@ -358,7 +365,7 @@
 
   EXPECT_CALL(mock_observer, ReaderModeWebStateWillBecomeUnavailable(
                                  reader_mode_tab_helper()));
-  reader_mode_tab_helper()->SetActive(false);
+  reader_mode_tab_helper()->DeactivateReader();
   EXPECT_EQ(original_proxy, web_view_proxy_tab_helper->GetWebViewProxy());
 }
 
@@ -376,7 +383,8 @@
   // Initially, no observer methods should be called.
   WaitForReaderModeContentReady();
 
-  reader_mode_tab_helper()->SetActive(true);
+  reader_mode_tab_helper()->ActivateReader(
+      ReaderModeAccessPoint::kContextualChip);
   WaitForReaderModeContentReady();
   web::WebState* reader_mode_web_state =
       reader_mode_tab_helper()->GetReaderModeWebState();
@@ -398,9 +406,10 @@
   // Initially, no observer methods should be called.
   WaitForReaderModeContentReady();
 
-  // When SetActive(true) is called and distillation completes,
+  // When ActivateReader() is called and distillation completes,
   // ReaderModeWebStateDidBecomeAvailable should be called.
-  reader_mode_tab_helper()->SetActive(true);
+  reader_mode_tab_helper()->ActivateReader(
+      ReaderModeAccessPoint::kContextualChip);
   WaitForReaderModeContentReady();
 
   // The metrics for the navigation are recorded.
@@ -430,10 +439,10 @@
   // Move past the custom heuristic page load time.
   WaitForReaderModeContentReady();
 
-  // When SetActive(true) is called and distillation completes,
-  // ReaderModeWebStateDidBecomeAvailable should be called. The cancelation
-  // should trigger immediately.
-  reader_mode_tab_helper()->SetActive(true);
+  // When ActivateReader() is called and distillation completes,
+  // ReaderModeWebStateDidBecomeAvailable should be called.
+  reader_mode_tab_helper()->ActivateReader(
+      ReaderModeAccessPoint::kContextualChip);
   task_environment()->RunUntilIdle();
 
   // The time out is recorded.
@@ -462,10 +471,10 @@
   // Move past the custom heuristic page load time.
   WaitForReaderModeContentReady();
 
-  // When SetActive(true) is called and distillation completes,
-  // ReaderModeWebStateDidBecomeAvailable should be called. The cancelation
-  // should trigger immediately.
-  reader_mode_tab_helper()->SetActive(true);
+  // When ActivateReader() is called and distillation completes,
+  // ReaderModeWebStateDidBecomeAvailable should be called.
+  reader_mode_tab_helper()->ActivateReader(
+      ReaderModeAccessPoint::kContextualChip);
   task_environment()->RunUntilIdle();
 
   // The completion is recorded.
@@ -575,13 +584,16 @@
 
   // The user explicitly requests distillation independent of the Reader Mode
   // eligibility.
-  reader_mode_tab_helper()->SetActive(true);
+  reader_mode_tab_helper()->ActivateReader(
+      ReaderModeAccessPoint::kContextualChip);
   task_environment()->RunUntilIdle();
 
   // The metrics for the navigation are recorded.
   FlushMetrics();
   EXPECT_THAT(histogram_tester_.GetAllSamples(kReaderModeStateHistogram),
               BucketsAre(Bucket(ReaderModeState::kDistillationCompleted, 1)));
+  EXPECT_THAT(histogram_tester_.GetAllSamples(kReaderModeAccessPointHistogram),
+              BucketsAre(Bucket(ReaderModeAccessPoint::kContextualChip, 1)));
   EXPECT_THAT(
       histogram_tester_.GetAllSamples(kReaderModeDistillerLatencyHistogram),
       BucketsAre(Bucket(0, 1)));
diff --git a/ios/chrome/browser/reader_mode/model/reader_mode_test.h b/ios/chrome/browser/reader_mode/model/reader_mode_test.h
index 967b486..7fac931 100644
--- a/ios/chrome/browser/reader_mode/model/reader_mode_test.h
+++ b/ios/chrome/browser/reader_mode/model/reader_mode_test.h
@@ -32,7 +32,8 @@
   std::unique_ptr<web::FakeWebState> CreateWebState();
 
   // Controls for displaying Reading Mode UI on the fake web state.
-  void EnableReaderMode(web::WebState* web_state);
+  void EnableReaderMode(web::WebState* web_state,
+                        ReaderModeAccessPoint access_point);
   void DisableReaderMode(web::WebState* web_state);
 
   // Loads the web page with fake HTML content and commits the URL.
diff --git a/ios/chrome/browser/reader_mode/model/reader_mode_test.mm b/ios/chrome/browser/reader_mode/model/reader_mode_test.mm
index 8f43ac3..74f089e 100644
--- a/ios/chrome/browser/reader_mode/model/reader_mode_test.mm
+++ b/ios/chrome/browser/reader_mode/model/reader_mode_test.mm
@@ -54,12 +54,13 @@
   return web_state;
 }
 
-void ReaderModeTest::EnableReaderMode(web::WebState* web_state) {
-  ReaderModeTabHelper::FromWebState(web_state)->SetActive(true);
+void ReaderModeTest::EnableReaderMode(web::WebState* web_state,
+                                      ReaderModeAccessPoint access_point) {
+  ReaderModeTabHelper::FromWebState(web_state)->ActivateReader(access_point);
 }
 
 void ReaderModeTest::DisableReaderMode(web::WebState* web_state) {
-  ReaderModeTabHelper::FromWebState(web_state)->SetActive(false);
+  ReaderModeTabHelper::FromWebState(web_state)->DeactivateReader();
 }
 
 void ReaderModeTest::LoadWebpage(web::FakeWebState* web_state,
diff --git a/ios/chrome/browser/share_extension/model/BUILD.gn b/ios/chrome/browser/share_extension/model/BUILD.gn
index e0a1fc4..f3aecf4 100644
--- a/ios/chrome/browser/share_extension/model/BUILD.gn
+++ b/ios/chrome/browser/share_extension/model/BUILD.gn
@@ -36,6 +36,7 @@
   ]
   deps = [
     ":bookmark_adder",
+    ":reading_list_adder",
     ":utils",
     "//base",
     "//google_apis",
@@ -84,3 +85,24 @@
     "//url",
   ]
 }
+
+source_set("reading_list_adder") {
+  sources = [
+    "reading_list_adder.h",
+    "reading_list_adder.mm",
+  ]
+  deps = [
+    ":utils",
+    "//base",
+    "//components/bookmarks/browser",
+    "//components/reading_list/core",
+    "//ios/chrome/browser/bookmarks/model",
+    "//ios/chrome/browser/reading_list/model",
+    "//ios/chrome/browser/shared/model/application_context",
+    "//ios/chrome/browser/shared/model/profile",
+    "//ios/chrome/browser/shared/model/profile:features",
+    "//ios/chrome/browser/shared/public/features:system_flags",
+    "//ios/chrome/common/app_group",
+    "//url",
+  ]
+}
diff --git a/ios/chrome/browser/share_extension/model/reading_list_adder.h b/ios/chrome/browser/share_extension/model/reading_list_adder.h
new file mode 100644
index 0000000..a5c2eb77
--- /dev/null
+++ b/ios/chrome/browser/share_extension/model/reading_list_adder.h
@@ -0,0 +1,65 @@
+// Copyright 2025 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_SHARE_EXTENSION_MODEL_READING_LIST_ADDER_H_
+#define IOS_CHROME_BROWSER_SHARE_EXTENSION_MODEL_READING_LIST_ADDER_H_
+
+#import "base/functional/callback.h"
+#import "base/scoped_observation.h"
+#import "components/reading_list/core/reading_list_model_observer.h"
+#import "ios/chrome/browser/shared/model/profile/profile_manager_ios.h"
+#import "ios/chrome/browser/shared/model/profile/profile_manager_observer_ios.h"
+#import "ios/chrome/browser/shared/model/profile/scoped_profile_keep_alive_ios.h"
+#import "url/gurl.h"
+
+class ReadingListModel;
+
+class ProfileManagerIOS;
+class ScopedProfileKeepAliveIOS;
+
+// A class to load a given profile and reading list a URL for that given
+// profile. It acts as an observer for both the profile (loaded/destroyed etc)
+// and reading list.
+class ReadingListAdder : public ProfileManagerObserverIOS,
+                         public ReadingListModelObserver {
+ public:
+  ReadingListAdder(const GURL& url_to_add, std::string title_to_add);
+
+  ReadingListAdder(const ReadingListAdder&) = delete;
+  ReadingListAdder& operator=(const ReadingListAdder&) = delete;
+
+  ~ReadingListAdder() override;
+
+  // ProfileManagerObserverIOS:
+  void OnProfileManagerWillBeDestroyed(ProfileManagerIOS* manager) override;
+  void OnProfileManagerDestroyed(ProfileManagerIOS* manager) override;
+  void OnProfileCreated(ProfileManagerIOS* manager,
+                        ProfileIOS* profile) override;
+  void OnProfileLoaded(ProfileManagerIOS* manager,
+                       ProfileIOS* profile) override;
+  void OnProfileUnloaded(ProfileManagerIOS* manager,
+                         ProfileIOS* profile) override;
+  void OnProfileMarkedForPermanentDeletion(ProfileManagerIOS* manager,
+                                           ProfileIOS* profile) override;
+
+  // ReadingListModelObserver:
+  void ReadingListModelLoaded(const ReadingListModel* model) override;
+
+  void OnProfileLoaded(ScopedProfileKeepAliveIOS keep_alive,
+                       base::OnceClosure completion);
+
+ private:
+  const std::string title_to_add_;
+  const GURL url_to_add_;
+  base::OnceClosure completion_;
+  ScopedProfileKeepAliveIOS keep_alive_;
+  base::ScopedObservation<ProfileManagerIOS, ProfileManagerObserverIOS>
+      profile_manager_observation_{this};
+  base::ScopedObservation<ReadingListModel, ReadingListModelObserver>
+      reading_list_model_observation_{this};
+
+  void AddUrlToReadingListModel(ReadingListModel* model);
+};
+
+#endif  // IOS_CHROME_BROWSER_SHARE_EXTENSION_MODEL_READING_LIST_ADDER_H_
diff --git a/ios/chrome/browser/share_extension/model/reading_list_adder.mm b/ios/chrome/browser/share_extension/model/reading_list_adder.mm
new file mode 100644
index 0000000..a22bbf53
--- /dev/null
+++ b/ios/chrome/browser/share_extension/model/reading_list_adder.mm
@@ -0,0 +1,71 @@
+// Copyright 2025 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/share_extension/model/reading_list_adder.h"
+
+#import "base/strings/utf_string_conversions.h"
+#import "components/reading_list/core/reading_list_model.h"
+#import "ios/chrome/browser/reading_list/model/reading_list_model_factory.h"
+#import "ios/chrome/browser/shared/model/application_context/application_context.h"
+#import "url/gurl.h"
+
+ReadingListAdder::ReadingListAdder(const GURL& url_to_add,
+                                   std::string title_to_add)
+    : title_to_add_(title_to_add), url_to_add_(url_to_add) {
+  profile_manager_observation_.Observe(
+      GetApplicationContext()->GetProfileManager());
+}
+
+ReadingListAdder::~ReadingListAdder() {}
+
+void ReadingListAdder::AddUrlToReadingListModel(ReadingListModel* model) {
+  model->AddOrReplaceEntry(url_to_add_, title_to_add_,
+                           reading_list::ADDED_VIA_EXTENSION,
+                           base::TimeDelta());
+  std::move(completion_).Run();
+}
+
+void ReadingListAdder::OnProfileLoaded(ScopedProfileKeepAliveIOS keep_alive,
+                                       base::OnceClosure completion) {
+  keep_alive_ = std::move(keep_alive);
+  completion_ = std::move(completion);
+
+  ReadingListModel* model =
+      ReadingListModelFactory::GetForProfile(keep_alive_.profile());
+
+  if (!model->loaded()) {
+    reading_list_model_observation_.Observe(model);
+    return;
+  }
+
+  ReadingListAdder::AddUrlToReadingListModel(model);
+}
+
+void ReadingListAdder::OnProfileManagerWillBeDestroyed(
+    ProfileManagerIOS* manager) {
+  keep_alive_ = ScopedProfileKeepAliveIOS{};
+  reading_list_model_observation_.Reset();
+  if (completion_) {
+    std::move(completion_).Run();
+  }
+}
+
+void ReadingListAdder::OnProfileLoaded(ProfileManagerIOS* manager,
+                                       ProfileIOS* profile) {}
+void ReadingListAdder::OnProfileManagerDestroyed(ProfileManagerIOS* manager) {
+  profile_manager_observation_.Reset();
+}
+void ReadingListAdder::OnProfileCreated(ProfileManagerIOS* manager,
+                                        ProfileIOS* profile) {}
+void ReadingListAdder::OnProfileUnloaded(ProfileManagerIOS* manager,
+                                         ProfileIOS* profile) {}
+void ReadingListAdder::OnProfileMarkedForPermanentDeletion(
+    ProfileManagerIOS* manager,
+    ProfileIOS* profile) {}
+
+void ReadingListAdder::ReadingListModelLoaded(const ReadingListModel* model) {
+  ReadingListModel* reading_list_model =
+      ReadingListModelFactory::GetForProfile(keep_alive_.profile());
+  AddUrlToReadingListModel(reading_list_model);
+}
diff --git a/ios/chrome/browser/share_extension/model/share_extension_controller.mm b/ios/chrome/browser/share_extension/model/share_extension_controller.mm
index bd2835f..53c0529 100644
--- a/ios/chrome/browser/share_extension/model/share_extension_controller.mm
+++ b/ios/chrome/browser/share_extension/model/share_extension_controller.mm
@@ -21,6 +21,7 @@
 #import "google_apis/gaia/gaia_id.h"
 #import "ios/chrome/browser/share_extension/model/bookmark_adder.h"
 #import "ios/chrome/browser/share_extension/model/parsed_share_extension_entry.h"
+#import "ios/chrome/browser/share_extension/model/reading_list_adder.h"
 #import "ios/chrome/browser/share_extension/model/share_extension_utils.h"
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
 #import "ios/chrome/browser/shared/model/profile/features.h"
@@ -74,13 +75,30 @@
   return UNKNOWN_SOURCE;
 }
 
-void OnProfileLoaded(std::unique_ptr<BookmarkAdder> adder,
+template <typename T>
+void OnProfileLoaded(std::unique_ptr<T> adder,
                      ScopedProfileKeepAliveIOS keep_alive) {
-  BookmarkAdder* adder_ptr = adder.get();
+  T* adder_ptr = adder.get();
   adder_ptr->OnProfileLoaded(
       std::move(keep_alive),
-      base::BindOnce([](std::unique_ptr<BookmarkAdder> adder) {},
-                     std::move(adder)));
+      base::BindOnce([](std::unique_ptr<T> adder) {}, std::move(adder)));
+}
+
+template <typename Adder, typename... Args>
+void AddDataToProfileByGaiaID(NSString* gaiaID, Args&&... args) {
+  std::optional<std::string> profileName =
+      GetApplicationContext()
+          ->GetAccountProfileMapper()
+          ->FindProfileNameForGaiaID(GaiaId(gaiaID));
+
+  if (profileName.has_value()) {
+    ProfileManagerIOS* profileManager =
+        GetApplicationContext()->GetProfileManager();
+    auto adder = std::make_unique<Adder>(std::forward<Args>(args)...);
+    profileManager->LoadProfileAsync(
+        *profileName,
+        base::BindOnce(&OnProfileLoaded<Adder>, std::move(adder)));
+  }
 }
 
 }  // namespace
@@ -329,14 +347,47 @@
                   completion:(ProceduralBlock)completion {
   DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker);
 
-  if (entryType == app_group::BOOKMARK_ITEM) {
-    [self addBookmarkToProfileByGaiaID:gaiaID
-                                   URL:entryURL
-                         bookmarkTitle:entryTitle];
+  switch (entryType) {
+    case app_group::BOOKMARK_ITEM: {
+      LogHistogramReceivedItem(BOOKMARK_ENTRY);
+      [self addBookmarkToProfileByGaiaID:gaiaID
+                                     URL:entryURL
+                           bookmarkTitle:entryTitle];
+      break;
+    }
+    case app_group::READING_LIST_ITEM: {
+      LogHistogramReceivedItem(READINGLIST_ENTRY);
+      [self addReadingListToProfileByGaiaID:gaiaID
+                                        URL:entryURL
+                           readingListTitle:entryTitle];
+      break;
+    }
+    case app_group::OPEN_IN_CHROME_ITEM: {
+      LogHistogramReceivedItem(OPEN_IN_CHROME_ENTRY);
+      break;
+    }
+    case app_group::OPEN_IN_CHROME_INCOGNITO_ITEM: {
+      LogHistogramReceivedItem(OPEN_IN_CHROME_INCOGNITO_ENTRY);
+      break;
+    }
+    case app_group::IMAGE_SEARCH_ITEM: {
+      LogHistogramReceivedItem(IMAGE_SEARCH_ENTRY);
+      break;
+    }
+    case app_group::TEXT_SEARCH_ITEM: {
+      LogHistogramReceivedItem(TEXT_SEARCH_ENTRY);
+      break;
+    }
+    case app_group::INCOGNITO_IMAGE_SEARCH_ITEM: {
+      LogHistogramReceivedItem(INCOGNITO_IMAGE_SEARCH_ENTRY);
+      break;
+    }
+    case app_group::INCOGNITO_TEXT_SEARCH_ITEM: {
+      LogHistogramReceivedItem(INCOGNITO_TEXT_SEARCH_ENTRY);
+      break;
+    }
   }
 
-  // TODO(crbug.com/40260909): Handle adding the URL to reading list
-
   if (completion) {
     completion();
   }
@@ -346,20 +397,49 @@
                                  URL:(NSURL*)URL
                        bookmarkTitle:(NSString*)bookmarkTitle {
   DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker);
-  std::optional<std::string> profileName =
-      GetApplicationContext()
-          ->GetAccountProfileMapper()
-          ->FindProfileNameForGaiaID(GaiaId(gaiaID));
+  AddDataToProfileByGaiaID<BookmarkAdder>(
+      gaiaID, net::GURLWithNSURL(URL), base::SysNSStringToUTF8(bookmarkTitle));
+  //  std::optional<std::string> profileName =
+  //      GetApplicationContext()
+  //          ->GetAccountProfileMapper()
+  //          ->FindProfileNameForGaiaID(GaiaId(gaiaID));
+  //
+  //  if (profileName.has_value()) {
+  //    std::string title = base::SysNSStringToUTF8(bookmarkTitle);
+  //    ProfileManagerIOS* profileManager =
+  //        GetApplicationContext()->GetProfileManager();
+  //    std::unique_ptr<BookmarkAdder> adder = std::make_unique<BookmarkAdder>(
+  //        net::GURLWithNSURL(URL), std::move(title));
+  //    profileManager->LoadProfileAsync(
+  //        *profileName,
+  //        base::BindOnce(&OnProfileLoaded<BookmarkAdder>, std::move(adder)));
+  //  }
+}
 
-  if (profileName.has_value()) {
-    std::string title = base::SysNSStringToUTF8(bookmarkTitle);
-    ProfileManagerIOS* profileManager =
-        GetApplicationContext()->GetProfileManager();
-    std::unique_ptr<BookmarkAdder> adder = std::make_unique<BookmarkAdder>(
-        net::GURLWithNSURL(URL), std::move(title));
-    profileManager->LoadProfileAsync(
-        *profileName, base::BindOnce(&OnProfileLoaded, std::move(adder)));
-  }
+- (void)addReadingListToProfileByGaiaID:(NSString*)gaiaID
+                                    URL:(NSURL*)URL
+                       readingListTitle:(NSString*)readingListTitle {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(_sequenceChecker);
+  AddDataToProfileByGaiaID<ReadingListAdder>(
+      gaiaID, net::GURLWithNSURL(URL),
+      base::SysNSStringToUTF8(readingListTitle));
+  //  std::optional<std::string> profileName =
+  //      GetApplicationContext()
+  //          ->GetAccountProfileMapper()
+  //          ->FindProfileNameForGaiaID(GaiaId(gaiaID));
+  //
+  //  if (profileName.has_value()) {
+  //    std::string title = base::SysNSStringToUTF8(readingListTitle);
+  //    ProfileManagerIOS* profileManager =
+  //        GetApplicationContext()->GetProfileManager();
+  //    std::unique_ptr<ReadingListAdder> adder =
+  //        std::make_unique<ReadingListAdder>(net::GURLWithNSURL(URL), title,
+  //                                           profileManager);
+  //    profileManager->LoadProfileAsync(
+  //        *profileName,
+  //        base::BindOnce(&OnProfileLoaded<ReadingListAdder>,
+  //        std::move(adder)));
+  //  }
 }
 
 @end
diff --git a/ios/chrome/browser/shared/coordinator/scene/BUILD.gn b/ios/chrome/browser/shared/coordinator/scene/BUILD.gn
index 5898e13..b6f75c1b 100644
--- a/ios/chrome/browser/shared/coordinator/scene/BUILD.gn
+++ b/ios/chrome/browser/shared/coordinator/scene/BUILD.gn
@@ -184,6 +184,7 @@
     "//ios/chrome/browser/shared/model/web_state_list:utils",
     "//ios/chrome/browser/shared/public/commands",
     "//ios/chrome/browser/shared/public/features",
+    "//ios/chrome/browser/shared/public/prototypes/diamond",
     "//ios/chrome/browser/shared/ui/util",
     "//ios/chrome/browser/shared/ui/util:snackbar_util",
     "//ios/chrome/browser/signin/model",
diff --git a/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm b/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm
index 10bb8f7..07790f2 100644
--- a/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm
+++ b/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm
@@ -175,6 +175,7 @@
 #import "ios/chrome/browser/shared/public/commands/show_signin_command.h"
 #import "ios/chrome/browser/shared/public/commands/snackbar_commands.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
+#import "ios/chrome/browser/shared/public/prototypes/diamond/utils.h"
 #import "ios/chrome/browser/shared/ui/util/snackbar_util.h"
 #import "ios/chrome/browser/shared/ui/util/top_view_controller.h"
 #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
@@ -2118,6 +2119,26 @@
     }
   }
 
+  if (IsDiamondPrototypeEnabled()) {
+    if (!command.URL.is_valid() || IsUrlNtp(command.URL)) {
+      if (command.inIncognito !=
+          (self.currentInterface == self.incognitoInterface)) {
+        [self setCurrentInterfaceForMode:command.inIncognito
+                                             ? ApplicationMode::INCOGNITO
+                                             : ApplicationMode::NORMAL];
+      }
+      dispatch_after(
+          dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)),
+          dispatch_get_main_queue(), ^{
+            DiamondPrototypeStartNewTab(
+                self.mainCoordinator.tabGridActive, command.inIncognito,
+                self.mainInterface.browser, self.incognitoInterface.browser,
+                self.mainCoordinator.activeViewController);
+          });
+      return;
+    }
+  }
+
   UrlLoadParams params =
       UrlLoadParams::InNewTab(command.URL, command.virtualURL);
   params.SetInBackground(command.inBackground);
@@ -3420,6 +3441,10 @@
 }
 
 - (BOOL)shouldOpenNTPTabOnActivationOfBrowser:(Browser*)browser {
+  if (IsDiamondPrototypeEnabled()) {
+    return NO;
+  }
+
   // Check if there are pending actions that would result in opening a new tab.
   // In that case, it is not useful to open another tab.
   for (NSUserActivity* activity in self.sceneState.connectionOptions
diff --git a/ios/chrome/browser/shared/public/commands/BUILD.gn b/ios/chrome/browser/shared/public/commands/BUILD.gn
index d806c45..f1ecbb5 100644
--- a/ios/chrome/browser/shared/public/commands/BUILD.gn
+++ b/ios/chrome/browser/shared/public/commands/BUILD.gn
@@ -107,6 +107,7 @@
     "//ios/chrome/browser/authentication/ui_bundled/signin:constants",
     "//ios/chrome/browser/browsing_data/model:util",
     "//ios/chrome/browser/lens_overlay/model:entrypoint",
+    "//ios/chrome/browser/reader_mode/model:constants",
     "//ios/chrome/browser/shared/ui/util:url_with_title",
     "//ios/chrome/browser/tab_switcher/ui_bundled/tab_grid:tab_grid_paging",
     "//ios/public/provider/chrome/browser/user_feedback:user_feedback_api",
diff --git a/ios/chrome/browser/shared/public/commands/reader_mode_commands.h b/ios/chrome/browser/shared/public/commands/reader_mode_commands.h
index 5164a6e7..99248c3d 100644
--- a/ios/chrome/browser/shared/public/commands/reader_mode_commands.h
+++ b/ios/chrome/browser/shared/public/commands/reader_mode_commands.h
@@ -7,11 +7,13 @@
 
 #import <Foundation/Foundation.h>
 
+#import "ios/chrome/browser/reader_mode/model/constants.h"
+
 // Commands protocol to show/hide the Reader mode UI.
 @protocol ReaderModeCommands <NSObject>
 
 // Shows the Reader mode UI.
-- (void)showReaderMode;
+- (void)showReaderModeFromAccessPoint:(ReaderModeAccessPoint)accessPoint;
 
 // Hides the Reader mode UI.
 - (void)hideReaderMode;
diff --git a/ios/chrome/browser/shared/public/prototypes/diamond/diamond_grid_button.mm b/ios/chrome/browser/shared/public/prototypes/diamond/diamond_grid_button.mm
index 7cff49d4..09cde27f 100644
--- a/ios/chrome/browser/shared/public/prototypes/diamond/diamond_grid_button.mm
+++ b/ios/chrome/browser/shared/public/prototypes/diamond/diamond_grid_button.mm
@@ -39,6 +39,9 @@
 }
 
 - (void)setup {
+  // The app starts in the TabGrid.
+  [self didEnterTabGrid];
+
   NSNotificationCenter* notificationCenter =
       [NSNotificationCenter defaultCenter];
   [notificationCenter addObserver:self
diff --git a/ios/chrome/browser/side_swipe/ui_bundled/side_swipe_mediator_unittest.mm b/ios/chrome/browser/side_swipe/ui_bundled/side_swipe_mediator_unittest.mm
index 2413c9c4..e3c01577 100644
--- a/ios/chrome/browser/side_swipe/ui_bundled/side_swipe_mediator_unittest.mm
+++ b/ios/chrome/browser/side_swipe/ui_bundled/side_swipe_mediator_unittest.mm
@@ -191,7 +191,8 @@
   SetReaderModeState(fake_web_state.get(), test_url,
                      ReaderModeHeuristicResult::kReaderModeEligible, "content");
   LoadWebpage(fake_web_state.get(), test_url);
-  EnableReaderMode(fake_web_state.get());
+  EnableReaderMode(fake_web_state.get(),
+                   ReaderModeAccessPoint::kContextualChip);
   WaitForReaderModeContentReady();
 
   [side_swipe_mediator_
diff --git a/ios/chrome/browser/start_surface/ui_bundled/start_surface_scene_agent.mm b/ios/chrome/browser/start_surface/ui_bundled/start_surface_scene_agent.mm
index 896ccb5e..5fffcb7 100644
--- a/ios/chrome/browser/start_surface/ui_bundled/start_surface_scene_agent.mm
+++ b/ios/chrome/browser/start_surface/ui_bundled/start_surface_scene_agent.mm
@@ -137,6 +137,9 @@
 }
 
 - (void)showStartSurfaceIfNecessary {
+  if (IsDiamondPrototypeEnabled()) {
+    return;
+  }
   if (self.sceneState.profileState.initStage < ProfileInitStage::kFinal) {
     // NO if the app is not yet ready to present normal UI that is required by
     // Start Surface.
@@ -352,6 +355,17 @@
   webStateList->CloseWebStatesAtIndices(
       WebStateList::ClosingReason::kDefault,
       RemovingIndexes(std::move(indicesToRemove)));
+
+  if (IsDiamondPrototypeEnabled()) {
+    for (int index = webStateList->count() - 1; index >= 0; --index) {
+      const web::WebState* webState = webStateList->GetWebStateAt(index);
+      const TabGroup* tabGroup = webStateList->GetGroupOfWebStateAt(index);
+      if (IsNTP(webState) && !tabGroup) {
+        webStateList->CloseWebStateAt(index,
+                                      WebStateList::ClosingReason::kDefault);
+      }
+    }
+  }
 }
 
 // Returns YES if the WebState at the given index has been activated. Only
diff --git a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_grid_coordinator.mm b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_grid_coordinator.mm
index 95f2789e..45cfae731 100644
--- a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_grid_coordinator.mm
+++ b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/tab_grid_coordinator.mm
@@ -364,6 +364,10 @@
         startDispatchingToTarget:[self bookmarksCoordinator]
                      forProtocol:@protocol(BookmarksCommands)];
   }
+
+  if (IsDiamondPrototypeEnabled()) {
+    _appBar.incognitoBrowser = incognitoBrowser;
+  }
 }
 
 - (void)stopChildCoordinatorsWithCompletion:(ProceduralBlock)completion {
@@ -568,6 +572,20 @@
   __weak TabGridCoordinator* weakSelf = self;
 
   if (IsDiamondPrototypeEnabled()) {
+    Browser* browser =
+        incognito ? _incognitoBrowser.get() : self.regularBrowser;
+    // Don't open the TabGrid if there is no web state. It can happen at
+    // startup.
+    if (browser && browser->GetWebStateList()->count() == 0) {
+      TabGridViewController* baseViewController = self.baseViewController;
+      [baseViewController contentWillAppearAnimated:NO];
+      [baseViewController contentDidAppear];
+      if (completion) {
+        completion();
+      }
+      return;
+    }
+
     [[NSNotificationCenter defaultCenter]
         postNotificationName:kDiamondLeaveTabGridNotification
                       object:nil];
diff --git a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/toolbars/tab_grid_bottom_toolbar.mm b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/toolbars/tab_grid_bottom_toolbar.mm
index 593a822..8554afd 100644
--- a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/toolbars/tab_grid_bottom_toolbar.mm
+++ b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/toolbars/tab_grid_bottom_toolbar.mm
@@ -248,8 +248,14 @@
   UIButton* button;
 #if defined(__IPHONE_26_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_26_0
   if (@available(iOS 26, *)) {
-    UIButtonConfiguration* buttonConfiguration =
-        [UIButtonConfiguration prominentGlassButtonConfiguration];
+    UIButtonConfiguration* buttonConfiguration;
+    if ([UIButtonConfiguration
+            respondsToSelector:@selector(prominentGlassButtonConfiguration)]) {
+      buttonConfiguration =
+          [UIButtonConfiguration prominentGlassButtonConfiguration];
+    } else {
+      buttonConfiguration = [UIButtonConfiguration glassButtonConfiguration];
+    }
     buttonConfiguration.title = title;
     buttonConfiguration.image = image;
     button = [UIButton buttonWithConfiguration:buttonConfiguration
diff --git a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/toolbars/tab_grid_top_toolbar.mm b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/toolbars/tab_grid_top_toolbar.mm
index 8bf2a85..ad448690 100644
--- a/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/toolbars/tab_grid_top_toolbar.mm
+++ b/ios/chrome/browser/tab_switcher/ui_bundled/tab_grid/toolbars/tab_grid_top_toolbar.mm
@@ -313,8 +313,14 @@
 
 #if defined(__IPHONE_26_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_26_0
   if (@available(iOS 26, *)) {
-    UIButtonConfiguration* buttonConfiguration =
-        [UIButtonConfiguration prominentGlassButtonConfiguration];
+    UIButtonConfiguration* buttonConfiguration;
+    if ([UIButtonConfiguration
+            respondsToSelector:@selector(prominentGlassButtonConfiguration)]) {
+      buttonConfiguration =
+          [UIButtonConfiguration prominentGlassButtonConfiguration];
+    } else {
+      buttonConfiguration = [UIButtonConfiguration glassButtonConfiguration];
+    }
     buttonConfiguration.title = title;
     buttonConfiguration.image = image;
     button = [UIButton buttonWithConfiguration:buttonConfiguration
diff --git a/ios/chrome/share_extension/extended_share_view_controller.mm b/ios/chrome/share_extension/extended_share_view_controller.mm
index 175ded64..69d9574 100644
--- a/ios/chrome/share_extension/extended_share_view_controller.mm
+++ b/ios/chrome/share_extension/extended_share_view_controller.mm
@@ -822,6 +822,7 @@
   __weak ExtendedShareViewController* weakSelf = self;
   [self queueActionItemURL:_shareURL
                      title:_shareTitle
+                    gaiaID:gaiaID
                     action:app_group::READING_LIST_ITEM
                     cancel:NO
                 completion:^{
diff --git a/ios_internal b/ios_internal
index 66f62a3..45e7e30 160000
--- a/ios_internal
+++ b/ios_internal
@@ -1 +1 @@
-Subproject commit 66f62a3e6eaa6a83cdb803293328c40ab5db35aa
+Subproject commit 45e7e3004508820d06e4e208db56518783d89492
diff --git a/media/base/audio_bus_unittest.cc b/media/base/audio_bus_unittest.cc
index ff0a147..621a7f3 100644
--- a/media/base/audio_bus_unittest.cc
+++ b/media/base/audio_bus_unittest.cc
@@ -16,6 +16,7 @@
 #include <limits>
 #include <memory>
 
+#include "base/containers/span.h"
 #include "base/memory/aligned_memory.h"
 #include "base/memory/raw_ptr.h"
 #include "base/strings/stringprintf.h"
@@ -305,9 +306,10 @@
   VerifyReadWriteAndAlignment(bus.get());
 
   // Verify the channel vectors lie within the provided memory block.
-  const float* backing_memory_start = data.as_span().data();
-  const float* backing_memory_end = backing_memory_start + total_frame_count;
-  EXPECT_GE(bus->channel_span(0).data(), backing_memory_start);
+  base::span<const float> backing_memory_start = data.as_span();
+  const float* backing_memory_end =
+      backing_memory_start.subspan(total_frame_count).data();
+  EXPECT_GE(bus->channel_span(0).data(), backing_memory_start.data());
   EXPECT_LT(bus->channel_span(bus->channels() - 1).data() + bus->frames(),
             backing_memory_end);
 }
diff --git a/media/base/decoder_buffer.h b/media/base/decoder_buffer.h
index f03dead..252b6f5 100644
--- a/media/base/decoder_buffer.h
+++ b/media/base/decoder_buffer.h
@@ -142,7 +142,8 @@
   // TODO(crbug.com/365814210): Remove this method.
   TimeInfo time_info() const {
     DCHECK(!end_of_stream());
-    return {timestamp_, duration_, discard_padding()};
+    return {timestamp_, duration_,
+            discard_padding().value_or(DiscardPadding())};
   }
 
   base::TimeDelta timestamp() const {
@@ -221,10 +222,10 @@
                             : data_.subspan(offset, count);
   }
 
-  // TODO(crbug.com/365814210): Change the return type to std::optional.
-  DiscardPadding discard_padding() const {
+  std::optional<DiscardPadding> discard_padding() const {
     DCHECK(!end_of_stream());
-    return side_data_ ? side_data_->discard_padding : DiscardPadding();
+    return side_data_ ? std::make_optional(side_data_->discard_padding)
+                      : std::nullopt;
   }
 
   // TODO(crbug.com/365814210): Remove this method and force callers to get it
diff --git a/media/base/multi_channel_resampler.cc b/media/base/multi_channel_resampler.cc
index c76d573..1e49c92 100644
--- a/media/base/multi_channel_resampler.cc
+++ b/media/base/multi_channel_resampler.cc
@@ -54,13 +54,13 @@
 void MultiChannelResampler::Resample(int frames, AudioBus* audio_bus) {
   DCHECK_EQ(static_cast<size_t>(audio_bus->channels()), resamplers_.size());
 
+  const size_t total_frames = base::checked_cast<size_t>(frames);
   // Optimize the single channel case to avoid the chunking process below.
   if (audio_bus->channels() == 1) {
-    resamplers_[0]->Resample(frames, audio_bus->channel_span(0).data());
+    resamplers_[0]->Resample(frames, audio_bus->channel_span(0).first(total_frames));
     return;
   }
 
-  const size_t total_frames = base::checked_cast<size_t>(frames);
 
   // We need to ensure that SincResampler only calls ProvideInput once for each
   // channel.  To ensure this, we chunk the number of requested frames into
@@ -82,9 +82,10 @@
       // the first channel, then it will call it for the remaining channels,
       // since they all buffer in the same way and are processing the same
       // number of frames.
-      resamplers_[i]->Resample(
-          frames_this_time,
-          audio_bus->channel_span(i).subspan(output_frames_ready_).data());
+      resamplers_[i]->Resample(frames_this_time,
+                               audio_bus->channel_span(i)
+                                   .subspan(output_frames_ready_)
+                                   .first(frames_this_time));
     }
 
     output_frames_ready_ += frames_this_time;
diff --git a/media/base/ranges.h b/media/base/ranges.h
index 98fcfeb2..d40d8237 100644
--- a/media/base/ranges.h
+++ b/media/base/ranges.h
@@ -49,9 +49,6 @@
   // Clear all ranges.
   void clear();
 
-  // Removes the first range.
-  void pop_front();
-
   // Computes the intersection between this range and |other|.
   Ranges<T> IntersectionWith(const Ranges<T>& other) const;
 
@@ -67,11 +64,6 @@
 // EVERYTHING BELOW HERE IS IMPLEMENTATION DETAIL!!
 //////////////////////////////////////////////////////////////////////
 
-template <typename T>
-void Ranges<T>::pop_front() {
-  ranges_.erase(ranges_.begin());
-}
-
 template<class T>
 size_t Ranges<T>::Add(T start, T end) {
   if (start == end)  // Nothing to be done with empty ranges.
diff --git a/media/base/sinc_resampler.cc b/media/base/sinc_resampler.cc
index f08666f3..61a3741d 100644
--- a/media/base/sinc_resampler.cc
+++ b/media/base/sinc_resampler.cc
@@ -85,6 +85,8 @@
 #include <numbers>
 
 #include "base/check_op.h"
+#include "base/containers/auto_spanification_helper.h"
+#include "base/containers/span.h"
 #include "base/cpu.h"
 #include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
@@ -278,10 +280,16 @@
   }
 }
 
-void SincResampler::Resample(int frames, float* destination) {
+void SincResampler::Resample(int spanification_suspected_redundant_frames,
+                             base::span<float> destination) {
+  // TODO(crbug.com/431824301): Remove unneeded parameter once validated to be
+  // redundant in M143.
+  CHECK(static_cast<size_t>(spanification_suspected_redundant_frames) ==
+            destination.size(),
+        base::NotFatalUntil::M143);
   TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("audio"), "SincResampler::Resample",
                "io sample rate ratio", io_sample_rate_ratio_);
-  int remaining_frames = frames;
+  int remaining_frames = spanification_suspected_redundant_frames;
 
   // Step (1) -- Prime the input buffer at the start of the input stream.
   if (!buffer_primed_ && remaining_frames) {
@@ -290,6 +298,7 @@
   }
 
   // Step (2) -- Resample!
+  auto dest_iter = destination.begin();
   while (remaining_frames) {
     // Silent audio can contain non-zero samples small enough to result in
     // subnormals internally. Disabling subnormals can be significantly faster.
@@ -320,8 +329,8 @@
         // Figure out how much to weight each kernel's "convolution".
         const double kernel_interpolation_factor =
             virtual_offset_idx - offset_idx;
-        *destination++ = convolve_proc_(kernel_size_, input_ptr, k1, k2,
-                                        kernel_interpolation_factor);
+        *dest_iter++ = convolve_proc_(
+            kernel_size_, input_ptr, k1, k2, kernel_interpolation_factor);
 
         // Advance the virtual index.
         virtual_source_idx_ += io_sample_rate_ratio_;
diff --git a/media/base/sinc_resampler.h b/media/base/sinc_resampler.h
index 99eae3f9..ee4cfd2 100644
--- a/media/base/sinc_resampler.h
+++ b/media/base/sinc_resampler.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include "base/containers/span.h"
 #include "base/functional/callback.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/aligned_memory.h"
@@ -64,7 +65,8 @@
   ~SincResampler();
 
   // Resample |frames| of data from |read_cb_| into |destination|.
-  void Resample(int frames, float* destination);
+  void Resample(int spanification_suspected_redundant_frames,
+                base::span<float> destination);
 
   // The maximum size in output frames that guarantees Resample() will only make
   // a single call to |read_cb_| for more data.  Note: If PrimeWithSilence() is
diff --git a/media/base/sinc_resampler_unittest.cc b/media/base/sinc_resampler_unittest.cc
index 34de954..7edec05 100644
--- a/media/base/sinc_resampler_unittest.cc
+++ b/media/base/sinc_resampler_unittest.cc
@@ -55,19 +55,20 @@
                                               base::Unretained(&mock_source)));
 
   static const int kChunks = 2;
-  int max_chunk_size = resampler.ChunkSize() * kChunks;
+  size_t max_chunk_size = resampler.ChunkSize() * kChunks;
   auto resampled_destination = base::HeapArray<float>::Uninit(max_chunk_size);
 
   // Verify requesting ChunkSize() frames causes a single callback.
   EXPECT_CALL(mock_source, ProvideInput(_, _)).Times(1).WillOnce(ClearBuffer());
-  resampler.Resample(resampler.ChunkSize(), resampled_destination.data());
+  const size_t chunk_size = resampler.ChunkSize();
+  resampler.Resample(chunk_size, resampled_destination.first(chunk_size));
 
   // Verify requesting kChunks * ChunkSize() frames causes kChunks callbacks.
   testing::Mock::VerifyAndClear(&mock_source);
   EXPECT_CALL(mock_source, ProvideInput(_, _))
       .Times(kChunks)
       .WillRepeatedly(ClearBuffer());
-  resampler.Resample(max_chunk_size, resampled_destination.data());
+  resampler.Resample(max_chunk_size, resampled_destination);
 }
 
 // Verify priming the resampler avoids changes to ChunkSize() between calls.
@@ -103,7 +104,8 @@
 
   // Verify requesting ChunkSize() frames causes a single callback.
   EXPECT_CALL(mock_source, ProvideInput(_, _)).Times(1).WillOnce(ClearBuffer());
-  resampler.Resample(max_chunk_size, resampled_destination.data());
+  resampler.Resample(max_chunk_size, resampled_destination.first(
+                                         static_cast<size_t>(max_chunk_size)));
   EXPECT_EQ(max_chunk_size, resampler.ChunkSize());
 
   // Verify requesting kChunks * ChunkSize() frames causes kChunks callbacks.
@@ -111,7 +113,7 @@
   EXPECT_CALL(mock_source, ProvideInput(_, _))
       .Times(kChunks)
       .WillRepeatedly(ClearBuffer());
-  resampler.Resample(kMaxFrames, resampled_destination.data());
+  resampler.Resample(kMaxFrames, resampled_destination);
   EXPECT_EQ(max_chunk_size, resampler.ChunkSize());
 }
 
@@ -126,14 +128,16 @@
 
   // Fill the resampler with junk data.
   EXPECT_CALL(mock_source, ProvideInput(_, _)).Times(1).WillOnce(FillBuffer());
-  resampler.Resample(resampler.ChunkSize() / 2, resampled_destination.data());
+  resampler.Resample(resampler.ChunkSize() / 2,
+                     resampled_destination.first(resampler.ChunkSize() / 2u));
   ASSERT_NE(resampled_destination[0], 0);
 
   // Flush and request more data, which should all be zeros now.
   resampler.Flush();
   testing::Mock::VerifyAndClear(&mock_source);
   EXPECT_CALL(mock_source, ProvideInput(_, _)).Times(1).WillOnce(ClearBuffer());
-  resampler.Resample(resampler.ChunkSize() / 2, resampled_destination.data());
+  resampler.Resample(resampler.ChunkSize() / 2,
+                     resampled_destination.first(resampler.ChunkSize() / 2u));
   for (int i = 0; i < resampler.ChunkSize() / 2; ++i) {
     ASSERT_FLOAT_EQ(resampled_destination[i], 0);
   }
@@ -309,7 +313,7 @@
   auto pure_destination = base::HeapArray<float>::Uninit(output_samples);
 
   // Generate resampled signal.
-  resampler.Resample(output_samples, resampled_destination.data());
+  resampler.Resample(output_samples, resampled_destination);
 
   // Generate pure signal.
   SinusoidalLinearChirpSource pure_source(output_rate_, output_samples,
@@ -403,7 +407,7 @@
   auto resampled_destination = base::HeapArray<float>::Uninit(output_samples);
 
   // Generate resampled signal.
-  resampler.Resample(output_samples, resampled_destination.data());
+  resampler.Resample(output_samples, resampled_destination);
 
   // Do not check for the maximum error range for the small kernel size,
   // as there is already quite a bit of test data. This test is only meant to
diff --git a/media/base/stream_parser_buffer.cc b/media/base/stream_parser_buffer.cc
index 7152caf4..25c7ad1 100644
--- a/media/base/stream_parser_buffer.cc
+++ b/media/base/stream_parser_buffer.cc
@@ -144,7 +144,7 @@
   DCHECK(!preroll_buffer->end_of_stream());
   DCHECK(!preroll_buffer->preroll_buffer_);
   DCHECK(preroll_buffer->timestamp() <= timestamp());
-  DCHECK(preroll_buffer->discard_padding() == DecoderBuffer::DiscardPadding());
+  DCHECK(!preroll_buffer->discard_padding().has_value());
   DCHECK_EQ(preroll_buffer->type(), type());
   DCHECK_EQ(preroll_buffer->track_id(), track_id());
 
diff --git a/media/base/stream_parser_unittest.cc b/media/base/stream_parser_unittest.cc
index 4318cfa..5fbebbbf 100644
--- a/media/base/stream_parser_unittest.cc
+++ b/media/base/stream_parser_unittest.cc
@@ -16,6 +16,7 @@
 #include <map>
 #include <sstream>
 
+#include "base/containers/span.h"
 #include "media/base/stream_parser_buffer.h"
 #include "media/base/test_data_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -43,11 +44,11 @@
 // their sequence of decode timestamps; a |kEnd| timestamp indicates the
 // end of the sequence and no buffer is appended for it. Each new buffer's
 // type will be |type| with track ID set to |track_id|.
-static void GenerateBuffers(const int* decode_timestamps,
+static void GenerateBuffers(base::span<const int> decode_timestamps,
                             StreamParserBuffer::Type type,
                             TrackId track_id,
                             BufferQueue* queue) {
-  DCHECK(decode_timestamps);
+  DCHECK(!decode_timestamps.empty());
   DCHECK(queue);
   DCHECK_NE(type, DemuxerStream::UNKNOWN);
   DCHECK_LE(type, DemuxerStream::TYPE_MAX);
@@ -88,14 +89,14 @@
 
   // Appends test audio buffers in the sequence described by |decode_timestamps|
   // to |audio_buffers_|. See GenerateBuffers() for |decode_timestamps| format.
-  void GenerateAudioBuffers(const int* decode_timestamps) {
+  void GenerateAudioBuffers(base::span<const int> decode_timestamps) {
     GenerateBuffers(decode_timestamps, DemuxerStream::AUDIO, kAudioTrackId,
                     &buffer_queue_map_[kAudioTrackId]);
   }
 
   // Appends test video buffers in the sequence described by |decode_timestamps|
   // to |video_buffers_|. See GenerateBuffers() for |decode_timestamps| format.
-  void GenerateVideoBuffers(const int* decode_timestamps) {
+  void GenerateVideoBuffers(base::span<const int> decode_timestamps) {
     GenerateBuffers(decode_timestamps, DemuxerStream::VIDEO, kVideoTrackId,
                     &buffer_queue_map_[kVideoTrackId]);
   }
diff --git a/media/base/video_transformation.cc b/media/base/video_transformation.cc
index edfab9d..463c9da 100644
--- a/media/base/video_transformation.cc
+++ b/media/base/video_transformation.cc
@@ -15,6 +15,7 @@
 #include <array>
 #include <cmath>
 
+#include "base/containers/span.h"
 #include "base/logging.h"
 #include "base/notreached.h"
 #include "base/numerics/angle_conversions.h"
@@ -77,7 +78,7 @@
   }
 }
 
-VideoTransformation::VideoTransformation(const int32_t matrix[4]) {
+VideoTransformation::VideoTransformation(base::span<const int32_t, 4> matrix) {
   // Promote to int64_t to avoid abs(int32_min) being undefined.
   const std::array<int64_t, 4> matrix64 = {
       matrix[0],
diff --git a/media/base/video_transformation.h b/media/base/video_transformation.h
index bc63259..49e2c57 100644
--- a/media/base/video_transformation.h
+++ b/media/base/video_transformation.h
@@ -10,6 +10,7 @@
 #include <array>
 #include <string>
 
+#include "base/containers/span.h"
 #include "media/base/media_export.h"
 
 namespace media {
@@ -42,7 +43,7 @@
   // [ sin(Θ),  cos(Θ)]
   // A vertical flip is represented by the cosine's having opposite signs
   // and a horizontal flip is represented by the sine's having the same sign.
-  VideoTransformation(const int32_t matrix[4]);
+  explicit VideoTransformation(base::span<const int32_t, 4> matrix);
 
   // Rotation is snapped to the nearest multiple of 90 degrees, rounding ties
   // toward positive infinity.
diff --git a/media/base/video_transformation_unittest.cc b/media/base/video_transformation_unittest.cc
index 0c0da5e1..2787e07 100644
--- a/media/base/video_transformation_unittest.cc
+++ b/media/base/video_transformation_unittest.cc
@@ -38,42 +38,42 @@
 // }
 TEST_F(VideoTransformationTest, MatrixToVideoTransformation) {
   std::array<int32_t, 4> mat = {65536, 0, 0, 65536};
-  auto t = VideoTransformation(mat.data());
+  auto t = VideoTransformation(mat);
   EXPECT_EQ(t.rotation, VIDEO_ROTATION_0);
   EXPECT_FALSE(t.mirrored);
 
   mat = {-65536, 0, 0, 65536};
-  t = VideoTransformation(mat.data());
+  t = VideoTransformation(mat);
   EXPECT_EQ(t.rotation, VIDEO_ROTATION_0);
   EXPECT_TRUE(t.mirrored);
 
   mat = {0, 65536, -65536, 0};
-  t = VideoTransformation(mat.data());
+  t = VideoTransformation(mat);
   EXPECT_EQ(t.rotation, VIDEO_ROTATION_90);
   EXPECT_FALSE(t.mirrored);
 
   mat = {0, 65536, 65536, 0};
-  t = VideoTransformation(mat.data());
+  t = VideoTransformation(mat);
   EXPECT_EQ(t.rotation, VIDEO_ROTATION_90);
   EXPECT_TRUE(t.mirrored);
 
   mat = {-65536, 0, 0, -65536};
-  t = VideoTransformation(mat.data());
+  t = VideoTransformation(mat);
   EXPECT_EQ(t.rotation, VIDEO_ROTATION_180);
   EXPECT_FALSE(t.mirrored);
 
   mat = {65536, 0, 0, -65536};
-  t = VideoTransformation(mat.data());
+  t = VideoTransformation(mat);
   EXPECT_EQ(t.rotation, VIDEO_ROTATION_180);
   EXPECT_TRUE(t.mirrored);
 
   mat = {0, -65536, 65536, 0};
-  t = VideoTransformation(mat.data());
+  t = VideoTransformation(mat);
   EXPECT_EQ(t.rotation, VIDEO_ROTATION_270);
   EXPECT_FALSE(t.mirrored);
 
   mat = {0, -65536, -65536, 0};
-  t = VideoTransformation(mat.data());
+  t = VideoTransformation(mat);
   EXPECT_EQ(t.rotation, VIDEO_ROTATION_270);
   EXPECT_TRUE(t.mirrored);
 }
@@ -81,36 +81,36 @@
 TEST_F(VideoTransformationTest, ComputeMatrix) {
   // Standard 90 degree increments with no rotation all end up rotated normally
   VideoTransformation transformation = VideoTransformation(VIDEO_ROTATION_0);
-  EXPECT_EQ(VideoTransformation(transformation.GetMatrix().data()),
+  EXPECT_EQ(VideoTransformation(transformation.GetMatrix()),
             VideoTransformation(VIDEO_ROTATION_0, false));
 
   transformation = VideoTransformation(VIDEO_ROTATION_90, false);
-  EXPECT_EQ(VideoTransformation(transformation.GetMatrix().data()),
+  EXPECT_EQ(VideoTransformation(transformation.GetMatrix()),
             VideoTransformation(VIDEO_ROTATION_90, false));
 
   transformation = VideoTransformation(VIDEO_ROTATION_180);
-  EXPECT_EQ(VideoTransformation(transformation.GetMatrix().data()),
+  EXPECT_EQ(VideoTransformation(transformation.GetMatrix()),
             VideoTransformation(VIDEO_ROTATION_180, false));
 
   transformation = VideoTransformation(VIDEO_ROTATION_270);
-  EXPECT_EQ(VideoTransformation(transformation.GetMatrix().data()),
+  EXPECT_EQ(VideoTransformation(transformation.GetMatrix()),
             VideoTransformation(VIDEO_ROTATION_270, false));
 
   // Test the mirrored cases
   transformation = VideoTransformation(VIDEO_ROTATION_0, true);
-  EXPECT_EQ(VideoTransformation(transformation.GetMatrix().data()),
+  EXPECT_EQ(VideoTransformation(transformation.GetMatrix()),
             VideoTransformation(VIDEO_ROTATION_0, true));
 
   transformation = VideoTransformation(VIDEO_ROTATION_90, true);
-  EXPECT_EQ(VideoTransformation(transformation.GetMatrix().data()),
+  EXPECT_EQ(VideoTransformation(transformation.GetMatrix()),
             VideoTransformation(VIDEO_ROTATION_90, true));
 
   transformation = VideoTransformation(VIDEO_ROTATION_180, true);
-  EXPECT_EQ(VideoTransformation(transformation.GetMatrix().data()),
+  EXPECT_EQ(VideoTransformation(transformation.GetMatrix()),
             VideoTransformation(VIDEO_ROTATION_180, true));
 
   transformation = VideoTransformation(VIDEO_ROTATION_270, true);
-  EXPECT_EQ(VideoTransformation(transformation.GetMatrix().data()),
+  EXPECT_EQ(VideoTransformation(transformation.GetMatrix()),
             VideoTransformation(VIDEO_ROTATION_270, true));
 }
 
diff --git a/media/capture/content/smooth_event_sampler_unittest.cc b/media/capture/content/smooth_event_sampler_unittest.cc
index 0d7b1be..44c64ee2 100644
--- a/media/capture/content/smooth_event_sampler_unittest.cc
+++ b/media/capture/content/smooth_event_sampler_unittest.cc
@@ -12,6 +12,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include "base/containers/span.h"
 #include "base/strings/stringprintf.h"
 #include "base/time/time.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -279,11 +280,17 @@
   double increment_ms;
 };
 
-void ReplayCheckingSamplerDecisions(const DataPoint* data_points,
-                                    size_t num_data_points,
-                                    SmoothEventSampler* sampler) {
+void ReplayCheckingSamplerDecisions(
+    base::span<const DataPoint> data_points,
+    size_t spanification_suspected_redundant_num_data_points,
+    SmoothEventSampler* sampler) {
+  // TODO(crbug.com/431824301): Remove unneeded parameter once validated to be
+  // redundant in M143.
+  CHECK(spanification_suspected_redundant_num_data_points == data_points.size(),
+        base::NotFatalUntil::M143);
   base::TimeTicks t = InitialTestTimeTicks();
-  for (size_t i = 0; i < num_data_points; ++i) {
+  for (size_t i = 0; i < spanification_suspected_redundant_num_data_points;
+       ++i) {
     t += base::Microseconds(
         static_cast<int64_t>(data_points[i].increment_ms * 1000));
     ASSERT_EQ(data_points[i].should_capture,
diff --git a/media/capture/video/chromeos/camera_buffer_factory.cc b/media/capture/video/chromeos/camera_buffer_factory.cc
index 34d4835..d87f093 100644
--- a/media/capture/video/chromeos/camera_buffer_factory.cc
+++ b/media/capture/video/chromeos/camera_buffer_factory.cc
@@ -8,7 +8,6 @@
 #include "base/functional/callback_helpers.h"
 #include "components/viz/common/resources/shared_image_format_utils.h"
 #include "gpu/ipc/client/gpu_channel_host.h"
-#include "media/capture/video/chromeos/pixel_format_utils.h"
 #include "media/capture/video/chromeos/video_capture_device_factory_chromeos.h"
 
 namespace media {
@@ -19,7 +18,7 @@
 
 scoped_refptr<gpu::ClientSharedImage> CameraBufferFactory::CreateSharedImage(
     const gfx::Size& size,
-    viz::SharedImageFormat format,
+    gfx::BufferFormat format,
     gfx::BufferUsage usage,
     const gfx::ColorSpace& color_space) {
   auto sii = VideoCaptureDeviceFactoryChromeOS::GetSharedImageInterface();
@@ -43,7 +42,7 @@
   // SharedImages over to the renderer process when feasible (i.e., for non-R8
   // and/or for R8 on devices where it's texturable).
   auto shared_image = sii->CreateSharedImage(
-      {format, size, color_space,
+      {viz::GetSharedImageFormat(format), size, color_space,
        gpu::SharedImageUsageSet(gpu::SHARED_IMAGE_USAGE_CPU_ONLY_READ_WRITE),
        "CameraBufferFactory"},
       gpu::kNullSurfaceHandle, usage);
@@ -57,7 +56,7 @@
 CameraBufferFactory::CreateSharedImageFromGmbHandle(
     gfx::GpuMemoryBufferHandle buffer_handle,
     const gfx::Size& size,
-    viz::SharedImageFormat format,
+    gfx::BufferFormat format,
     gfx::BufferUsage usage,
     const gfx::ColorSpace& color_space) {
   auto sii = VideoCaptureDeviceFactoryChromeOS::GetSharedImageInterface();
@@ -81,7 +80,7 @@
   // SharedImages over to the renderer process when feasible (i.e., for non-R8
   // and/or for R8 on devices where it's texturable).
   auto shared_image = sii->CreateSharedImage(
-      {format, size, color_space,
+      {viz::GetSharedImageFormat(format), size, color_space,
        gpu::SharedImageUsageSet(gpu::SHARED_IMAGE_USAGE_CPU_ONLY_READ_WRITE),
        "CameraBufferFactory"},
       gpu::kNullSurfaceHandle, usage, std::move(buffer_handle));
@@ -102,17 +101,17 @@
     return resolved_format_usages_[key];
   }
 
-  const ChromiumPixelFormat kUnsupportedFormat{
-      PIXEL_FORMAT_UNKNOWN, viz::SinglePlaneFormat::kRGBX_8888};
-  constexpr size_t kDummyBufferWidth = 128, kDummyBufferHeight = 128;
+  ChromiumPixelFormat kUnsupportedFormat{PIXEL_FORMAT_UNKNOWN,
+                                         gfx::BufferFormat::RGBX_8888};
+  size_t kDummyBufferWidth = 128, kDummyBufferHeight = 128;
   std::vector<ChromiumPixelFormat> cr_formats =
-      HalPixelFormatToChromiumPixelFormat(hal_format);
+      PixFormatHalToChromium(hal_format);
   if (cr_formats.empty()) {
     return kUnsupportedFormat;
   }
   for (const auto& f : cr_formats) {
     auto shared_image = CreateSharedImage(
-        gfx::Size(kDummyBufferWidth, kDummyBufferHeight), f.si_format, usage);
+        gfx::Size(kDummyBufferWidth, kDummyBufferHeight), f.gfx_format, usage);
     if (shared_image) {
       resolved_format_usages_[key] = f;
       return f;
diff --git a/media/capture/video/chromeos/camera_buffer_factory.h b/media/capture/video/chromeos/camera_buffer_factory.h
index 762399c..99ec1ca 100644
--- a/media/capture/video/chromeos/camera_buffer_factory.h
+++ b/media/capture/video/chromeos/camera_buffer_factory.h
@@ -8,7 +8,6 @@
 #include <map>
 #include <memory>
 
-#include "components/viz/common/resources/shared_image_format.h"
 #include "media/capture/video/chromeos/mojom/camera3.mojom.h"
 #include "media/capture/video/chromeos/pixel_format_utils.h"
 #include "media/capture/video_capture_types.h"
@@ -30,14 +29,14 @@
 
   virtual scoped_refptr<gpu::ClientSharedImage> CreateSharedImage(
       const gfx::Size& size,
-      viz::SharedImageFormat format,
+      gfx::BufferFormat format,
       gfx::BufferUsage usage,
       const gfx::ColorSpace& color_space = gfx::ColorSpace());
 
   virtual scoped_refptr<gpu::ClientSharedImage> CreateSharedImageFromGmbHandle(
       gfx::GpuMemoryBufferHandle buffer_handle,
       const gfx::Size& size,
-      viz::SharedImageFormat format,
+      gfx::BufferFormat format,
       gfx::BufferUsage usage,
       const gfx::ColorSpace& color_space = gfx::ColorSpace());
 
diff --git a/media/capture/video/chromeos/gpu_memory_buffer_tracker_cros.cc b/media/capture/video/chromeos/gpu_memory_buffer_tracker_cros.cc
index bfa53490..4cd7a02 100644
--- a/media/capture/video/chromeos/gpu_memory_buffer_tracker_cros.cc
+++ b/media/capture/video/chromeos/gpu_memory_buffer_tracker_cros.cc
@@ -8,54 +8,46 @@
 #include "base/notreached.h"
 #include "components/viz/common/resources/shared_image_format_utils.h"
 #include "gpu/command_buffer/client/client_shared_image.h"
-#include "media/base/format_utils.h"
+#include "media/capture/video/chromeos/pixel_format_utils.h"
 #include "media/capture/video/video_capture_buffer_handle.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace media {
 
 GpuMemoryBufferTrackerCros::GpuMemoryBufferTrackerCros() = default;
+
 GpuMemoryBufferTrackerCros::~GpuMemoryBufferTrackerCros() = default;
 
 bool GpuMemoryBufferTrackerCros::Init(const gfx::Size& dimensions,
                                       VideoPixelFormat format,
                                       const mojom::PlaneStridesPtr& strides) {
-  // JPEG capture buffer is backed by R8 pixel buffer.
-  if (format == PIXEL_FORMAT_MJPEG) {
-    shared_image_ = buffer_factory_.CreateSharedImage(
-        dimensions, viz::SinglePlaneFormat::kR_8,
-        gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE);
-    return !!shared_image_;
-  }
-
-  std::optional<viz::SharedImageFormat> si_format =
-      VideoPixelFormatToSharedImageFormat(format);
-  if (!si_format) {
+  std::optional<gfx::BufferFormat> gfx_format = PixFormatVideoToGfx(format);
+  if (!gfx_format) {
     NOTREACHED() << "Unsupported VideoPixelFormat "
                  << VideoPixelFormatToString(format);
   }
   // There's no consumer information here to determine the precise buffer usage,
   // so we try the usage flag that covers all use cases.
-  shared_image_ = buffer_factory_.CreateSharedImage(
-      dimensions, *si_format,
-      gfx::BufferUsage::VEA_READ_CAMERA_AND_CPU_READ_WRITE);
-  return !!shared_image_;
+  // JPEG capture buffer is backed by R8 pixel buffer.
+  const gfx::BufferUsage usage =
+      *gfx_format == gfx::BufferFormat::R_8
+          ? gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE
+          : gfx::BufferUsage::VEA_READ_CAMERA_AND_CPU_READ_WRITE;
+
+  shared_image_ =
+      buffer_factory_.CreateSharedImage(dimensions, *gfx_format, usage);
+  return shared_image_ ? true : false;
 }
 
 bool GpuMemoryBufferTrackerCros::IsReusableForFormat(
     const gfx::Size& dimensions,
     VideoPixelFormat format,
     const mojom::PlaneStridesPtr& strides) {
-  std::optional<viz::SharedImageFormat> si_format =
-      VideoPixelFormatToSharedImageFormat(format);
-  if (!si_format) {
-    if (format == PIXEL_FORMAT_MJPEG) {
-      si_format = viz::SinglePlaneFormat::kR_8;
-    } else {
-      return false;
-    }
+  std::optional<gfx::BufferFormat> gfx_format = PixFormatVideoToGfx(format);
+  if (!gfx_format) {
+    return false;
   }
-  return (*si_format == shared_image_->format() &&
+  return (viz::GetSharedImageFormat(*gfx_format) == shared_image_->format() &&
           dimensions == shared_image_->size());
 }
 
diff --git a/media/capture/video/chromeos/pixel_format_utils.cc b/media/capture/video/chromeos/pixel_format_utils.cc
index 34b1ba94..a273cd0c 100644
--- a/media/capture/video/chromeos/pixel_format_utils.cc
+++ b/media/capture/video/chromeos/pixel_format_utils.cc
@@ -30,16 +30,16 @@
     // capture stream in Chrome VCD as it is mandatory for the camera HAL to
     // support YUV flexbile format video streams.
     {cros::mojom::HalPixelFormat::HAL_PIXEL_FORMAT_YCbCr_420_888,
-     {PIXEL_FORMAT_NV12, viz::MultiPlaneFormat::kNV12}},
+     {PIXEL_FORMAT_NV12, gfx::BufferFormat::YUV_420_BIPLANAR}},
     // FIXME(jcliang): MJPEG is not accurate; we should have BLOB or JPEG
     {cros::mojom::HalPixelFormat::HAL_PIXEL_FORMAT_BLOB,
-     {PIXEL_FORMAT_MJPEG, viz::SinglePlaneFormat::kR_8}},
+     {PIXEL_FORMAT_MJPEG, gfx::BufferFormat::R_8}},
     // Add more mappings when we have more devices.
 };
 
 }  // namespace
 
-std::vector<ChromiumPixelFormat> HalPixelFormatToChromiumPixelFormat(
+std::vector<ChromiumPixelFormat> PixFormatHalToChromium(
     cros::mojom::HalPixelFormat from) {
   std::vector<ChromiumPixelFormat> ret;
   for (const auto& it : kSupportedFormats) {
@@ -62,4 +62,16 @@
   }
 }
 
+std::optional<gfx::BufferFormat> PixFormatVideoToGfx(
+    VideoPixelFormat pixel_format) {
+  switch (pixel_format) {
+    case PIXEL_FORMAT_MJPEG:
+      return gfx::BufferFormat::R_8;
+    case PIXEL_FORMAT_NV12:
+      return gfx::BufferFormat::YUV_420_BIPLANAR;
+    default:
+      return std::nullopt;
+  }
+}
+
 }  // namespace media
diff --git a/media/capture/video/chromeos/pixel_format_utils.h b/media/capture/video/chromeos/pixel_format_utils.h
index 63ab3cb..2d4e079 100644
--- a/media/capture/video/chromeos/pixel_format_utils.h
+++ b/media/capture/video/chromeos/pixel_format_utils.h
@@ -8,29 +8,33 @@
 #include <optional>
 #include <vector>
 
-#include "components/viz/common/resources/shared_image_format.h"
 #include "media/capture/video/chromeos/mojom/camera3.mojom.h"
 #include "media/capture/video_capture_types.h"
+#include "ui/gfx/buffer_types.h"
 
 namespace media {
 
 // A collection of the various pixel formats we need to look up.  We need to
 // resolve the HAL pixel format to VideoPixelFormat for VideoCaptureDevice, and
-// to viz::SharedImageFormat for gpu::GpuMemoryBufferManager.
+// to gfx::BufferFormat for gpu::GpuMemoryBufferManager.
 struct ChromiumPixelFormat {
   VideoPixelFormat video_format;
-  viz::SharedImageFormat si_format;
+  gfx::BufferFormat gfx_format;
 };
 
 // Converts the HAL pixel format |from| to Chromium pixel format.  Returns
 // empty vector if |from| is not supported.
-std::vector<ChromiumPixelFormat> HalPixelFormatToChromiumPixelFormat(
+std::vector<ChromiumPixelFormat> PixFormatHalToChromium(
     cros::mojom::HalPixelFormat from);
 
 // Converts the video pixel format |from| to DRM pixel format.  Returns 0
 // if |from| is not supported.
 uint32_t PixFormatVideoToDrm(VideoPixelFormat from);
 
+// Converts the video pixel format |pixel_format| to gfx::BufferFormat.
+std::optional<gfx::BufferFormat> PixFormatVideoToGfx(
+    VideoPixelFormat pixel_format);
+
 }  // namespace media
 
 #endif  // MEDIA_CAPTURE_VIDEO_CHROMEOS_PIXEL_FORMAT_UTILS_H_
diff --git a/media/capture/video/chromeos/request_manager_unittest.cc b/media/capture/video/chromeos/request_manager_unittest.cc
index 8780411..a77ac2d 100644
--- a/media/capture/video/chromeos/request_manager_unittest.cc
+++ b/media/capture/video/chromeos/request_manager_unittest.cc
@@ -86,15 +86,15 @@
 
   scoped_refptr<gpu::ClientSharedImage> CreateSharedImage(
       const gfx::Size& size,
-      viz::SharedImageFormat format,
+      gfx::BufferFormat format,
       gfx::BufferUsage usage,
       const gfx::ColorSpace& color_space) override {
     // Setting some default usage in order to get a mappable shared image.
     constexpr auto si_usage = gpu::SHARED_IMAGE_USAGE_CPU_WRITE_ONLY |
                               gpu::SHARED_IMAGE_USAGE_DISPLAY_READ;
     auto shared_image = test_sii_->CreateSharedImage(
-        {format, size, color_space, gpu::SharedImageUsageSet(si_usage),
-         "FakeCameraBufferFactory"},
+        {viz::GetSharedImageFormat(format), size, color_space,
+         gpu::SharedImageUsageSet(si_usage), "FakeCameraBufferFactory"},
         gpu::kNullSurfaceHandle, usage);
     if (!shared_image) {
       LOG(ERROR) << "Failed to create shared image.";
@@ -105,7 +105,8 @@
   ChromiumPixelFormat ResolveStreamBufferFormat(
       cros::mojom::HalPixelFormat hal_format,
       gfx::BufferUsage usage) override {
-    return ChromiumPixelFormat{PIXEL_FORMAT_NV12, viz::MultiPlaneFormat::kNV12};
+    return ChromiumPixelFormat{PIXEL_FORMAT_NV12,
+                               gfx::BufferFormat::YUV_420_BIPLANAR};
   }
 
  private:
diff --git a/media/capture/video/chromeos/stream_buffer_manager.cc b/media/capture/video/chromeos/stream_buffer_manager.cc
index fc97745..16d0535 100644
--- a/media/capture/video/chromeos/stream_buffer_manager.cc
+++ b/media/capture/video/chromeos/stream_buffer_manager.cc
@@ -19,7 +19,6 @@
 #include "base/strings/stringprintf.h"
 #include "base/trace_event/trace_event.h"
 #include "gpu/command_buffer/client/client_shared_image.h"
-#include "media/base/format_utils.h"
 #include "media/capture/video/chromeos/camera_buffer_factory.h"
 #include "media/capture/video/chromeos/camera_metadata_utils.h"
 #include "media/capture/video/chromeos/pixel_format_utils.h"
@@ -97,8 +96,9 @@
         gfx::Size(format->frame_size.height(), format->frame_size.width());
   }
 
-  const std::optional<viz::SharedImageFormat> si_format =
-      VideoPixelFormatToSharedImageFormat(format->pixel_format);
+  const std::optional<gfx::BufferFormat> gfx_format =
+      PixFormatVideoToGfx(format->pixel_format);
+  DCHECK(gfx_format);
   const auto& original_shared_image = buffer_pair.shared_image;
   std::unique_ptr<gpu::ClientSharedImage::ScopedMapping>
       original_scoped_mapping;
@@ -171,7 +171,7 @@
   auto rotated_shared_image =
       camera_buffer_factory_->CreateSharedImageFromGmbHandle(
           rotated_buffer.handle_provider->GetGpuMemoryBufferHandle(),
-          format->frame_size, *si_format, stream_context->buffer_usage);
+          format->frame_size, *gfx_format, stream_context->buffer_usage);
   std::unique_ptr<gpu::ClientSharedImage::ScopedMapping> rotated_scoped_mapping;
   if (rotated_shared_image) {
     rotated_scoped_mapping = rotated_shared_image->Map();
@@ -388,10 +388,11 @@
     gfx::GpuMemoryBufferHandle handle,
     const VideoCaptureFormat& format,
     gfx::BufferUsage buffer_usage) {
-  std::optional<viz::SharedImageFormat> si_format =
-      VideoPixelFormatToSharedImageFormat(format.pixel_format);
+  std::optional<gfx::BufferFormat> buffer_format =
+      PixFormatVideoToGfx(format.pixel_format);
+  CHECK(buffer_format);
   auto shared_image = camera_buffer_factory_->CreateSharedImageFromGmbHandle(
-      std::move(handle), format.frame_size, *si_format, buffer_usage);
+      std::move(handle), format.frame_size, *buffer_format, buffer_usage);
   if (!shared_image) {
     LOG(ERROR) << "Failed to create mappable shared image.";
   }
@@ -418,10 +419,9 @@
 
 void StreamBufferManager::ReserveBufferFromFactory(StreamType stream_type) {
   auto& stream_context = stream_context_[stream_type];
-  std::optional<viz::SharedImageFormat> si_format =
-      VideoPixelFormatToSharedImageFormat(
-          stream_context->capture_format.pixel_format);
-  if (!si_format) {
+  std::optional<gfx::BufferFormat> gfx_format =
+      PixFormatVideoToGfx(stream_context->capture_format.pixel_format);
+  if (!gfx_format) {
     device_context_->SetErrorState(
         media::VideoCaptureError::
             kCrosHalV3BufferManagerFailedToCreateMappableSI,
@@ -429,7 +429,7 @@
     return;
   }
   auto shared_image = camera_buffer_factory_->CreateSharedImage(
-      stream_context->buffer_dimension, *si_format,
+      stream_context->buffer_dimension, *gfx_format,
       stream_context->buffer_usage);
   if (!shared_image) {
     device_context_->SetErrorState(
@@ -450,10 +450,9 @@
 
 void StreamBufferManager::ReserveBufferFromPool(StreamType stream_type) {
   auto& stream_context = stream_context_[stream_type];
-  std::optional<viz::SharedImageFormat> si_format =
-      VideoPixelFormatToSharedImageFormat(
-          stream_context->capture_format.pixel_format);
-  if (!si_format) {
+  std::optional<gfx::BufferFormat> gfx_format =
+      PixFormatVideoToGfx(stream_context->capture_format.pixel_format);
+  if (!gfx_format) {
     device_context_->SetErrorState(
         media::VideoCaptureError::
             kCrosHalV3BufferManagerFailedToCreateMappableSI,
@@ -485,7 +484,7 @@
   // converted to create MappableSI.
   auto shared_image = camera_buffer_factory_->CreateSharedImageFromGmbHandle(
       vcd_buffer.handle_provider->GetGpuMemoryBufferHandle(),
-      stream_context->buffer_dimension, *si_format,
+      stream_context->buffer_dimension, *gfx_format,
       stream_context->buffer_usage);
   if (!shared_image) {
     device_context_->SetErrorState(
diff --git a/media/capture/video/file_video_capture_device.cc b/media/capture/video/file_video_capture_device.cc
index 6142cb2..471be32 100644
--- a/media/capture/video/file_video_capture_device.cc
+++ b/media/capture/video/file_video_capture_device.cc
@@ -12,12 +12,14 @@
 #include <stddef.h>
 
 #include <algorithm>
+#include <cstdint>
 #include <memory>
 #include <optional>
 #include <string_view>
 #include <utility>
 
 #include "base/containers/heap_array.h"
+#include "base/containers/span.h"
 #include "base/functional/bind.h"
 #include "base/location.h"
 #include "base/logging.h"
@@ -407,22 +409,23 @@
       VideoFrame::AllocationSize(PIXEL_FORMAT_I420, crop_size);
   std::vector<uint8_t> crop_frame(crop_buffer_size);
 
-  uint8_t* crop_yp = crop_frame.data();
-  uint8_t* crop_up =
-      crop_yp +
-      VideoFrame::PlaneSize(PIXEL_FORMAT_I420, 0, crop_size).GetArea();
+  base::span<uint8_t> crop_yp = crop_frame;
+  base::span<uint8_t> crop_up = crop_yp.subspan(base::checked_cast<size_t>(
+      VideoFrame::PlaneSize(PIXEL_FORMAT_I420, 0, crop_size).GetArea()));
   uint8_t* crop_vp =
-      crop_up +
-      VideoFrame::PlaneSize(PIXEL_FORMAT_I420, 1, crop_size).GetArea();
+      crop_up
+          .subspan(base::checked_cast<size_t>(
+              VideoFrame::PlaneSize(PIXEL_FORMAT_I420, 1, crop_size).GetArea()))
+          .data();
   int crop_yp_stride = crop_width;
   int crop_up_stride = crop_yp_stride / 2;
   int crop_vp_stride = crop_yp_stride / 2;
 
-  if (libyuv::ConvertToI420(frame, frame_buffer_size, crop_yp, crop_yp_stride,
-                            crop_up, crop_up_stride, crop_vp, crop_vp_stride,
-                            crop_x, crop_y, frame_size.width(),
-                            frame_size.height(), crop_width, crop_height,
-                            libyuv::RotationMode::kRotate0, fourcc)) {
+  if (libyuv::ConvertToI420(
+          frame, frame_buffer_size, crop_yp.data(), crop_yp_stride,
+          crop_up.data(), crop_up_stride, crop_vp, crop_vp_stride, crop_x,
+          crop_y, frame_size.width(), frame_size.height(), crop_width,
+          crop_height, libyuv::RotationMode::kRotate0, fourcc)) {
     LOG(ERROR) << "Failed to crop image for ptz transform.";
     return {};
   }
@@ -436,23 +439,25 @@
       VideoFrame::AllocationSize(PIXEL_FORMAT_I420, scale_size);
   std::vector<uint8_t> scale_frame(scale_buffer_size);
 
-  uint8_t* scale_yp = scale_frame.data();
-  uint8_t* scale_up =
-      scale_yp +
-      VideoFrame::PlaneSize(PIXEL_FORMAT_I420, 0, scale_size).GetArea();
+  base::span<uint8_t> scale_yp = scale_frame;
+  base::span<uint8_t> scale_up = scale_yp.subspan(base::checked_cast<size_t>(
+      VideoFrame::PlaneSize(PIXEL_FORMAT_I420, 0, scale_size).GetArea()));
   uint8_t* scale_vp =
-      scale_up +
-      VideoFrame::PlaneSize(PIXEL_FORMAT_I420, 1, scale_size).GetArea();
+      scale_up
+          .subspan(base::checked_cast<size_t>(
+              VideoFrame::PlaneSize(PIXEL_FORMAT_I420, 1, scale_size)
+                  .GetArea()))
+          .data();
   int scale_yp_stride = scale_size.width();
   int scale_up_stride = scale_yp_stride / 2;
   int scale_vp_stride = scale_yp_stride / 2;
 
-  if (libyuv::I420Scale(crop_yp, crop_yp_stride, crop_up, crop_up_stride,
-                        crop_vp, crop_vp_stride, crop_width, crop_height,
-                        scale_yp, scale_yp_stride, scale_up, scale_up_stride,
-                        scale_vp, scale_vp_stride, scale_size.width(),
-                        scale_size.height(),
-                        libyuv::FilterMode::kFilterBilinear)) {
+  if (libyuv::I420Scale(
+          crop_yp.data(), crop_yp_stride, crop_up.data(), crop_up_stride,
+          crop_vp, crop_vp_stride, crop_width, crop_height, scale_yp.data(),
+          scale_yp_stride, scale_up.data(), scale_up_stride, scale_vp,
+          scale_vp_stride, scale_size.width(), scale_size.height(),
+          libyuv::FilterMode::kFilterBilinear)) {
     LOG(ERROR) << "Failed to scale image for ptz transform.";
     return {};
   }
diff --git a/media/capture/video/linux/v4l2_capture_delegate_gpu_helper.cc b/media/capture/video/linux/v4l2_capture_delegate_gpu_helper.cc
index c071fa6..84219da 100644
--- a/media/capture/video/linux/v4l2_capture_delegate_gpu_helper.cc
+++ b/media/capture/video/linux/v4l2_capture_delegate_gpu_helper.cc
@@ -9,6 +9,9 @@
 
 #include "media/capture/video/linux/v4l2_capture_delegate_gpu_helper.h"
 
+#include <cstdint>
+
+#include "base/containers/span.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/trace_event/trace_event.h"
 #include "components/viz/common/resources/shared_image_format.h"
@@ -209,20 +212,26 @@
 
   const size_t i420_size = VideoFrame::AllocationSize(
       VideoPixelFormat::PIXEL_FORMAT_I420, dimensions);
-  i420_buffer_.reserve(i420_size);
+
+  if (i420_buffer_.size() < i420_size) {
+    i420_buffer_.resize(i420_size);
+  }
   if (!i420_buffer_.data()) {
     return -1;
   }
 
-  uint8_t* i420_y = i420_buffer_.data();
-  uint8_t* i420_u =
-      i420_y + VideoFrame::PlaneSize(VideoPixelFormat::PIXEL_FORMAT_I420,
-                                     VideoFrame::Plane::kY, dimensions)
-                   .GetArea();
+  base::span<uint8_t> i420_y = i420_buffer_;
+  base::span<uint8_t> i420_u = i420_y.subspan(base::checked_cast<size_t>(
+      VideoFrame::PlaneSize(VideoPixelFormat::PIXEL_FORMAT_I420,
+                            VideoFrame::Plane::kY, dimensions)
+          .GetArea()));
   uint8_t* i420_v =
-      i420_u + VideoFrame::PlaneSize(VideoPixelFormat::PIXEL_FORMAT_I420,
-                                     VideoFrame::Plane::kU, dimensions)
-                   .GetArea();
+      i420_u
+          .subspan(base::checked_cast<size_t>(
+              VideoFrame::PlaneSize(VideoPixelFormat::PIXEL_FORMAT_I420,
+                                    VideoFrame::Plane::kU, dimensions)
+                  .GetArea()))
+          .data();
   std::vector<size_t> i420_strides = VideoFrame::ComputeStrides(
       VideoPixelFormat::PIXEL_FORMAT_I420, dimensions);
   const int i420_stride_y =
@@ -237,16 +246,16 @@
   const int crop_width = width & ~1;
   const int crop_height = height & ~1;
   int status = libyuv::ConvertToI420(
-      sample, sample_size, i420_y, i420_stride_y, i420_u, i420_stride_u, i420_v,
-      i420_stride_v, 0, 0, width, height, crop_width, crop_height,
-      rotation_mode, fourcc);
+      sample, sample_size, i420_y.data(), i420_stride_y, i420_u.data(),
+      i420_stride_u, i420_v, i420_stride_v, 0, 0, width, height, crop_width,
+      crop_height, rotation_mode, fourcc);
   if (status != 0) {
     return status;
   }
 
-  status = libyuv::I420ToNV12(i420_y, i420_stride_y, i420_u, i420_stride_u,
-                              i420_v, i420_stride_v, dst_y, dst_stride_y,
-                              dst_uv, dst_stride_uv, width, height);
+  status = libyuv::I420ToNV12(
+      i420_y.data(), i420_stride_y, i420_u.data(), i420_stride_u, i420_v,
+      i420_stride_v, dst_y, dst_stride_y, dst_uv, dst_stride_uv, width, height);
 
   return status;
 }
diff --git a/media/capture/video/linux/v4l2_capture_delegate_gpu_helper_unittest.cc b/media/capture/video/linux/v4l2_capture_delegate_gpu_helper_unittest.cc
index c44cf4d..f329daa9 100644
--- a/media/capture/video/linux/v4l2_capture_delegate_gpu_helper_unittest.cc
+++ b/media/capture/video/linux/v4l2_capture_delegate_gpu_helper_unittest.cc
@@ -6,9 +6,11 @@
 // TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
 #pragma allow_unsafe_buffers
 #endif
+
 #include "media/capture/video/linux/v4l2_capture_delegate_gpu_helper.h"
 
 #include "base/command_line.h"
+#include "base/containers/span.h"
 #include "base/test/bind.h"
 #include "base/test/task_environment.h"
 #include "gpu/command_buffer/client/test_shared_image_interface.h"
@@ -207,10 +209,7 @@
 
   if (sample) {
     // corrupt the sample data
-    uint8_t* data = sample->data();
-    for (size_t i = 0; i < 0xff && i < sample->size(); i++) {
-      data[i] = 0xff;
-    }
+    std::fill(sample->begin(), sample->end(), 0xff);
   }
 
   EXPECT_CALL(client, ReserveOutputBuffer)
diff --git a/media/cast/encoding/external_video_encoder.cc b/media/cast/encoding/external_video_encoder.cc
index 9d37ce56..b76042fe 100644
--- a/media/cast/encoding/external_video_encoder.cc
+++ b/media/cast/encoding/external_video_encoder.cc
@@ -16,6 +16,7 @@
 #include <utility>
 
 #include "base/command_line.h"
+#include "base/containers/span.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/logging.h"
@@ -933,8 +934,8 @@
   // Estimate a quantizer value depending on the difference data in the
   // histogram and return it.
   const int num_samples = (size.width() - 1) * rows_in_subset;
-  return ToQuantizerEstimate(ComputeEntropyFromHistogram(
-      histogram.data(), histogram.size(), num_samples));
+  return ToQuantizerEstimate(
+      ComputeEntropyFromHistogram(histogram, histogram.size(), num_samples));
 }
 
 std::optional<double> QuantizerEstimator::EstimateForDeltaFrame(
@@ -979,8 +980,8 @@
   // Estimate a quantizer value depending on the difference data in the
   // histogram and return it.
   const int num_samples = size.width() * rows_in_subset;
-  return ToQuantizerEstimate(ComputeEntropyFromHistogram(
-      histogram.data(), histogram.size(), num_samples));
+  return ToQuantizerEstimate(
+      ComputeEntropyFromHistogram(histogram, histogram.size(), num_samples));
 }
 
 // static
@@ -991,12 +992,18 @@
 }
 
 // static
-double QuantizerEstimator::ComputeEntropyFromHistogram(const int* histogram,
-                                                       size_t histogram_size,
-                                                       int num_samples) {
+double QuantizerEstimator::ComputeEntropyFromHistogram(
+    base::span<const int> histogram,
+    size_t spanification_suspected_redundant_histogram_size,
+    int num_samples) {
+  // TODO(crbug.com/431824301): Remove unneeded parameter once validated to be
+  // redundant in M143.
+  CHECK(spanification_suspected_redundant_histogram_size == histogram.size(),
+        base::NotFatalUntil::M143);
   DCHECK_LT(0, num_samples);
   double entropy = 0.0;
-  for (size_t i = 0; i < histogram_size; ++i) {
+  for (size_t i = 0; i < spanification_suspected_redundant_histogram_size;
+       ++i) {
     const double probability = static_cast<double>(histogram[i]) / num_samples;
     if (probability > 0.0) {
       entropy = entropy - probability * std::log2(probability);
diff --git a/media/cast/encoding/external_video_encoder.h b/media/cast/encoding/external_video_encoder.h
index 1217318b..91d38ac 100644
--- a/media/cast/encoding/external_video_encoder.h
+++ b/media/cast/encoding/external_video_encoder.h
@@ -11,6 +11,7 @@
 #include <memory>
 #include <string_view>
 
+#include "base/containers/span.h"
 #include "base/memory/raw_ref.h"
 #include "base/memory/weak_ptr.h"
 #include "base/task/single_thread_task_runner.h"
@@ -152,9 +153,10 @@
   // Returns a value in the range [0,log2(num_buckets)], the Shannon Entropy
   // based on the probabilities of values falling within each of the buckets of
   // the given |histogram|.
-  static double ComputeEntropyFromHistogram(const int* histogram,
-                                            size_t histogram_size,
-                                            int num_samples);
+  static double ComputeEntropyFromHistogram(
+      base::span<const int> histogram,
+      size_t spanification_suspected_redundant_histogram_size,
+      int num_samples);
 
   // Map the |shannon_entropy| to its corresponding software VP8 quantizer.
   static double ToQuantizerEstimate(double shannon_entropy);
diff --git a/media/cast/openscreen/remoting_proto_utils.cc b/media/cast/openscreen/remoting_proto_utils.cc
index 6332e27e..77585220 100644
--- a/media/cast/openscreen/remoting_proto_utils.cc
+++ b/media/cast/openscreen/remoting_proto_utils.cc
@@ -87,10 +87,13 @@
   buffer_message->set_duration_usec(decoder_buffer.duration().InMicroseconds());
   buffer_message->set_is_key_frame(decoder_buffer.is_key_frame());
 
-  buffer_message->set_front_discard_usec(
-      decoder_buffer.discard_padding().first.InMicroseconds());
-  buffer_message->set_back_discard_usec(
-      decoder_buffer.discard_padding().second.InMicroseconds());
+  auto discard_padding = decoder_buffer.discard_padding();
+  if (discard_padding.has_value()) {
+    buffer_message->set_front_discard_usec(
+        discard_padding->first.InMicroseconds());
+    buffer_message->set_back_discard_usec(
+        discard_padding->second.InMicroseconds());
+  }
 
   if (decoder_buffer.side_data() &&
       !decoder_buffer.side_data()->alpha_data.empty()) {
diff --git a/media/cdm/aes_decryptor_unittest.cc b/media/cdm/aes_decryptor_unittest.cc
index 548aede0..b7941ef 100644
--- a/media/cdm/aes_decryptor_unittest.cc
+++ b/media/cdm/aes_decryptor_unittest.cc
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <string_view>
+
 #ifdef UNSAFE_BUFFERS_BUILD
 // TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
 #pragma allow_unsafe_buffers
 #endif
 
-#include "media/cdm/aes_decryptor.h"
-
 #include <stdint.h>
 
 #include <array>
@@ -17,6 +17,7 @@
 #include <string>
 #include <vector>
 
+#include "base/containers/span.h"
 #include "base/containers/to_vector.h"
 #include "base/debug/leak_annotations.h"
 #include "base/functional/bind.h"
@@ -35,6 +36,7 @@
 #include "media/base/decryptor.h"
 #include "media/base/media_switches.h"
 #include "media/base/mock_filters.h"
+#include "media/cdm/aes_decryptor.h"
 #include "media/media_buildflags.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest-param-test.h"
@@ -201,7 +203,7 @@
     0x09, 0xbb, 0x83, 0x1d, 0x4d, 0x08, 0xd7, 0x78, 0xa4, 0xa7, 0xf1, 0x2e,
 });
 
-const uint8_t kOriginalData2[] = "Changed Original data.";
+const std::string_view kOriginalData2 = "Changed Original data.";
 
 const auto kIv2 = std::to_array<uint8_t>({
     0x00,
@@ -685,13 +687,13 @@
 }
 
 TEST_P(AesDecryptorTest, CreateSessionWithKeyIdsInitData) {
-  const char init_data[] =
+  const std::string_view init_data =
       "{\"kids\":[\"AQI\",\"AQIDBA\",\"AQIDBAUGBwgJCgsMDQ4PEA\"]}";
 
   EXPECT_CALL(cdm_client_, OnSessionMessage(NotEmpty(), _, IsJSONDictionary()));
   cdm_->CreateSessionAndGenerateRequest(
       CdmSessionType::kTemporary, EmeInitDataType::KEYIDS,
-      std::vector<uint8_t>(init_data, init_data + std::size(init_data) - 1),
+      std::vector<uint8_t>(init_data.begin(), init_data.end()),
       CreateSessionPromise(RESOLVED));
 }
 
@@ -783,11 +785,10 @@
           kIv2.data(),
           base::span<const uint8_t>(kIv2).subspan(std::size(kIv2)).data()),
       no_subsample_entries_);
-  ASSERT_NO_FATAL_FAILURE(DecryptAndExpect(
+  UNSAFE_TODO(ASSERT_NO_FATAL_FAILURE(DecryptAndExpect(
       encrypted_buffer,
-      std::vector<uint8_t>(kOriginalData2,
-                           kOriginalData2 + std::size(kOriginalData2) - 1),
-      SUCCESS));
+      std::vector<uint8_t>(kOriginalData2.begin(), kOriginalData2.end()),
+      SUCCESS)));
 }
 
 TEST_P(AesDecryptorTest, CorruptedIv) {
diff --git a/media/cdm/cdm_adapter_unittest.cc b/media/cdm/cdm_adapter_unittest.cc
index 280b37bd..6077b14 100644
--- a/media/cdm/cdm_adapter_unittest.cc
+++ b/media/cdm/cdm_adapter_unittest.cc
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <string_view>
+
 #ifdef UNSAFE_BUFFERS_BUILD
 // TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
 #pragma allow_unsafe_buffers
 #endif
 
-#include "media/cdm/cdm_adapter.h"
-
 #include <stdint.h>
 
 #include <array>
@@ -16,6 +16,7 @@
 
 #include "base/check.h"
 #include "base/command_line.h"
+#include "base/containers/span.h"
 #include "base/functional/bind.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
@@ -29,6 +30,7 @@
 #include "media/base/media_switches.h"
 #include "media/base/mock_filters.h"
 #include "media/cdm/api/content_decryption_module.h"
+#include "media/cdm/cdm_adapter.h"
 #include "media/cdm/cdm_module.h"
 #include "media/cdm/external_clear_key_test_helper.h"
 #include "media/cdm/library_cdm/cdm_host_proxy.h"
@@ -107,7 +109,7 @@
     0x10,
 });
 
-const char kKeyIdAsJWK[] = "{\"kids\": [\"AQIDBAUGBwgJCgsMDQ4PEA\"]}";
+const std::string_view kKeyIdAsJWK = "{\"kids\": [\"AQIDBAUGBwgJCgsMDQ4PEA\"]}";
 
 const auto kKeyIdAsPssh = std::to_array<uint8_t>({
     0x00, 0x00, 0x00, 0x34,                          // size = 52
@@ -454,9 +456,7 @@
 TEST_P(CdmAdapterTestWithClearKeyCdm, CreateKeyIdsSession) {
   InitializeAndExpect(SUCCESS);
 
-  // Don't include the trailing /0 from the string in the data passed in.
-  std::vector<uint8_t> key_id(kKeyIdAsJWK,
-                              kKeyIdAsJWK + std::size(kKeyIdAsJWK) - 1);
+  std::vector<uint8_t> key_id(kKeyIdAsJWK.begin(), kKeyIdAsJWK.end());
   CreateSessionAndExpect(EmeInitDataType::KEYIDS, key_id, SUCCESS);
 }
 
diff --git a/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc b/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc
index 3d7b4021..5a5fdfd 100644
--- a/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc
+++ b/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc
@@ -232,8 +232,14 @@
 
 // Makes sure files and corresponding signature files are readable but not
 // writable.
-bool VerifyCdmHost_0(const cdm::HostFile* host_files, uint32_t num_files) {
-  LOG(WARNING) << __func__ << ": " << num_files;
+bool VerifyCdmHost_0(base::span<const cdm::HostFile> host_files,
+                     uint32_t spanification_suspected_redundant_num_files) {
+  // TODO(crbug.com/431824301): Remove unneeded parameter once validated to be
+  // redundant in M143.
+  CHECK(spanification_suspected_redundant_num_files == host_files.size(),
+        base::NotFatalUntil::M143);
+  LOG(WARNING) << __func__ << ": "
+               << spanification_suspected_redundant_num_files;
 
   // We should always have the CDM and at least one common file.
   // The common CDM host file (e.g. chrome) might not exist since we are running
@@ -243,14 +249,15 @@
   // We should always have the CDM.
   const int kNumCdmFiles = 1;
 
-  if (num_files < kMinNumHostFiles) {
-    LOG(ERROR) << "Too few host files: " << num_files;
+  if (spanification_suspected_redundant_num_files < kMinNumHostFiles) {
+    LOG(ERROR) << "Too few host files: "
+               << spanification_suspected_redundant_num_files;
     g_verify_host_files_result = false;
     return true;
   }
 
   int num_opened_files = 0;
-  for (uint32_t i = 0; i < num_files; ++i) {
+  for (uint32_t i = 0; i < spanification_suspected_redundant_num_files; ++i) {
     const int kBytesToRead = 10;
     std::vector<char> buffer(kBytesToRead);
 
diff --git a/media/filters/audio_renderer_algorithm.cc b/media/filters/audio_renderer_algorithm.cc
index f74d59b..2adf083 100644
--- a/media/filters/audio_renderer_algorithm.cc
+++ b/media/filters/audio_renderer_algorithm.cc
@@ -12,6 +12,7 @@
 #include <algorithm>
 #include <cmath>
 
+#include "base/containers/span.h"
 #include "base/functional/bind.h"
 #include "base/logging.h"
 #include "base/memory/raw_ptr.h"
@@ -524,7 +525,8 @@
     if (!channel_mask_[k])
       continue;
 
-    const float* const ch_opt_frame = optimal_block_->channel_span(k).data();
+    const base::span<const float> ch_opt_frame =
+        optimal_block_->channel_span(k);
     float* ch_output =
         wsola_output_->channel_span(k).data() + num_complete_frames_;
     for (int n = 0; n < ola_hop_size_; ++n) {
@@ -534,7 +536,7 @@
 
     // Copy the second half to the output.
     memcpy(&ch_output[ola_hop_size_], &ch_opt_frame[ola_hop_size_],
-           sizeof(*ch_opt_frame) * ola_hop_size_);
+           sizeof(ch_opt_frame[0]) * ola_hop_size_);
   }
 
   num_complete_frames_ += ola_hop_size_;
@@ -583,8 +585,10 @@
   for (int k = 0; k < channels_; ++k) {
     if (!channel_mask_[k])
       continue;
-    float* ch = wsola_output_->channel_span(k).data();
-    memmove(ch, &ch[rendered_frames], sizeof(*ch) * frames_to_move);
+    base::span<float> ch = wsola_output_->channel_span(k);
+    memmove(ch.data(),
+            ch.subspan(base::checked_cast<size_t>(rendered_frames)).data(),
+            sizeof(ch[0]) * frames_to_move);
   }
   num_complete_frames_ -= rendered_frames;
   return rendered_frames;
@@ -639,8 +643,8 @@
     for (int k = 0; k < channels_; ++k) {
       if (!channel_mask_[k])
         continue;
-      float* ch_opt = optimal_block_->channel_span(k).data();
-      const float* const ch_target = target_block_->channel_span(k).data();
+      base::span<float> ch_opt = optimal_block_->channel_span(k);
+      const base::span<const float> ch_target = target_block_->channel_span(k);
       for (int n = 0; n < ola_window_size_; ++n) {
         ch_opt[n] = ch_opt[n] * transition_window_[n] +
                     ch_target[n] * transition_window_[ola_window_size_ + n];
diff --git a/media/filters/audio_timestamp_validator.cc b/media/filters/audio_timestamp_validator.cc
index 11cb61a..d6365ffd3 100644
--- a/media/filters/audio_timestamp_validator.cc
+++ b/media/filters/audio_timestamp_validator.cc
@@ -52,9 +52,11 @@
   // If audio_base_ts_ == kNoTimestamp, we are processing our first buffer.
   // If stream has neither codec delay nor discard padding, we should expect
   // timestamps and output durations to line up from the start (i.e. be stable).
+  auto discard_padding = buffer.discard_padding();
   if (audio_base_ts_ == kNoTimestamp && !has_codec_delay_ &&
-      buffer.discard_padding().first == base::TimeDelta() &&
-      buffer.discard_padding().second == base::TimeDelta()) {
+      (!discard_padding.has_value() ||
+       (discard_padding->first == base::TimeDelta() &&
+        discard_padding->second == base::TimeDelta()))) {
     DVLOG(3) << __func__ << " Expecting stable timestamps - stream has neither "
              << "codec delay nor discard padding.";
     limit_unstable_audio_tries_ = 0;
diff --git a/media/filters/blocking_url_protocol.cc b/media/filters/blocking_url_protocol.cc
index d76e7b32..d026bfd 100644
--- a/media/filters/blocking_url_protocol.cc
+++ b/media/filters/blocking_url_protocol.cc
@@ -11,6 +11,8 @@
 
 #include <stddef.h>
 
+#include <array>
+
 #include "base/functional/bind.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/threading/thread_restrictions.h"
@@ -70,11 +72,12 @@
                                       base::Unretained(this)));
   }
 
-  base::WaitableEvent* events[] = { &aborted_, &read_complete_ };
+  auto events =
+      std::to_array<base::WaitableEvent*>({&aborted_, &read_complete_});
   size_t index;
   {
     base::ScopedAllowBaseSyncPrimitives allow_base_sync_primitives;
-    index = base::WaitableEvent::WaitMany(events, std::size(events));
+    index = base::WaitableEvent::WaitMany(events.data(), std::size(events));
   }
 
   if (events[index] == &aborted_)
diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc
index efd6f7bf..9ee5adb 100644
--- a/media/filters/chunk_demuxer_unittest.cc
+++ b/media/filters/chunk_demuxer_unittest.cc
@@ -14,15 +14,18 @@
 
 #include <algorithm>
 #include <array>
+#include <cstdint>
 #include <memory>
 #include <queue>
 #include <utility>
 
 #include "base/command_line.h"
 #include "base/containers/heap_array.h"
+#include "base/containers/span.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/memory/raw_ptr.h"
+#include "base/numerics/safe_conversions.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
@@ -73,10 +76,24 @@
     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // cues(size = 0)
 };
 
-const uint8_t kEncryptedMediaInitData[] = {
-    0x68, 0xFE, 0xF9, 0xA1, 0xB3, 0x0D, 0x6B, 0x4D,
-    0xF2, 0x22, 0xB5, 0x0B, 0x4D, 0xE9, 0xE9, 0x95,
-};
+const auto kEncryptedMediaInitData = std::to_array<uint8_t>({
+    0x68,
+    0xFE,
+    0xF9,
+    0xA1,
+    0xB3,
+    0x0D,
+    0x6B,
+    0x4D,
+    0xF2,
+    0x22,
+    0xB5,
+    0x0B,
+    0x4D,
+    0xE9,
+    0xE9,
+    0x95,
+});
 
 const int kTracksHeaderSize = sizeof(kTracksHeader);
 const int kTracksSizeOffset = 4;
@@ -118,7 +135,7 @@
 // Write an integer into buffer in the form of vint that spans 8 bytes.
 // The data pointed by |buffer| should be at least 8 bytes long.
 // |number| should be in the range 0 <= number < 0x00FFFFFFFFFFFFFF.
-static void WriteInt64(uint8_t* buffer, int64_t number) {
+static void WriteInt64(base::span<uint8_t> buffer, int64_t number) {
   DCHECK(number >= 0 && number < 0x00FFFFFFFFFFFFFFLL);
   buffer[0] = 0x01;
   int64_t tmp = number;
@@ -304,55 +321,56 @@
 
     *buffer = base::HeapArray<uint8_t>::Uninit(size);
 
-    uint8_t* buf = buffer->data();
+    base::span<uint8_t> buf = *buffer;
     auto ebml_header_span = base::span(*ebml_header);
-    memcpy(buf, ebml_header_span.data(), ebml_header_span.size());
-    buf += ebml_header_span.size();
+    buf.copy_prefix_from(ebml_header_span);
+    buf = buf.subspan(ebml_header_span.size());
 
     auto info_span = base::span(*info);
-    memcpy(buf, info_span.data(), info_span.size());
-    buf += info_span.size();
+    buf.copy_prefix_from(info_span);
+    buf = buf.subspan(info_span.size());
 
-    memcpy(buf, kTracksHeader, kTracksHeaderSize);
-    WriteInt64(buf + kTracksSizeOffset, tracks_element_size);
-    buf += kTracksHeaderSize;
+    buf.copy_prefix_from(kTracksHeader);
+    WriteInt64(buf.subspan(base::checked_cast<size_t>(kTracksSizeOffset)),
+               tracks_element_size);
+    buf = buf.subspan(base::checked_cast<size_t>(kTracksHeaderSize));
 
     // TODO(xhwang): Simplify this! Probably have test data files that contain
     // ContentEncodings directly instead of trying to create one at run-time.
     if (has_video) {
       auto video_track_entry_span = base::span(*video_track_entry);
-      memcpy(buf, video_track_entry_span.data(), video_track_entry_span.size());
+      buf.copy_prefix_from(video_track_entry_span);
       if (is_video_encrypted) {
         auto video_content_encodings_span =
             base::span(*video_content_encodings);
-        memcpy(buf + video_track_entry_span.size(),
-               video_content_encodings_span.data(),
-               video_content_encodings_span.size());
-        WriteInt64(buf + kVideoTrackSizeOffset,
-                   video_track_entry_span.size() +
-                       video_content_encodings_span.size() -
-                       kVideoTrackEntryHeaderSize);
-        buf += video_content_encodings_span.size();
+        buf.subspan(video_track_entry_span.size())
+            .copy_prefix_from(video_content_encodings_span);
+        WriteInt64(
+            buf.subspan(base::checked_cast<size_t>(kVideoTrackSizeOffset)),
+            video_track_entry_span.size() +
+                video_content_encodings_span.size() -
+                kVideoTrackEntryHeaderSize);
+        buf = buf.subspan(video_content_encodings_span.size());
       }
-      buf += video_track_entry_span.size();
+      buf = buf.subspan(video_track_entry_span.size());
     }
 
     if (has_audio) {
       auto audio_track_entry_span = base::span(*audio_track_entry);
-      memcpy(buf, audio_track_entry_span.data(), audio_track_entry_span.size());
+      buf.copy_prefix_from(audio_track_entry_span);
       if (is_audio_encrypted) {
         auto audio_content_encodings_span =
             base::span(*audio_content_encodings);
-        memcpy(buf + audio_track_entry_span.size(),
-               audio_content_encodings_span.data(),
-               audio_content_encodings_span.size());
-        WriteInt64(buf + kAudioTrackSizeOffset,
-                   audio_track_entry_span.size() +
-                       audio_content_encodings_span.size() -
-                       kAudioTrackEntryHeaderSize);
-        buf += audio_content_encodings_span.size();
+        buf.subspan(audio_track_entry_span.size())
+            .copy_prefix_from(audio_content_encodings_span);
+        WriteInt64(
+            buf.subspan(base::checked_cast<size_t>(kAudioTrackSizeOffset)),
+            audio_track_entry_span.size() +
+                audio_content_encodings_span.size() -
+                kAudioTrackEntryHeaderSize);
+        buf = buf.subspan(audio_content_encodings_span.size());
       }
-      buf += audio_track_entry_span.size();
+      buf = buf.subspan(audio_track_entry_span.size());
     }
   }
 
@@ -775,12 +793,15 @@
 
       int need_key_count =
           (is_audio_encrypted ? 1 : 0) + (is_video_encrypted ? 1 : 0);
-      EXPECT_CALL(*this, OnEncryptedMediaInitData(
-                             EmeInitDataType::WEBM,
-                             std::vector<uint8_t>(
-                                 kEncryptedMediaInitData,
-                                 kEncryptedMediaInitData +
-                                     std::size(kEncryptedMediaInitData))))
+
+      EXPECT_CALL(*this,
+                  OnEncryptedMediaInitData(
+                      EmeInitDataType::WEBM,
+                      std::vector<uint8_t>(
+                          kEncryptedMediaInitData.data(),
+                          base::span(kEncryptedMediaInitData)
+                              .subspan(std::size(kEncryptedMediaInitData))
+                              .data())))
           .Times(Exactly(need_key_count));
     }
 
@@ -1211,8 +1232,10 @@
 
       // Handle preroll buffers.
       if (base::EndsWith(timestamps[i], "P", base::CompareCase::SENSITIVE)) {
-        ASSERT_EQ(kInfiniteDuration, buffers[0]->discard_padding().first);
-        ASSERT_EQ(base::TimeDelta(), buffers[0]->discard_padding().second);
+        auto discard_padding = buffers[0]->discard_padding();
+        ASSERT_TRUE(discard_padding.has_value());
+        ASSERT_EQ(kInfiniteDuration, discard_padding->first);
+        ASSERT_EQ(base::TimeDelta(), discard_padding->second);
         ss << "P";
       }
     }
@@ -1234,13 +1257,13 @@
   //    shouldn't be made on that iteration of the loop. If both streams have
   //    a kSkip then the loop will terminate.
   bool ParseWebMFile(const std::string& filename,
-                     const BufferTimestamps* timestamps,
+                     base::span<const BufferTimestamps> timestamps,
                      const base::TimeDelta& duration) {
     return ParseWebMFile(filename, timestamps, duration, HAS_AUDIO | HAS_VIDEO);
   }
 
   bool ParseWebMFile(const std::string& filename,
-                     const BufferTimestamps* timestamps,
+                     base::span<const BufferTimestamps> timestamps,
                      const base::TimeDelta& duration,
                      int stream_flags) {
     EXPECT_CALL(*this, DemuxerOpened());
@@ -2087,15 +2110,15 @@
   size_t buffer_size =
       info_tracks.size() + cluster_a->bytes_used() + cluster_b->bytes_used();
   auto buffer = base::HeapArray<uint8_t>::Uninit(buffer_size);
-  uint8_t* dst = buffer.data();
-  memcpy(dst, info_tracks.data(), info_tracks.size());
-  dst += info_tracks.size();
+  base::span<uint8_t> dst = buffer;
+  memcpy(dst.data(), info_tracks.data(), info_tracks.size());
+  dst = dst.subspan(info_tracks.size());
 
-  memcpy(dst, cluster_a->data(), cluster_a->bytes_used());
-  dst += cluster_a->bytes_used();
+  memcpy(dst.data(), cluster_a->data(), cluster_a->bytes_used());
+  dst = dst.subspan(base::checked_cast<size_t>(cluster_a->bytes_used()));
 
-  memcpy(dst, cluster_b->data(), cluster_b->bytes_used());
-  dst += cluster_b->bytes_used();
+  memcpy(dst.data(), cluster_b->data(), cluster_b->bytes_used());
+  dst = dst.subspan(base::checked_cast<size_t>(cluster_b->bytes_used()));
 
   ExpectInitMediaLogs(HAS_AUDIO | HAS_VIDEO);
   EXPECT_CALL(*this, InitSegmentReceivedMock(_));
diff --git a/media/filters/decoder_stream_traits.cc b/media/filters/decoder_stream_traits.cc
index df9e6a4..0e65504c 100644
--- a/media/filters/decoder_stream_traits.cc
+++ b/media/filters/decoder_stream_traits.cc
@@ -255,9 +255,10 @@
   }
 
   frame_metadata_[buffer.timestamp()] = {
-      buffer.discard_padding().first == kInfiniteDuration,  // should_drop
-      buffer.duration(),                                    // duration
-      base::TimeTicks::Now(),                               // decode_begin_time
+      buffer.discard_padding().has_value() &&
+          buffer.discard_padding()->first == kInfiniteDuration,  // should_drop
+      buffer.duration(),                                         // duration
+      base::TimeTicks::Now(),  // decode_begin_time
   };
 
   if (!buffer.is_key_frame())
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc
index b7a6882..207f236 100644
--- a/media/filters/ffmpeg_demuxer.cc
+++ b/media/filters/ffmpeg_demuxer.cc
@@ -553,7 +553,7 @@
   // don't want to overwrite any existing discard padding since the discard
   // padding may refer to frames beyond this packet.
   if (packet->flags & AV_PKT_FLAG_DISCARD &&
-      buffer->discard_padding() == DecoderBuffer::DiscardPadding()) {
+      !buffer->discard_padding().has_value()) {
     buffer->set_discard_padding(
         std::make_pair(kInfiniteDuration, base::TimeDelta()));
   }
@@ -563,7 +563,10 @@
     // discarded after decoding.
     if (buffer->timestamp().is_negative()) {
       // Discard padding may also remove samples after zero.
-      auto fixed_ts = buffer->discard_padding().first + buffer->timestamp();
+      auto discard_padding = buffer->discard_padding();
+      auto fixed_ts = (discard_padding.has_value() ? discard_padding->first
+                                                   : base::TimeDelta()) +
+                      buffer->timestamp();
 
       // Allow for rounding error in the discard padding calculations.
       if (fixed_ts == base::Microseconds(-1)) {
@@ -592,20 +595,27 @@
         buffer->duration() != kNoTimestamp &&
         !audio_decoder_config().codec_delay()) {
       if ((stream_timestamp + buffer->duration()).is_negative()) {
-        DCHECK_EQ(buffer->discard_padding().second, base::TimeDelta());
+        auto discard_padding = buffer->discard_padding();
+        DCHECK(!discard_padding.has_value() ||
+               discard_padding->second == base::TimeDelta());
 
         // Discard the entire packet if it's entirely before zero, but don't
         // override the discard padding if it refers to frames beyond this
         // packet.
-        if (buffer->discard_padding().first <= buffer->duration()) {
+        if (!discard_padding.has_value() ||
+            discard_padding->first <= buffer->duration()) {
           buffer->set_discard_padding(
               std::make_pair(kInfiniteDuration, base::TimeDelta()));
         }
       } else {
         // Only discard part of the frame if it overlaps zero.
+        auto discard_padding = buffer->discard_padding();
         buffer->set_discard_padding(std::make_pair(
-            std::max(-stream_timestamp, buffer->discard_padding().first),
-            buffer->discard_padding().second));
+            std::max(-stream_timestamp, discard_padding.has_value()
+                                            ? discard_padding->first
+                                            : base::TimeDelta()),
+            discard_padding.has_value() ? discard_padding->second
+                                        : base::TimeDelta()));
       }
     }
   }
@@ -656,7 +666,11 @@
     return;
   }
 
-  const auto [start_padding, end_padding] = buffer->discard_padding();
+  auto discard_padding = buffer->discard_padding();
+  auto start_padding =
+      discard_padding.has_value() ? discard_padding->first : base::TimeDelta();
+  auto end_padding =
+      discard_padding.has_value() ? discard_padding->second : base::TimeDelta();
 
   // Save the timestamp of the first non-discarded frame, to calculate duration
   // below. Only the first buffer should have discard padding.
diff --git a/media/filters/ffmpeg_demuxer_unittest.cc b/media/filters/ffmpeg_demuxer_unittest.cc
index 9a01f3a..817de9f 100644
--- a/media/filters/ffmpeg_demuxer_unittest.cc
+++ b/media/filters/ffmpeg_demuxer_unittest.cc
@@ -92,10 +92,24 @@
                std::string(stream_type) + " track");
 }
 
-const uint8_t kEncryptedMediaInitData[] = {
-    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-    0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-};
+const auto kEncryptedMediaInitData = std::to_array<uint8_t>({
+    0x30,
+    0x31,
+    0x32,
+    0x33,
+    0x34,
+    0x35,
+    0x36,
+    0x37,
+    0x38,
+    0x39,
+    0x30,
+    0x31,
+    0x32,
+    0x33,
+    0x34,
+    0x35,
+});
 
 static void EosOnReadDone(bool* got_eos_buffer,
                           base::OnceClosure quit_closure,
@@ -224,8 +238,10 @@
       EXPECT_EQ(read_expectation.size, buffer->size());
       EXPECT_EQ(read_expectation.timestamp_us,
                 buffer->timestamp().InMicroseconds());
+      auto discard_padding = buffer->discard_padding();
       EXPECT_EQ(read_expectation.discard_front_padding,
-                buffer->discard_padding().first);
+                discard_padding.has_value() ? discard_padding->first
+                                            : base::TimeDelta());
       EXPECT_EQ(read_expectation.is_key_frame, buffer->is_key_frame());
     }
     OnReadDoneCalled(read_expectation.size, read_expectation.timestamp_us);
@@ -515,12 +531,13 @@
 #endif
 
 TEST_F(FFmpegDemuxerTest, Initialize_Encrypted) {
-  EXPECT_CALL(*this,
-              OnEncryptedMediaInitData(
-                  EmeInitDataType::WEBM,
-                  std::vector<uint8_t>(kEncryptedMediaInitData,
-                                       kEncryptedMediaInitData +
-                                           std::size(kEncryptedMediaInitData))))
+  EXPECT_CALL(*this, OnEncryptedMediaInitData(
+                         EmeInitDataType::WEBM,
+                         std::vector<uint8_t>(
+                             kEncryptedMediaInitData.data(),
+                             base::span(kEncryptedMediaInitData)
+                                 .subspan(std::size(kEncryptedMediaInitData))
+                                 .data())))
       .Times(Exactly(2));
 
   CreateDemuxer("bear-320x240-av_enc-av.webm");
@@ -858,8 +875,9 @@
                       [&](DemuxerStream::Status status,
                           DemuxerStream::DecoderBufferVector buffers) {
                         for (const auto& buffer : buffers) {
-                          EXPECT_EQ(buffer->discard_padding().first,
-                                    kInfiniteDuration);
+                          auto discard_padding = buffer->discard_padding();
+                          EXPECT_TRUE(discard_padding.has_value());
+                          EXPECT_EQ(discard_padding->first, kInfiniteDuration);
                         }
                         run_loop.QuitWhenIdle();
                       }));
diff --git a/media/filters/frame_processor.cc b/media/filters/frame_processor.cc
index 754a2c9..addcf0b7 100644
--- a/media/filters/frame_processor.cc
+++ b/media/filters/frame_processor.cc
@@ -709,8 +709,10 @@
     // Mark the overlapping portion of the buffer for discard.
     // TODO(wolenetz): Is this correct to ignore any pre-existing discard
     // padding (e.g. WebM discard padding)? See https://crbug.com/969195.
+    auto existing_discard = buffer->discard_padding();
     buffer->set_discard_padding(
-        std::make_pair(buffer->discard_padding().first,
+        std::make_pair(existing_discard.has_value() ? existing_discard->first
+                                                    : base::TimeDelta(),
                        frame_end_timestamp - append_window_end));
 
     // Decrease the duration of the buffer to remove the discarded portion.
diff --git a/media/filters/frame_processor_unittest.cc b/media/filters/frame_processor_unittest.cc
index 1f23509..d599065 100644
--- a/media/filters/frame_processor_unittest.cc
+++ b/media/filters/frame_processor_unittest.cc
@@ -343,8 +343,10 @@
         ss << ":" << original_time_in_ms;
 
       // Detect full-discard preroll buffer.
-      if (last_read_buffer_->discard_padding().first == kInfiniteDuration &&
-          last_read_buffer_->discard_padding().second.is_zero()) {
+      auto discard_padding = last_read_buffer_->discard_padding();
+      if (discard_padding.has_value() &&
+          discard_padding->first == kInfiniteDuration &&
+          discard_padding->second.is_zero()) {
         ss << "P";
       }
 
diff --git a/media/filters/h26x_annex_b_bitstream_builder_unittest.cc b/media/filters/h26x_annex_b_bitstream_builder_unittest.cc
index 2eabf37..7c8b094e 100644
--- a/media/filters/h26x_annex_b_bitstream_builder_unittest.cc
+++ b/media/filters/h26x_annex_b_bitstream_builder_unittest.cc
@@ -7,10 +7,13 @@
 #pragma allow_unsafe_buffers
 #endif
 
+#include "media/filters/h26x_annex_b_bitstream_builder.h"
+
 #include <stdint.h>
 
 #include "base/bits.h"
-#include "media/filters/h26x_annex_b_bitstream_builder.h"
+#include "base/containers/auto_spanification_helper.h"
+#include "base/containers/span.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace media {
@@ -18,16 +21,16 @@
 namespace {
 const uint64_t kTestPattern = 0xfedcba0987654321;
 
-uint64_t GetDataFromBuffer(const uint8_t* ptr, uint64_t num_bits) {
+uint64_t GetDataFromBuffer(base::span<const uint8_t> ptr, uint64_t num_bits) {
   uint64_t got = 0;
   while (num_bits > 8) {
-    got |= (*ptr & 0xff);
+    got |= (ptr[0] & 0xff);
     num_bits -= 8;
     got <<= (num_bits > 8 ? 8 : num_bits);
-    ptr++;
+    base::PostIncrementSpan(ptr);
   }
   if (num_bits > 0) {
-    uint64_t temp = (*ptr & 0xff);
+    uint64_t temp = (ptr[0] & 0xff);
     temp >>= (8 - num_bits);
     got |= temp;
   }
@@ -52,7 +55,7 @@
 
   EXPECT_EQ(b.BytesInBuffer(), num_bytes);
 
-  const uint8_t* ptr = b.data().data();
+  base::span<const uint8_t> ptr = b.data();
   uint64_t got = GetDataFromBuffer(ptr, num_bits);
   uint64_t expected = kTestPattern;
 
@@ -73,7 +76,7 @@
   EXPECT_EQ(b.BytesInBuffer(), num_bytes);
   EXPECT_EQ(b.BitsInBuffer(), num_bits);
 
-  const uint8_t* ptr = b.data().data();
+  base::span<const uint8_t> ptr = b.data();
   uint64_t got = GetDataFromBuffer(ptr, num_bits);
   uint64_t expected = kTestPattern;
   expected &= ((1ull << num_bits) - 1);
diff --git a/media/filters/hls_manifest_demuxer_engine_unittest.cc b/media/filters/hls_manifest_demuxer_engine_unittest.cc
index b843c90..61769d8 100644
--- a/media/filters/hls_manifest_demuxer_engine_unittest.cc
+++ b/media/filters/hls_manifest_demuxer_engine_unittest.cc
@@ -517,15 +517,12 @@
 
   EXPECT_CALL(*mock_mdeh_, GetBufferedRanges(_))
       .WillOnce(Return(Ranges<base::TimeDelta>()))  // First CheckState
-      .WillOnce(Return(Ranges<base::TimeDelta>()))  // Before appending A
       .WillOnce(Return(after_seg_a))                // After appending segment A
       .WillOnce(Return(after_seg_a))                // Second CheckState
-      .WillOnce(Return(after_seg_a))                // Before appending B
       .WillOnce(Return(after_seg_b))                // After appending segment B
       .WillOnce(Return(after_seg_b))                // MediaLog
       .WillOnce(Return(after_seg_b))                // Third CheckState
       .WillOnce(Return(after_seg_b))                // Fourth CheckState
-      .WillOnce(Return(after_seg_b))                // Before appending C
       .WillOnce(Return(after_seg_c))                // After appending segment C
       .WillOnce(Return(after_seg_c))                // MediaLog
       .WillOnce(Return(after_seg_c))                // Fifth CheckState
@@ -955,13 +952,12 @@
 
   // `GetBufferedRanges` gets called many times during this process:
   // - HlsVodRendition::CheckState (1) => empty ranges, nothing loaded.
-  // - HlsVodRendition::OnSegmentData (2) => populated by AppendAndParseData
+  // - HlsVodRendition::OnSegmentData (1) => populated by AppendAndParseData
   // - HlsVodRendition::CheckState (2) => still has data
   Ranges<base::TimeDelta> populated_ranges;
   populated_ranges.Add(base::Seconds(0), base::Seconds(5));
   EXPECT_CALL(*mock_mdeh_, GetBufferedRanges(_))
       .WillOnce(Return(Ranges<base::TimeDelta>()))
-      .WillOnce(Return(Ranges<base::TimeDelta>()))
       .WillOnce(Return(populated_ranges))
       .WillOnce(Return(populated_ranges));
 
diff --git a/media/filters/hls_rendition_impl.cc b/media/filters/hls_rendition_impl.cc
index dc26f99..dca6d00 100644
--- a/media/filters/hls_rendition_impl.cc
+++ b/media/filters/hls_rendition_impl.cc
@@ -144,49 +144,14 @@
     return;
   }
 
-  // If media time is inside the first loaded range, things are OK.
-  // If it comes inside the first `gapless_playback_seek_skip_` or inside the
-  // second loaded range, we've probably hit one of those annoying muxing
-  // issues where we need to seek ahead. See crbug.com/429060503 for more
-  // information.
-  if (ranges.contains(0, media_time)) {
-    // The media time is already buffered. The buffer checks and below will
-    // decide what to do about this.
-  } else if (gapless_playback_seek_skip_.size()) {
-    // There should always be one more range than gaps between ranges, for
-    // obvious reasons.
-    DCHECK_EQ(ranges.size(), gapless_playback_seek_skip_.size() + 1);
-
-    if (gapless_playback_seek_skip_.contains(0, media_time) ||
-        ranges.contains(1, media_time)) {
-      // Seeking into a loaded range won't drop anything, so do it here, and
-      // drop the gapless ranges to match it.
-      engine_host_->Remove(role_, base::TimeDelta(),
-                           gapless_playback_seek_skip_.start(0));
-      gapless_playback_seek_skip_.pop_front();
-      ranges = engine_host_->GetBufferedRanges(role_);
-      if (ranges.size()) {
-        engine_host_->RequestSeek(ranges.start(0));
-        std::move(time_remaining_cb).Run(kNoTimestamp);
-        return;
-      }
-    }
-
-    // Media time wasn't in an expected place - this is probably caused by a
-    // really bad muxing situation with lots of dropped frames all close to
-    // each other. This probably isn't worth trying to play.
+  // If media time comes before the last loaded range, then a seek probably
+  // failed, and we should raise an error.
+  if (std::get<0>(ranges.back()) > media_time) {
     HlsDemuxerStatus error = HlsDemuxerStatus::Codes::kInvalidLoadedRanges;
     rendition_host_->Quit(std::move(error)
                               .WithData("timestamp", media_time)
-                              .WithData("ranges", ranges));
-    return;
-  } else if (std::get<0>(ranges.back()) > media_time) {
-    // All loaded ranges are ahead of us, which means there was probably a
-    // failed seek.
-    HlsDemuxerStatus error = HlsDemuxerStatus::Codes::kInvalidLoadedRanges;
-    rendition_host_->Quit(std::move(error)
-                              .WithData("timestamp", media_time)
-                              .WithData("ranges", ranges));
+                              .WithData("range_start", ranges.back().first)
+                              .WithData("range_end", ranges.back().second));
     return;
   }
 
@@ -518,10 +483,6 @@
                                    &parse_offset_);
   }
 
-  // Sometimes slight muxing errors can introduce a very small gap in playback
-  // which we will need to seek over, like a normal MSE player.
-  auto ranges_size_pre_append = engine_host_->GetBufferedRanges(role_).size();
-
   if (!engine_host_->AppendAndParseData(role_, parse_end + base::Seconds(1),
                                         &parse_offset_, stream_data)) {
     rendition_host_->Quit(HlsDemuxerStatus::Codes::kCouldNotAppendData);
@@ -546,32 +507,7 @@
   auto ranges = engine_host_->GetBufferedRanges(role_);
   media_log_->SetProperty<MediaLogProperty::kHlsBufferedRanges>(ranges);
 
-  // This append/parse has added a playback gap! This is likely caused by a
-  // bad timestamp on a frame or some other muxing error. If the gap is small,
-  // it's probably OK to just skip over it.
-  auto last_end = ranges.size() ? ranges.start(0) : base::Seconds(0);
-  bool contains_required_time = false;
-  for (size_t i = 0; i < ranges.size(); i++) {
-    auto gap = ranges.start(i) - last_end;
-    contains_required_time |= ranges.contains(i, required_time);
-    if (gap.is_zero()) {
-      // The first group has a "gap" of zero, and shouldn't do these checks.
-    } else if (gap < base::Seconds(1)) {
-      // Record this as an "autoseek point". Also handle the case where required
-      // time is inside the gap.
-      gapless_playback_seek_skip_.Add(last_end, ranges.start(i));
-      contains_required_time |=
-          gapless_playback_seek_skip_.contains(i - 1, required_time);
-    } else if (ranges.size() > ranges_size_pre_append) {
-      HlsDemuxerStatus error = HlsDemuxerStatus::Codes::kInvalidLoadedRanges;
-      rendition_host_->Quit(std::move(error)
-                                .WithData("required_time", required_time)
-                                .WithData("ranges", ranges));
-    }
-    last_end = ranges.end(i);
-  }
-
-  if (contains_required_time) {
+  if (ranges.size() && ranges.contains(ranges.size() - 1, required_time)) {
     std::move(cb).Run();
     return;
   }
diff --git a/media/filters/hls_rendition_impl.h b/media/filters/hls_rendition_impl.h
index 555bd5dc..8ee452d2 100644
--- a/media/filters/hls_rendition_impl.h
+++ b/media/filters/hls_rendition_impl.h
@@ -124,9 +124,6 @@
 
   std::unique_ptr<MediaLog> media_log_;
 
-  // What time ranges we should skip due to missing frames.
-  Ranges<base::TimeDelta> gapless_playback_seek_skip_;
-
   // toggleable bool flags.
   bool set_stream_end_ = false;
   bool is_stopped_for_shutdown_ = false;
diff --git a/media/filters/hls_rendition_impl_unittest.cc b/media/filters/hls_rendition_impl_unittest.cc
index 9b2aeda..4de4eff 100644
--- a/media/filters/hls_rendition_impl_unittest.cc
+++ b/media/filters/hls_rendition_impl_unittest.cc
@@ -153,7 +153,6 @@
 
 using testing::_;
 using testing::ElementsAreArray;
-using testing::InSequence;
 using testing::NiceMock;
 using testing::Return;
 
@@ -235,18 +234,21 @@
         .WillRepeatedly(Return(ranges));
   }
 
-  void RespondWithRangeSet(
-      std::vector<std::tuple<base::TimeDelta, base::TimeDelta>> ranges) {
-    InSequence s;
-    for (const auto& pair : ranges) {
-      Ranges<base::TimeDelta> range;
-      if (std::get<0>(pair) != std::get<1>(pair)) {
-        range.Add(std::get<0>(pair), std::get<1>(pair));
-      }
-      EXPECT_CALL(*mock_mdeh_, GetBufferedRanges("test"))
-          .Times(1)
-          .WillOnce(Return(range));
+  void RespondWithRangeTwice(base::TimeDelta A,
+                             base::TimeDelta B,
+                             base::TimeDelta X,
+                             base::TimeDelta Y) {
+    Ranges<base::TimeDelta> ab;
+    if (A != B) {
+      ab.Add(A, B);
     }
+    Ranges<base::TimeDelta> xy;
+    if (X != Y) {
+      xy.Add(X, Y);
+    }
+    EXPECT_CALL(*mock_mdeh_, GetBufferedRanges("test"))
+        .WillOnce(Return(ab))
+        .WillOnce(Return(xy));
   }
 
   void SupplyAndExpectJunkData(base::TimeDelta initial_response_start,
@@ -273,8 +275,7 @@
     appended_range.Add(fetch_expected_time - base::Seconds(1),
                        fetch_expected_time + base::Seconds(1));
     EXPECT_CALL(*mock_mdeh_, GetBufferedRanges("test"))
-        .Times(3)
-        .WillOnce(Return(initial_range))
+        .Times(2)
         .WillOnce(Return(initial_range))
         .WillOnce(Return(appended_range));
   }
@@ -404,11 +405,8 @@
 
   // CheckState causes the rentidion to:
   // Check buffered ranges first
-  RespondWithRangeSet({
-      {base::Seconds(0), base::Seconds(0)},
-      {base::Seconds(0), base::Seconds(0)},
-      {base::Seconds(0), base::Seconds(5)},
-  });
+  RespondWithRangeTwice(base::Seconds(0), base::Seconds(0), base::Seconds(0),
+                        base::Seconds(5));
   // The first segment will be queried
   std::string tscontent = "tscontent";
   RespondToUrl("http://example.com/playlist_4500Kb_14551245.ts", tscontent);
@@ -431,9 +429,8 @@
   // CheckState causes the rentidion to:
   // Check buffered ranges first. In this case, we've loaded a bunch of content
   // already, and our loaded ranges are [0 - 8)
-  RespondWithRangeSet({{base::Seconds(0), base::Seconds(8)},
-                       {base::Seconds(0), base::Seconds(8)},
-                       {base::Seconds(0), base::Seconds(16)}});
+  RespondWithRangeTwice(base::Seconds(0), base::Seconds(8), base::Seconds(0),
+                        base::Seconds(16));
 
   // The next unqueried segment will be queried
   std::string tscontent = "tscontent";
@@ -557,11 +554,8 @@
   std::string tscontent = "tscontent";
   RespondToUrl("http://example.com/playlist_4500Kb_14551245.ts", tscontent);
   RequireAppend(base::as_byte_span(tscontent));
-  RespondWithRangeSet({
-      {base::Seconds(0), base::Seconds(0)},
-      {base::Seconds(0), base::Seconds(0)},
-      {base::Seconds(0), base::Seconds(2)},
-  });
+  RespondWithRangeTwice(base::Seconds(0), base::Seconds(0), base::Seconds(0),
+                        base::Seconds(2));
   rendition->CheckState(base::Seconds(0), 0.0,
                         BindCheckState(base::Seconds(0)));
   task_environment_.RunUntilIdle();
@@ -622,11 +616,8 @@
   // is not exhausted (it's just been updated!) and so we fetch the next one.
   // After appending and parsing, it's brought our loaded ranges up to 202, and
   // the response to check state is to run it again in 0 seconds.
-  RespondWithRangeSet({
-      {base::Seconds(0), base::Seconds(32)},
-      {base::Seconds(0), base::Seconds(32)},
-      {base::Seconds(0), base::Seconds(202)},
-  });
+  RespondWithRangeTwice(base::Seconds(0), base::Seconds(32), base::Seconds(0),
+                        base::Seconds(202));
   std::string newcontent = "newcontent";
   RespondToUrl("http://example.com/playlist_4500Kb_14551349.ts", newcontent);
   RequireAppend(base::as_byte_span(newcontent));
@@ -638,11 +629,8 @@
   // requested again, this time for the next segment. Lets pretend that next
   // segment has 20 seconds of data in it, bringing new range end to 222. The
   // response will still be 0 seconds.
-  RespondWithRangeSet({
-      {base::Seconds(0), base::Seconds(202)},
-      {base::Seconds(0), base::Seconds(202)},
-      {base::Seconds(0), base::Seconds(222)},
-  });
+  RespondWithRangeTwice(base::Seconds(0), base::Seconds(202), base::Seconds(0),
+                        base::Seconds(222));
   newcontent = "blah";
   RespondToUrl("http://example.com/playlist_4500Kb_14551350.ts", "blah");
   RequireAppend(base::as_byte_span(newcontent));
@@ -661,183 +649,34 @@
   task_environment_.RunUntilIdle();
 }
 
-TEST_F(HlsRenditionImplUnittest, TestCantSkipOverLargeGaps) {
-  auto rendition = MakeVodRendition(kDiscontinuous);
-  ASSERT_NE(rendition, nullptr);
-  std::string content = "123";
-  Ranges<base::TimeDelta> empty_range;
-  Ranges<base::TimeDelta> split_range;
-  split_range.Add(base::Seconds(0), base::Milliseconds(998));
-  split_range.Add(base::Seconds(3), base::Milliseconds(3999));
-  EXPECT_CALL(*mock_mdeh_, GetBufferedRanges("test"))
-      .WillOnce(Return(empty_range))   // Once in CheckState
-      .WillOnce(Return(empty_range))   // Before appending
-      .WillOnce(Return(split_range));  // After appending
-  RespondToUrl("https://example.com/bip00.ts", content);
-  RequireAppend(base::as_byte_span(content));
-
-  // The ranges are more than 1 second apart, so failure occurs.
-  EXPECT_CALL(*mock_hrh_, Quit(_));
-  rendition->CheckState(base::Seconds(0), 0.0, BindCheck0Sec());
-}
-
-TEST_F(HlsRenditionImplUnittest, TestSkipsSmallSingleGap) {
-  auto rendition = MakeVodRendition(kDiscontinuous);
-  ASSERT_NE(rendition, nullptr);
-  std::string content = "123";
-  Ranges<base::TimeDelta> empty_range;
-  Ranges<base::TimeDelta> split_range;
-  Ranges<base::TimeDelta> end_range;
-  split_range.Add(base::Seconds(0), base::Milliseconds(998));
-  split_range.Add(base::Seconds(1), base::Seconds(2));
-  end_range.Add(base::Seconds(1), base::Seconds(2));
-  EXPECT_CALL(*mock_mdeh_, GetBufferedRanges("test"))
-      .WillOnce(Return(empty_range))   // Once in CheckState
-      .WillOnce(Return(empty_range))   // Before appending
-      .WillOnce(Return(split_range));  // After appending
-  RespondToUrl("https://example.com/bip00.ts", content);
-  RequireAppend(base::as_byte_span(content));
-  rendition->CheckState(base::Seconds(0), 0.0, BindCheck0Sec());
-
-  // The next check state comes in at time 0.999. The rendition impl clears the
-  // things before the gap and seeks to the end of the gap.
-  EXPECT_CALL(*mock_mdeh_, GetBufferedRanges("test"))
-      .WillOnce(Return(split_range))  // CheckState initial check
-      .WillOnce(Return(end_range));   // CheckState after removing buffers.
-  EXPECT_CALL(*mock_mdeh_,
-              Remove(_, base::Seconds(0), base::Milliseconds(998)));
-  EXPECT_CALL(*mock_mdeh_, RequestSeek(base::Seconds(1)));
-  rendition->CheckState(base::Seconds(1), 0.0, BindCheckState(kNoTimestamp));
-}
-
-TEST_F(HlsRenditionImplUnittest, TestCantSkipMultipleNearbyGaps) {
-  auto rendition = MakeVodRendition(kDiscontinuous);
-  ASSERT_NE(rendition, nullptr);
-  std::string content = "123";
-  Ranges<base::TimeDelta> empty_range;
-  Ranges<base::TimeDelta> split_range;
-  split_range.Add(base::Seconds(0), base::Milliseconds(998));
-  split_range.Add(base::Milliseconds(1001), base::Milliseconds(1007));
-  split_range.Add(base::Milliseconds(1014), base::Milliseconds(1019));
-  split_range.Add(base::Milliseconds(1028), base::Milliseconds(2000));
-  EXPECT_CALL(*mock_mdeh_, GetBufferedRanges("test"))
-      .WillOnce(Return(empty_range))   // Once in CheckState
-      .WillOnce(Return(empty_range))   // Before appending
-      .WillOnce(Return(split_range));  // After appending
-  RespondToUrl("https://example.com/bip00.ts", content);
-  RequireAppend(base::as_byte_span(content));
-  rendition->CheckState(base::Seconds(0), 0.0, BindCheck0Sec());
-
-  // Check State comes in after the first gap, so failure occurs.
-  EXPECT_CALL(*mock_mdeh_, GetBufferedRanges("test"))
-      .WillOnce(Return(split_range));
-  EXPECT_CALL(*mock_hrh_, Quit(_));
-  rendition->CheckState(base::Milliseconds(1033), 0.0,
-                        BindCheckStateNoExpect());
-}
-
-TEST_F(HlsRenditionImplUnittest, TestCanSkipIntoRangesWithSpacedOutGaps) {
-  auto rendition = MakeVodRendition(kDiscontinuous);
-  ASSERT_NE(rendition, nullptr);
-  std::string content = "123";
-  Ranges<base::TimeDelta> empty_range;
-  Ranges<base::TimeDelta> split_range;
-  Ranges<base::TimeDelta> end_range;
-  split_range.Add(base::Seconds(0), base::Seconds(1));
-  split_range.Add(base::Milliseconds(1002), base::Seconds(5));
-  split_range.Add(base::Milliseconds(5002), base::Seconds(10));
-  split_range.Add(base::Milliseconds(10002), base::Seconds(15));
-
-  end_range.Add(base::Milliseconds(1002), base::Seconds(5));
-  end_range.Add(base::Milliseconds(5002), base::Seconds(10));
-  end_range.Add(base::Milliseconds(10002), base::Seconds(15));
-  EXPECT_CALL(*mock_mdeh_, GetBufferedRanges("test"))
-      .WillOnce(Return(empty_range))   // Once in CheckState
-      .WillOnce(Return(empty_range))   // Before appending
-      .WillOnce(Return(split_range));  // After appending
-  RespondToUrl("https://example.com/bip00.ts", content);
-  RequireAppend(base::as_byte_span(content));
-  rendition->CheckState(base::Seconds(0), 0.0, BindCheck0Sec());
-
-  EXPECT_CALL(*mock_mdeh_, GetBufferedRanges("test"))
-      .WillOnce(Return(split_range))  // CheckState initial check
-      .WillOnce(Return(end_range));   // CheckState after removing buffers.
-  EXPECT_CALL(*mock_mdeh_, Remove(_, base::Seconds(0), base::Seconds(1)));
-  EXPECT_CALL(*mock_mdeh_, RequestSeek(base::Milliseconds(1002)));
-  rendition->CheckState(base::Milliseconds(1010), 0.0,
-                        BindCheckState(kNoTimestamp));
-}
-
-TEST_F(HlsRenditionImplUnittest, TestGapWasRightWhereRequestedBufferEndIs) {
-  auto rendition = MakeVodRendition(kDiscontinuous);
-  ASSERT_NE(rendition, nullptr);
-  std::string content = "123";
-  Ranges<base::TimeDelta> empty_range;
-  Ranges<base::TimeDelta> split_range;
-  Ranges<base::TimeDelta> end_range;
-  split_range.Add(base::Seconds(0), base::Milliseconds(998));
-  split_range.Add(base::Milliseconds(1002), base::Seconds(3));
-  end_range.Add(base::Milliseconds(1002), base::Seconds(3));
-  EXPECT_CALL(*mock_mdeh_, GetBufferedRanges("test"))
-      .WillOnce(Return(empty_range))   // Once in CheckState
-      .WillOnce(Return(empty_range))   // Before appending
-      .WillOnce(Return(split_range));  // After appending
-  RespondToUrl("https://example.com/bip00.ts", content);
-  RequireAppend(base::as_byte_span(content));
-
-  // Our requested time landed right in the middle of the gap. but that's OK.
-  // The next CheckState will seek us.
-  rendition->CheckState(base::Seconds(1), 0.0, BindCheck0Sec());
-
-  EXPECT_CALL(*mock_mdeh_, GetBufferedRanges("test"))
-      .WillOnce(Return(split_range))  // CheckState initial check
-      .WillOnce(Return(end_range));   // CheckState after removing buffers.
-  EXPECT_CALL(*mock_mdeh_,
-              Remove(_, base::Seconds(0), base::Milliseconds(998)));
-  EXPECT_CALL(*mock_mdeh_, RequestSeek(base::Milliseconds(1002)));
-  rendition->CheckState(base::Seconds(1), 0.0, BindCheckState(kNoTimestamp));
-}
-
 TEST_F(HlsRenditionImplUnittest, TestDiscontinuity) {
   auto rendition = MakeVodRendition(kDiscontinuous);
   ASSERT_NE(rendition, nullptr);
   const std::string content = "ehh, whatever";
 
-  RespondWithRangeSet({
-      {base::Seconds(0), base::Seconds(0)},
-      {base::Seconds(0), base::Seconds(0)},
-      {base::Seconds(0), base::Seconds(2)},
-  });
+  RespondWithRangeTwice(base::Seconds(0), base::Seconds(0), base::Seconds(0),
+                        base::Seconds(2));
   RespondToUrl("https://example.com/bip00.ts", content);
   RequireAppend(base::as_byte_span(content));
   rendition->CheckState(base::Seconds(0), 0.0, BindCheck0Sec());
   task_environment_.RunUntilIdle();
 
-  RespondWithRangeSet({
-      {base::Seconds(0), base::Seconds(0)},
-      {base::Seconds(0), base::Seconds(0)},
-      {base::Seconds(0), base::Seconds(2)},
-  });
+  RespondWithRangeTwice(base::Seconds(0), base::Seconds(0), base::Seconds(0),
+                        base::Seconds(2));
   RespondToUrl("https://example.com/bip01.ts", content);
   RequireAppend(base::as_byte_span(content));
   rendition->CheckState(base::Seconds(0), 0.0, BindCheck0Sec());
   task_environment_.RunUntilIdle();
 
-  RespondWithRangeSet({
-      {base::Seconds(0), base::Seconds(0)},
-      {base::Seconds(0), base::Seconds(0)},
-      {base::Seconds(0), base::Seconds(2)},
-  });
+  RespondWithRangeTwice(base::Seconds(0), base::Seconds(0), base::Seconds(0),
+                        base::Seconds(2));
   RespondToUrl("https://example.com/bip02.ts", content);
   RequireAppend(base::as_byte_span(content));
   rendition->CheckState(base::Seconds(0), 0.0, BindCheck0Sec());
   task_environment_.RunUntilIdle();
 
-  RespondWithRangeSet({
-      {base::Seconds(0), base::Seconds(0)},
-      {base::Seconds(0), base::Seconds(0)},
-      {base::Seconds(0), base::Seconds(2)},
-  });
+  RespondWithRangeTwice(base::Seconds(0), base::Seconds(0), base::Seconds(0),
+                        base::Seconds(2));
   RespondToUrl("https://example.com/data00.ts", content);
 
   EXPECT_CALL(*mock_mdeh_, ResetParserState("test", base::Seconds(8.6), _));
@@ -846,21 +685,15 @@
   rendition->CheckState(base::Seconds(0), 0.0, BindCheck0Sec());
   task_environment_.RunUntilIdle();
 
-  RespondWithRangeSet({
-      {base::Seconds(0), base::Seconds(0)},
-      {base::Seconds(0), base::Seconds(0)},
-      {base::Seconds(0), base::Seconds(2)},
-  });
+  RespondWithRangeTwice(base::Seconds(0), base::Seconds(0), base::Seconds(0),
+                        base::Seconds(2));
   RespondToUrl("https://example.com/data01.ts", content);
   RequireAppend(base::as_byte_span(content));
   rendition->CheckState(base::Seconds(0), 0.0, BindCheck0Sec());
   task_environment_.RunUntilIdle();
 
-  RespondWithRangeSet({
-      {base::Seconds(0), base::Seconds(0)},
-      {base::Seconds(0), base::Seconds(0)},
-      {base::Seconds(0), base::Seconds(2)},
-  });
+  RespondWithRangeTwice(base::Seconds(0), base::Seconds(0), base::Seconds(0),
+                        base::Seconds(2));
   RespondToUrl("https://example.com/data02.ts", content);
   RequireAppend(base::as_byte_span(content));
   rendition->CheckState(base::Seconds(0), 0.0, BindCheck0Sec());
@@ -889,11 +722,8 @@
   /* START CHECK 1 */
   // CheckState will start the paused player, query BufferedRanges, get 0-0,
   // which will trigger an attempt to fetch.
-  RespondWithRangeSet({
-      {base::Seconds(0), base::Seconds(0)},
-      {base::Seconds(0), base::Seconds(0)},
-      {base::Seconds(0), base::Seconds(2)},
-  });
+  RespondWithRangeTwice(base::Seconds(0), base::Seconds(0), base::Seconds(0),
+                        base::Seconds(2));
 
   // The fetch will request the segment at "media_0.ts", which has an encryption
   // data attached. We need to populate that here so we can use the same key to
@@ -922,11 +752,8 @@
 
   // On the second fetch, the encryption data should remain the same,
   // so we can just use new text.
-  RespondWithRangeSet({
-      {base::Seconds(0), base::Seconds(2)},
-      {base::Seconds(0), base::Seconds(2)},
-      {base::Seconds(0), base::Seconds(4)},
-  });
+  RespondWithRangeTwice(base::Seconds(0), base::Seconds(2), base::Seconds(0),
+                        base::Seconds(4));
   RespondToUrl("https://example.com/media_1.ts", ciphertext);
   RequireAppend(base::as_byte_span(cleartext));
   rendition->CheckState(base::Seconds(0), 0.0,
@@ -946,11 +773,8 @@
 
   // CheckState will start the paused player, query BufferedRanges, get 0-4
   // which will trigger an attempt to fetch.
-  RespondWithRangeSet({
-      {base::Seconds(0), base::Seconds(4)},
-      {base::Seconds(0), base::Seconds(4)},
-      {base::Seconds(0), base::Seconds(6)},
-  });
+  RespondWithRangeTwice(base::Seconds(0), base::Seconds(4), base::Seconds(0),
+                        base::Seconds(6));
 
   // The fetch will request the segment at "media_2.ts", which has a new
   // encryption data.
@@ -979,11 +803,8 @@
   rendition->UpdatePlaylist(std::move(parsed).value());
 
   // The encryption data is the same for segment 3, since it didn't change.
-  RespondWithRangeSet({
-      {base::Seconds(0), base::Seconds(2)},
-      {base::Seconds(0), base::Seconds(2)},
-      {base::Seconds(0), base::Seconds(4)},
-  });
+  RespondWithRangeTwice(base::Seconds(0), base::Seconds(2), base::Seconds(0),
+                        base::Seconds(4));
   RespondToUrl("https://example.com/media_3.ts", ciphertext2);
   RequireAppend(base::as_byte_span(cleartext));
   rendition->CheckState(base::Seconds(0), 0.0,
@@ -1004,11 +825,8 @@
 
   // CheckState will start the paused player, query BufferedRanges, get 0-4
   // which will trigger an attempt to fetch.
-  RespondWithRangeSet({
-      {base::Seconds(0), base::Seconds(4)},
-      {base::Seconds(0), base::Seconds(4)},
-      {base::Seconds(0), base::Seconds(6)},
-  });
+  RespondWithRangeTwice(base::Seconds(0), base::Seconds(4), base::Seconds(0),
+                        base::Seconds(6));
 
   // The fetch will request the segment at "mediax_4.ts", for which the
   // encryption data has not been fetched.
@@ -1028,11 +846,8 @@
   /* START CHECK 6 */
 
   // The encryption data is the same for segment 5, since it didn't change.
-  RespondWithRangeSet({
-      {base::Seconds(0), base::Seconds(2)},
-      {base::Seconds(0), base::Seconds(2)},
-      {base::Seconds(0), base::Seconds(4)},
-  });
+  RespondWithRangeTwice(base::Seconds(0), base::Seconds(2), base::Seconds(0),
+                        base::Seconds(4));
   RespondToUrl("https://example.com/mediax_5.ts", ciphertext3);
   RequireAppend(base::as_byte_span(cleartext));
   rendition->CheckState(base::Seconds(0), 0.0,
diff --git a/media/filters/source_buffer_stream.cc b/media/filters/source_buffer_stream.cc
index ab4d15c..218ab67f 100644
--- a/media/filters/source_buffer_stream.cc
+++ b/media/filters/source_buffer_stream.cc
@@ -1198,8 +1198,9 @@
   }
 
   // Trim overlap from the existing buffer.
+  auto existing_discard = overlapped_buffer->discard_padding();
   DecoderBuffer::DiscardPadding discard_padding =
-      overlapped_buffer->discard_padding();
+      existing_discard.value_or(DecoderBuffer::DiscardPadding());
   discard_padding.second += overlap_duration;
   overlapped_buffer->set_discard_padding(discard_padding);
   overlapped_buffer->set_duration(overlapped_buffer->duration() -
diff --git a/media/filters/source_buffer_stream_unittest.cc b/media/filters/source_buffer_stream_unittest.cc
index 61ef0d5..8f0e0896 100644
--- a/media/filters/source_buffer_stream_unittest.cc
+++ b/media/filters/source_buffer_stream_unittest.cc
@@ -379,8 +379,10 @@
         ASSERT_EQ(buffer->timestamp(), preroll_buffer->timestamp());
         ASSERT_EQ(buffer->GetDecodeTimestamp(),
                   preroll_buffer->GetDecodeTimestamp());
-        ASSERT_EQ(kInfiniteDuration, preroll_buffer->discard_padding().first);
-        ASSERT_EQ(base::TimeDelta(), preroll_buffer->discard_padding().second);
+        auto preroll_discard = preroll_buffer->discard_padding();
+        ASSERT_TRUE(preroll_discard.has_value());
+        ASSERT_EQ(kInfiniteDuration, preroll_discard->first);
+        ASSERT_EQ(base::TimeDelta(), preroll_discard->second);
         ASSERT_TRUE(buffer->is_key_frame());
 
         ss << "P";
@@ -4330,14 +4332,13 @@
   // Manually inspect the buffers at the no-splice boundary to verify duration
   // and lack of discard padding (set when splicing).
   scoped_refptr<StreamParserBuffer> buffer;
-  const DecoderBuffer::DiscardPadding kEmptyDiscardPadding;
   for (int i = 0; i < 10; i++) {
     // Verify buffer timestamps and durations are preserved and no buffers have
     // discard padding (indicating no splice trimming).
     EXPECT_STATUS_FOR_STREAM_OP(kSuccess, GetNextBuffer(&buffer));
     EXPECT_EQ(base::Milliseconds(i * 2), buffer->timestamp());
     EXPECT_EQ(base::Milliseconds(2), buffer->duration());
-    EXPECT_EQ(kEmptyDiscardPadding, buffer->discard_padding());
+    EXPECT_FALSE(buffer->discard_padding().has_value());
   }
 
   CheckNoNextBuffer();
@@ -4477,8 +4478,7 @@
   EXPECT_STATUS_FOR_STREAM_OP(kSuccess, GetNextBuffer(&read_buffer));
   EXPECT_EQ(base::Milliseconds(5), read_buffer->timestamp());
   EXPECT_EQ(kDuration, read_buffer->duration());
-  EXPECT_EQ(std::make_pair(kNoDiscard, kNoDiscard),
-            read_buffer->discard_padding());
+  EXPECT_FALSE(read_buffer->discard_padding().has_value());
 
   CheckNoNextBuffer();
 }
diff --git a/media/filters/wsola_internals.cc b/media/filters/wsola_internals.cc
index 3503664..c34e43518 100644
--- a/media/filters/wsola_internals.cc
+++ b/media/filters/wsola_internals.cc
@@ -11,13 +11,17 @@
 
 #include <algorithm>
 #include <cmath>
+#include <cstdint>
 #include <cstring>
 #include <limits>
 #include <memory>
 #include <numbers>
 
 #include "base/check_op.h"
+#include "base/containers/auto_spanification_helper.h"
+#include "base/containers/span.h"
 #include "base/cpu.h"
+#include "base/numerics/safe_conversions.h"
 #include "build/build_config.h"
 #include "media/base/audio_bus.h"
 
@@ -57,20 +61,20 @@
                                 int num_frames,
                                 float* dot_product) {
   // SIMD optimized variants can provide a massive speedup to this operation.
-  const int rem = num_frames % 4;
-  const int last_index = num_frames - rem;
+  const size_t rem = base::checked_cast<size_t>(num_frames) % 4;
+  const size_t last_index = num_frames - rem;
   const int channels = a->channels();
   for (int ch = 0; ch < channels; ++ch) {
-    const float* a_src =
-        a->channel_span(ch).subspan(static_cast<size_t>(frame_offset_a)).data();
-    const float* b_src =
-        b->channel_span(ch).subspan(static_cast<size_t>(frame_offset_b)).data();
+    base::span<const float> a_src =
+        a->channel_span(ch).subspan(static_cast<size_t>(frame_offset_a));
+    base::span<const float> b_src =
+        b->channel_span(ch).subspan(static_cast<size_t>(frame_offset_b));
 
     // First sum all components.
     __m128 m_sum = _mm_setzero_ps();
-    for (int s = 0; s < last_index; s += 4) {
+    for (size_t s = 0; s < last_index; s += 4) {
       m_sum = _mm_add_ps(
-          m_sum, _mm_mul_ps(_mm_loadu_ps(a_src + s), _mm_loadu_ps(b_src + s)));
+          m_sum, _mm_mul_ps(_mm_loadu_ps(&a_src[s]), _mm_loadu_ps(&b_src[s])));
     }
 
     // Reduce to a single float for this channel. Sadly, SSE1,2 doesn't have a
@@ -91,7 +95,7 @@
   for (int k = 0; k < a->channels(); ++k) {
     const float* ch_a = a->channel(k) + frame_offset_a;
     const float* ch_b = b->channel(k) + frame_offset_b;
-    for (int n = 0; n < rem; ++n) {
+    for (size_t n = 0; n < rem; ++n) {
       dot_product[k] += *ch_a++ * *ch_b++;
     }
   }
@@ -251,7 +255,7 @@
   int channels = input->channels();
 
   for (int k = 0; k < input->channels(); ++k) {
-    const float* input_channel = input->channel_span(k).data();
+    base::span<const float> input_channel = input->channel_span(k);
 
     energy[k] = 0;
 
@@ -260,12 +264,14 @@
       energy[k] += input_channel[m] * input_channel[m];
     }
 
-    const float* slide_out = input_channel;
-    const float* slide_in = input_channel + frames_per_block;
+    auto slide_out = input_channel.begin();
+    auto slide_in =
+        input_channel.subspan(base::checked_cast<size_t>(frames_per_block))
+            .begin();
     for (int n = 1; n < num_blocks; ++n, ++slide_in, ++slide_out) {
       energy[k + n * channels] = energy[k + (n - 1) * channels] -
-                                 *slide_out * *slide_out +
-                                 *slide_in * *slide_in;
+                                 (*slide_out) * (*slide_out) +
+                                 (*slide_in) * (*slide_in);
     }
   }
 }
diff --git a/media/gpu/macros.h b/media/gpu/macros.h
index f119044..1265c6f 100644
--- a/media/gpu/macros.h
+++ b/media/gpu/macros.h
@@ -10,6 +10,9 @@
 #ifndef MEDIA_GPU_MACROS_H_
 #define MEDIA_GPU_MACROS_H_
 
+#include <array>
+
+#include "base/containers/auto_spanification_helper.h"
 #include "base/logging.h"
 
 // Try to adhere to [1] when adding and using logging.
@@ -34,6 +37,19 @@
   memcpy(to, from, sizeof(T[N]));
 }
 
+// Copy the memory between arrays while ensuring the same size.
+template <typename T, size_t N>
+inline void SafeArrayMemcpy(T (&to)[N], const std::array<T, N>& from) {
+  memcpy(to, from.data(), sizeof(T[N]));
+}
+
+// Copy the memory between arrays while ensuring the same size.
+template <typename T, size_t N, size_t M>
+inline void SafeArrayMemcpy(T (&to)[N][M],
+                            const std::array<std::array<T, M>, N>& from) {
+  memcpy(to, from.data(), sizeof(T[N][M]));
+}
+
 }  // namespace media
 
 #endif  // MEDIA_GPU_MACROS_H_
diff --git a/media/gpu/test/image_quality_metrics.cc b/media/gpu/test/image_quality_metrics.cc
index 6142e890..ab6b7c1 100644
--- a/media/gpu/test/image_quality_metrics.cc
+++ b/media/gpu/test/image_quality_metrics.cc
@@ -8,9 +8,11 @@
 #endif
 
 #include <math.h>
+
 #include <algorithm>
 #include <utility>
 
+#include "base/containers/span.h"
 #include "base/logging.h"
 #include "media/base/video_frame.h"
 #include "media/base/video_types.h"
@@ -349,9 +351,9 @@
   return test_log_prob / golden_log_prob;
 }
 
-double ComputeAR30PSNR(const uint32_t* frame1_data,
+double ComputeAR30PSNR(base::span<const uint32_t> frame1_data,
                        size_t frame1_stride,
-                       const uint32_t* frame2_data,
+                       base::span<const uint32_t> frame2_data,
                        size_t frame2_stride,
                        size_t width,
                        size_t height) {
diff --git a/media/gpu/test/raw_video.cc b/media/gpu/test/raw_video.cc
index af09dffe9..85986ee 100644
--- a/media/gpu/test/raw_video.cc
+++ b/media/gpu/test/raw_video.cc
@@ -11,6 +11,7 @@
 
 #include <array>
 
+#include "base/containers/span.h"
 #include "base/files/file_util.h"
 #include "base/files/memory_mapped_file.h"
 #include "base/functional/bind.h"
@@ -246,13 +247,15 @@
     LOG_ASSERT(i420_frame.format() == VideoPixelFormat::PIXEL_FORMAT_I420);
     std::vector<uint8_t> buffer(video_frame_size_);
     if (layout_.format() == PIXEL_FORMAT_NV12) {
-      uint8_t* nv12_frame = buffer.data();
+      base::span<uint8_t> nv12_frame = buffer;
       int ret = libyuv::I420ToNV12(
           i420_frame.data(0), i420_frame.stride(0), i420_frame.data(1),
           i420_frame.stride(1), i420_frame.data(2), i420_frame.stride(2),
-          nv12_frame + layout_.planes()[0].offset, layout_.planes()[0].stride,
-          nv12_frame + layout_.planes()[1].offset, layout_.planes()[1].stride,
-          layout_.coded_size().width(), layout_.coded_size().height());
+          nv12_frame.subspan(layout_.planes()[0].offset).data(),
+          layout_.planes()[0].stride,
+          nv12_frame.subspan(layout_.planes()[1].offset).data(),
+          layout_.planes()[1].stride, layout_.coded_size().width(),
+          layout_.coded_size().height());
       LOG_ASSERT(ret == 0) << "Failed converting from I420 to NV12";
     } else {
       CHECK_EQ(layout_.format(), PIXEL_FORMAT_I420);
diff --git a/media/gpu/v4l2/v4l2_video_decoder_delegate_vp8.cc b/media/gpu/v4l2/v4l2_video_decoder_delegate_vp8.cc
index 60a71c6..e5c23c9 100644
--- a/media/gpu/v4l2/v4l2_video_decoder_delegate_vp8.cc
+++ b/media/gpu/v4l2/v4l2_video_decoder_delegate_vp8.cc
@@ -178,7 +178,7 @@
   v4l2_frame_hdr.num_dct_parts = frame_hdr->num_of_dct_partitions;
 
   static_assert(std::extent<decltype(v4l2_frame_hdr.dct_part_sizes)>() ==
-                    std::extent<decltype(frame_hdr->dct_partition_sizes)>(),
+                    std::tuple_size<decltype(frame_hdr->dct_partition_sizes)>(),
                 "DCT partition size arrays must have equal number of elements");
   for (size_t i = 0; i < frame_hdr->num_of_dct_partitions &&
                      i < std::size(v4l2_frame_hdr.dct_part_sizes);
diff --git a/media/gpu/vaapi/av1_vaapi_video_decoder_delegate.cc b/media/gpu/vaapi/av1_vaapi_video_decoder_delegate.cc
index 5e055caa..6c43dac 100644
--- a/media/gpu/vaapi/av1_vaapi_video_decoder_delegate.cc
+++ b/media/gpu/vaapi/av1_vaapi_video_decoder_delegate.cc
@@ -15,6 +15,7 @@
 #include <algorithm>
 #include <vector>
 
+#include "base/containers/span.h"
 #include "base/functional/callback_helpers.h"
 #include "base/logging.h"
 #include "base/memory/scoped_refptr.h"
@@ -192,7 +193,7 @@
 }
 
 void FillGlobalMotionInfo(
-    VAWarpedMotionParamsAV1 va_warped_motion[7],
+    base::span<VAWarpedMotionParamsAV1, 7> va_warped_motion,
     const std::array<libgav1::GlobalMotion, libgav1::kNumReferenceFrameTypes>&
         global_motion) {
   // global_motion[0] (for kReferenceFrameIntra) is not used.
diff --git a/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.cc b/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.cc
index 954be501..87541cb1 100644
--- a/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.cc
+++ b/media/gpu/vaapi/av1_vaapi_video_encoder_delegate.cc
@@ -15,6 +15,8 @@
 #include <utility>
 
 #include "base/bits.h"
+#include "base/containers/auto_spanification_helper.h"
+#include "base/containers/span.h"
 #include "base/logging.h"
 #include "media/gpu/macros.h"
 #include "media/gpu/svc_layers.h"
@@ -195,15 +197,19 @@
       reinterpret_cast<AV1Picture*>(job.picture().get()));
 }
 
-void DownscaleSegmentMap(const uint8_t* src_seg_map,
-                         uint32_t src_seg_size,
-                         size_t num_segments,
-                         uint8_t* dst_seg_map,
-                         uint32_t dst_seg_size,
-                         const gfx::Size& coded_size) {
+void DownscaleSegmentMap(
+    const uint8_t* src_seg_map,
+    uint32_t src_seg_size,
+    size_t num_segments,
+    base::span<uint8_t> dst_seg_map,
+    uint32_t spanification_suspected_redundant_dst_seg_size,
+    const gfx::Size& coded_size) {
+  // TODO(crbug.com/431824301): Remove unneeded parameter once validated to be
+  // redundant in M143.
+  CHECK_EQ(spanification_suspected_redundant_dst_seg_size, dst_seg_map.size());
   CHECK(std::has_single_bit(src_seg_size));
-  CHECK(std::has_single_bit(dst_seg_size));
-  CHECK_LT(src_seg_size, dst_seg_size);
+  CHECK(std::has_single_bit(spanification_suspected_redundant_dst_seg_size));
+  CHECK_LT(src_seg_size, spanification_suspected_redundant_dst_seg_size);
 
   // We want to avoid doing a division operation for each src segment, so we
   // find the log of the segment size ratio and right shift by that instead to
@@ -211,7 +217,8 @@
   // compute the log, since we know the segment size ratios of going to be
   // powers of two.
   const uint32_t log_seg_size_ratio =
-      std::countl_zero(src_seg_size) - std::countl_zero(dst_seg_size);
+      std::countl_zero(src_seg_size) -
+      std::countl_zero(spanification_suspected_redundant_dst_seg_size);
   const uint32_t src_width =
       base::bits::AlignUp(static_cast<uint32_t>(coded_size.width()),
                           src_seg_size) /
@@ -222,12 +229,12 @@
       src_seg_size;
   const uint32_t dst_width =
       base::bits::AlignUp(static_cast<uint32_t>(coded_size.width()),
-                          dst_seg_size) /
-      dst_seg_size;
+                          spanification_suspected_redundant_dst_seg_size) /
+      spanification_suspected_redundant_dst_seg_size;
   const uint32_t dst_height =
       base::bits::AlignUp(static_cast<uint32_t>(coded_size.height()),
-                          dst_seg_size) /
-      dst_seg_size;
+                          spanification_suspected_redundant_dst_seg_size) /
+      spanification_suspected_redundant_dst_seg_size;
 
   std::vector<uint8_t> freq_distribution(num_segments * dst_width * dst_height);
 
@@ -256,8 +263,8 @@
           most_freq = i;
         }
       }
-      *dst_seg_map = most_freq;
-      dst_seg_map++;
+      dst_seg_map[0] = most_freq;
+      base::PostIncrementSpan(dst_seg_map);
     }
   }
 }
@@ -957,8 +964,8 @@
     }
     segment_map_param.segmentMapDataSize = segmentation_map_.size();
     DownscaleSegmentMap(seg_data.segmentation_map, kSegmentGranularity,
-                        seg_data.delta_q_size, segmentation_map_.data(),
-                        seg_size_, coded_size_);
+                        seg_data.delta_q_size, segmentation_map_, seg_size_,
+                        coded_size_);
     segment_map_param.pSegmentMap = segmentation_map_.data();
   }
 
diff --git a/media/gpu/vaapi/h264_vaapi_video_encoder_delegate.cc b/media/gpu/vaapi/h264_vaapi_video_encoder_delegate.cc
index 53e1e99..ab59c21 100644
--- a/media/gpu/vaapi/h264_vaapi_video_encoder_delegate.cc
+++ b/media/gpu/vaapi/h264_vaapi_video_encoder_delegate.cc
@@ -16,6 +16,7 @@
 #include <utility>
 
 #include "base/bits.h"
+#include "base/containers/span.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/notimplemented.h"
@@ -86,15 +87,16 @@
   return *reinterpret_cast<VAEncMiscParam*>(va_buffer->data);
 }
 
-void CreateVAEncRateControlParams(uint32_t bps,
-                                  uint32_t target_percentage,
-                                  uint32_t window_size,
-                                  uint32_t initial_qp,
-                                  uint32_t min_qp,
-                                  uint32_t max_qp,
-                                  uint32_t framerate,
-                                  uint32_t buffer_size,
-                                  std::vector<uint8_t> misc_buffers[3]) {
+void CreateVAEncRateControlParams(
+    uint32_t bps,
+    uint32_t target_percentage,
+    uint32_t window_size,
+    uint32_t initial_qp,
+    uint32_t min_qp,
+    uint32_t max_qp,
+    uint32_t framerate,
+    uint32_t buffer_size,
+    base::span<std::vector<uint8_t>, 3> misc_buffers) {
   auto& rate_control_param =
       AllocateMiscParameterBuffer<VAEncMiscParameterRateControl>(
           misc_buffers[0], VAEncMiscParameterTypeRateControl);
diff --git a/media/gpu/vaapi/h264_vaapi_video_encoder_delegate_unittest.cc b/media/gpu/vaapi/h264_vaapi_video_encoder_delegate_unittest.cc
index c121f364..a0a62e7 100644
--- a/media/gpu/vaapi/h264_vaapi_video_encoder_delegate_unittest.cc
+++ b/media/gpu/vaapi/h264_vaapi_video_encoder_delegate_unittest.cc
@@ -9,6 +9,7 @@
 
 #include "media/gpu/vaapi/h264_vaapi_video_encoder_delegate.h"
 
+#include <array>
 #include <memory>
 
 #include "base/logging.h"
@@ -47,9 +48,12 @@
 constexpr size_t kMaxRefIdxL0Size = 2;
 
 constexpr size_t kTemporalLayerCycle = 4;
-constexpr uint8_t kExpectedTemporalId[][kTemporalLayerCycle] = {{0, 0, 0, 0},
-                                                                {0, 1, 0, 1},
-                                                                {0, 2, 1, 2}};
+constexpr auto kExpectedTemporalId =
+    std::to_array<std::array<uint8_t, kTemporalLayerCycle>>({
+        {0, 0, 0, 0},
+        {0, 1, 0, 1},
+        {0, 2, 1, 2},
+    });
 
 VaapiVideoEncoderDelegate::Config kDefaultVEADelegateConfig{
     .max_num_ref_frames = 4,
@@ -575,8 +579,8 @@
   InitializeEncoderWithSWBitrateController(num_temporal_layers);
   const uint32_t kBitrate = DefaultVEAConfig().bitrate.target_bps();
   const uint32_t kFramerate = DefaultVEAConfig().framerate;
-  const uint8_t* expected_temporal_ids =
-      kExpectedTemporalId[num_temporal_layers - 1];
+  const auto expected_temporal_ids =
+      base::span<const uint8_t>(kExpectedTemporalId[num_temporal_layers - 1]);
 
   // Call UpdateRates before Encode.
   UpdateRatesAndEncode(true, kBitrate / 2, kFramerate, num_temporal_layers,
diff --git a/media/gpu/vaapi/h265_vaapi_video_decoder_delegate.cc b/media/gpu/vaapi/h265_vaapi_video_decoder_delegate.cc
index bdd8b83..d5f13ad54 100644
--- a/media/gpu/vaapi/h265_vaapi_video_decoder_delegate.cc
+++ b/media/gpu/vaapi/h265_vaapi_video_decoder_delegate.cc
@@ -9,6 +9,7 @@
 
 #include "media/gpu/vaapi/h265_vaapi_video_decoder_delegate.h"
 
+#include "base/containers/span.h"
 #include "base/memory/scoped_refptr.h"
 #include "build/build_config.h"
 #include "media/base/cdm_context.h"
@@ -592,7 +593,7 @@
 
 void H265VaapiVideoDecoderDelegate::FillVARefFramesFromRefList(
     const H265Picture::Vector& ref_pic_list,
-    VAPictureHEVC* va_pics) {
+    base::span<VAPictureHEVC> va_pics) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   ref_pic_list_pocs_.clear();
   for (auto& it : ref_pic_list) {
diff --git a/media/gpu/vaapi/h265_vaapi_video_decoder_delegate.h b/media/gpu/vaapi/h265_vaapi_video_decoder_delegate.h
index b134c7e..eea6d8fe0 100644
--- a/media/gpu/vaapi/h265_vaapi_video_decoder_delegate.h
+++ b/media/gpu/vaapi/h265_vaapi_video_decoder_delegate.h
@@ -7,6 +7,7 @@
 
 #include <va/va.h>
 
+#include "base/containers/span.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
 #include "media/gpu/h265_decoder.h"
@@ -71,7 +72,7 @@
  private:
   void FillVAPicture(VAPictureHEVC* va_pic, scoped_refptr<H265Picture> pic);
   void FillVARefFramesFromRefList(const H265Picture::Vector& ref_pic_list,
-                                  VAPictureHEVC* va_pics);
+                                  base::span<VAPictureHEVC> va_pics);
 
   // Returns |kInvalidRefPicIndex| if it cannot find a picture.
   int GetRefPicIndex(int poc);
diff --git a/media/gpu/vaapi/test/h265_vaapi_wrapper.cc b/media/gpu/vaapi/test/h265_vaapi_wrapper.cc
index 32ce074..be3b3a8 100644
--- a/media/gpu/vaapi/test/h265_vaapi_wrapper.cc
+++ b/media/gpu/vaapi/test/h265_vaapi_wrapper.cc
@@ -11,6 +11,7 @@
 
 #include <va/va.h>
 
+#include "base/containers/span.h"
 #include "base/memory/scoped_refptr.h"
 #include "build/build_config.h"
 #include "media/gpu/macros.h"
@@ -500,7 +501,7 @@
 
 void H265VaapiWrapper::FillVARefFramesFromRefList(
     const H265Picture::Vector& ref_pic_list,
-    VAPictureHEVC* va_pics) {
+    base::span<VAPictureHEVC> va_pics) {
   ref_pic_list_pocs_.clear();
   for (auto& it : ref_pic_list) {
     if (!it->IsUnused()) {
diff --git a/media/gpu/vaapi/test/h265_vaapi_wrapper.h b/media/gpu/vaapi/test/h265_vaapi_wrapper.h
index bcf3b45..0698322e 100644
--- a/media/gpu/vaapi/test/h265_vaapi_wrapper.h
+++ b/media/gpu/vaapi/test/h265_vaapi_wrapper.h
@@ -5,6 +5,7 @@
 #ifndef MEDIA_GPU_VAAPI_TEST_H265_VAAPI_WRAPPER_H_
 #define MEDIA_GPU_VAAPI_TEST_H265_VAAPI_WRAPPER_H_
 
+#include "base/containers/span.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/raw_ref.h"
 #include "media/gpu/vaapi/test/h265_dpb.h"
@@ -55,7 +56,7 @@
  private:
   void FillVAPicture(VAPictureHEVC* va_pic, scoped_refptr<H265Picture> pic);
   void FillVARefFramesFromRefList(const H265Picture::Vector& ref_pic_list,
-                                  VAPictureHEVC* va_pics);
+                                  base::span<VAPictureHEVC> va_pics);
 
   // Returns |kInvalidRefPicIndex| if it cannot find a picture.
   int GetRefPicIndex(int poc);
diff --git a/media/gpu/vaapi/vaapi_jpeg_decoder.cc b/media/gpu/vaapi/vaapi_jpeg_decoder.cc
index e324601..129213ba 100644
--- a/media/gpu/vaapi/vaapi_jpeg_decoder.cc
+++ b/media/gpu/vaapi/vaapi_jpeg_decoder.cc
@@ -15,6 +15,7 @@
 #include <iostream>
 #include <type_traits>
 
+#include "base/containers/span.h"
 #include "base/logging.h"
 #include "base/numerics/safe_conversions.h"
 #include "gpu/config/gpu_finch_features.h"
@@ -47,7 +48,7 @@
   }
 }
 
-static void FillIQMatrix(const JpegQuantizationTable* q_table,
+static void FillIQMatrix(base::span<const JpegQuantizationTable> q_table,
                          VAIQMatrixBufferJPEGBaseline* iq_matrix) {
   static_assert(kJpegMaxQuantizationTableNum ==
                     std::extent<decltype(iq_matrix->load_quantiser_table)>(),
@@ -64,8 +65,8 @@
   }
 }
 
-static void FillHuffmanTable(const JpegHuffmanTable* dc_table,
-                             const JpegHuffmanTable* ac_table,
+static void FillHuffmanTable(base::span<const JpegHuffmanTable> dc_table,
+                             base::span<const JpegHuffmanTable> ac_table,
                              VAHuffmanTableBufferJPEGBaseline* huffman_table) {
   // Use default huffman tables if not specified in header.
   bool has_huffman_table = false;
diff --git a/media/gpu/vaapi/vaapi_jpeg_encoder.cc b/media/gpu/vaapi/vaapi_jpeg_encoder.cc
index 359e74f..4b0242a 100644
--- a/media/gpu/vaapi/vaapi_jpeg_encoder.cc
+++ b/media/gpu/vaapi/vaapi_jpeg_encoder.cc
@@ -17,6 +17,7 @@
 #include <type_traits>
 
 #include "base/check_op.h"
+#include "base/containers/span.h"
 #include "base/numerics/safe_conversions.h"
 #include "media/gpu/macros.h"
 #include "media/gpu/vaapi/vaapi_wrapper.h"
@@ -138,7 +139,7 @@
                       const uint8_t* exif_buffer,
                       size_t exif_buffer_size,
                       int quality,
-                      uint8_t* header,
+                      base::span<uint8_t> header,
                       size_t* exif_offset) {
   unsigned int width = input_size.width();
   unsigned int height = input_size.height();
@@ -147,7 +148,7 @@
 
   // Start Of Input.
   static const uint8_t kSOI[] = {0xFF, JPEG_SOI};
-  memcpy(header, kSOI, sizeof(kSOI));
+  memcpy(header.data(), kSOI, sizeof(kSOI));
   idx += sizeof(kSOI);
 
   if (exif_buffer_size > 0) {
@@ -156,10 +157,10 @@
     const uint8_t kAppSegment[] = {
         0xFF, JPEG_APP1, static_cast<uint8_t>(exif_segment_size / 256),
         static_cast<uint8_t>(exif_segment_size % 256)};
-    memcpy(header + idx, kAppSegment, sizeof(kAppSegment));
+    memcpy(header.subspan(idx).data(), kAppSegment, sizeof(kAppSegment));
     idx += sizeof(kAppSegment);
     *exif_offset = idx;
-    memcpy(header + idx, exif_buffer, exif_buffer_size);
+    memcpy(header.subspan(idx).data(), exif_buffer, exif_buffer_size);
     idx += exif_buffer_size;
   } else {
     // Application Segment - JFIF standard 1.01.
@@ -182,7 +183,7 @@
         0x00,  // Thumbnail width.
         0x00   // Thumbnail height.
     };
-    memcpy(header + idx, kAppSegment, sizeof(kAppSegment));
+    memcpy(header.subspan(idx).data(), kAppSegment, sizeof(kAppSegment));
     idx += sizeof(kAppSegment);
   }
 
@@ -204,7 +205,7 @@
         static_cast<uint8_t>(i)  // Precision (4-bit high) = 0,
                                  // Index (4-bit low) = i.
     };
-    memcpy(header + idx, kQuantSegment, sizeof(kQuantSegment));
+    memcpy(header.subspan(idx).data(), kQuantSegment, sizeof(kQuantSegment));
     idx += sizeof(kQuantSegment);
 
     const JpegQuantizationTable& quant_table = kDefaultQuantTable[i];
@@ -237,7 +238,7 @@
       static_cast<uint8_t>(width & 0xFF),
       0x03,  // Number of Components.
   };
-  memcpy(header + idx, kStartOfFrame, sizeof(kStartOfFrame));
+  memcpy(header.subspan(idx).data(), kStartOfFrame, sizeof(kStartOfFrame));
   idx += sizeof(kStartOfFrame);
   for (uint8_t i = 0; i < 3; ++i) {
     // These are the values for U and V planes.
@@ -270,7 +271,7 @@
   // Huffman Tables.
   for (size_t i = 0; i < 2; ++i) {
     // DC Table.
-    memcpy(header + idx, kDcSegment, sizeof(kDcSegment));
+    memcpy(header.subspan(idx).data(), kDcSegment, sizeof(kDcSegment));
     idx += sizeof(kDcSegment);
 
     // Type (4-bit high) = 0:DC, Index (4-bit low).
@@ -283,7 +284,7 @@
       header[idx++] = dcTable.code_value[j];
 
     // AC Table.
-    memcpy(header + idx, kAcSegment, sizeof(kAcSegment));
+    memcpy(header.subspan(idx).data(), kAcSegment, sizeof(kAcSegment));
     idx += sizeof(kAcSegment);
 
     // Type (4-bit high) = 1:AC, Index (4-bit low).
@@ -302,7 +303,7 @@
       0x0C,  // Segment Length:12 (2-byte).
       0x03   // Number of components in scan.
   };
-  memcpy(header + idx, kStartOfScan, sizeof(kStartOfScan));
+  memcpy(header.subspan(idx).data(), kStartOfScan, sizeof(kStartOfScan));
   idx += sizeof(kStartOfScan);
 
   for (uint8_t i = 0; i < 3; ++i) {
@@ -379,7 +380,7 @@
   std::vector<uint8_t> jpeg_header(jpeg_header_size);
   const size_t length_in_bits =
       FillJpegHeader(input_size, exif_buffer, exif_buffer_size, quality,
-                     jpeg_header.data(), exif_offset);
+                     jpeg_header, exif_offset);
 
   VAEncPackedHeaderParameterBuffer header_param;
   memset(&header_param, 0, sizeof(header_param));
diff --git a/media/mojo/services/deferred_destroy_unique_receiver_set_unittest.cc b/media/mojo/services/deferred_destroy_unique_receiver_set_unittest.cc
index ec372cc..8a9573c 100644
--- a/media/mojo/services/deferred_destroy_unique_receiver_set_unittest.cc
+++ b/media/mojo/services/deferred_destroy_unique_receiver_set_unittest.cc
@@ -10,9 +10,12 @@
 #include "media/mojo/services/deferred_destroy_unique_receiver_set.h"
 
 #include <array>
+#include <cstdint>
 #include <memory>
 #include <utility>
 
+#include "base/containers/span.h"
+#include "base/numerics/safe_conversions.h"
 #include "base/run_loop.h"
 #include "base/test/task_environment.h"
 #include "mojo/public/interfaces/bindings/tests/ping_service.test-mojom.h"
@@ -69,12 +72,15 @@
 };
 
 TEST_F(DeferredDestroyUniqueReceiverSetTest, Destructor) {
-  mojo::PendingRemote<PingService> ping[2];
+  std::array<mojo::PendingRemote<PingService>, 2> ping;
   auto receivers =
       std::make_unique<DeferredDestroyUniqueReceiverSet<PingService>>();
 
   for (int i = 0; i < 2; ++i)
-    AddDeferredDestroyReceiver(receivers.get(), ping + i);
+    AddDeferredDestroyReceiver(
+        receivers.get(), base::span<mojo::PendingRemote<PingService>>(ping)
+                             .subspan(base::checked_cast<size_t>(i))
+                             .data());
   EXPECT_EQ(2, DeferredDestroyPingImpl::instance_count);
 
   receivers.reset();
@@ -82,13 +88,16 @@
 }
 
 TEST_F(DeferredDestroyUniqueReceiverSetTest, ConnectionError) {
-  mojo::PendingRemote<PingService> ping[4];
+  std::array<mojo::PendingRemote<PingService>, 4> ping;
   std::array<DeferredDestroyPingImpl*, 4> impl;
   auto receivers =
       std::make_unique<DeferredDestroyUniqueReceiverSet<PingService>>();
 
   for (int i = 0; i < 4; ++i)
-    impl[i] = AddDeferredDestroyReceiver(receivers.get(), ping + i);
+    impl[i] = AddDeferredDestroyReceiver(
+        receivers.get(), base::span<mojo::PendingRemote<PingService>>(ping)
+                             .subspan(base::checked_cast<size_t>(i))
+                             .data());
   EXPECT_EQ(4, DeferredDestroyPingImpl::instance_count);
 
   // Destroy deferred after disconnection until set_can_destroy()..
@@ -118,12 +127,15 @@
 }
 
 TEST_F(DeferredDestroyUniqueReceiverSetTest, CloseAllReceivers) {
-  mojo::PendingRemote<PingService> ping[3];
+  std::array<mojo::PendingRemote<PingService>, 3> ping;
   std::array<DeferredDestroyPingImpl*, 3> impl;
   DeferredDestroyUniqueReceiverSet<PingService> receivers;
 
   for (int i = 0; i < 2; ++i)
-    impl[i] = AddDeferredDestroyReceiver(&receivers, ping + i);
+    impl[i] = AddDeferredDestroyReceiver(
+        &receivers, base::span<mojo::PendingRemote<PingService>>(ping)
+                        .subspan(base::checked_cast<size_t>(i))
+                        .data());
   EXPECT_EQ(2, DeferredDestroyPingImpl::instance_count);
   EXPECT_FALSE(receivers.empty());
 
@@ -133,7 +145,9 @@
 
   // After CloseAllReceivers, new added receivers can still be deferred
   // destroyed.
-  impl[2] = AddDeferredDestroyReceiver(&receivers, ping + 2);
+  impl[2] = AddDeferredDestroyReceiver(
+      &receivers,
+      base::span<mojo::PendingRemote<PingService>>(ping).subspan(2u).data());
   EXPECT_EQ(1, DeferredDestroyPingImpl::instance_count);
 
   ping[2].reset();
diff --git a/media/parsers/h264_parser.cc b/media/parsers/h264_parser.cc
index c521f321..65dcef0 100644
--- a/media/parsers/h264_parser.cc
+++ b/media/parsers/h264_parser.cc
@@ -14,6 +14,7 @@
 #include <limits>
 #include <memory>
 
+#include "base/containers/span.h"
 #include "base/logging.h"
 #include "base/notreached.h"
 #include "base/numerics/safe_math.h"
diff --git a/media/parsers/h265_parser.cc b/media/parsers/h265_parser.cc
index 26cc64aba9..c5840f7 100644
--- a/media/parsers/h265_parser.cc
+++ b/media/parsers/h265_parser.cc
@@ -1155,7 +1155,7 @@
     // This is copying the dependent slice data that we do not parse below.
     size_t skip_amount = offsetof(H265SliceHeader, slice_type);
     // TODO(crbug.com/40285824): Find more graceful way to copy a part of the
-    // scturct
+    // struct
     UNSAFE_TODO(memcpy(reinterpret_cast<uint8_t*>(shdr) + skip_amount,
                        reinterpret_cast<uint8_t*>(prior_shdr) + skip_amount,
                        sizeof(H265SliceHeader) - skip_amount));
@@ -1443,7 +1443,7 @@
     size_t block_end = offsetof(H265SliceHeader, slice_sao_luma_flag);
 
     // TODO(crbug.com/40285824): Find more graceful way to compare a part of the
-    // scturct
+    // struct
     UNSAFE_TODO(TRUE_OR_RETURN(
         !memcmp(reinterpret_cast<uint8_t*>(shdr) + block_start,
                 reinterpret_cast<uint8_t*>(prior_shdr) + block_start,
diff --git a/media/parsers/jpeg_parser.cc b/media/parsers/jpeg_parser.cc
index 38191cf..431650c 100644
--- a/media/parsers/jpeg_parser.cc
+++ b/media/parsers/jpeg_parser.cc
@@ -204,9 +204,9 @@
 
 // |q_table| is already initialized to 0 in ParseJpegPicture.
 static bool ParseDQT(base::span<const uint8_t> buffer,
-                     JpegQuantizationTable* q_table) {
+                     base::span<JpegQuantizationTable> q_table) {
   // Spec B.2.4.1 Quantization table-specification syntax
-  DCHECK(q_table);
+  DCHECK(!q_table.empty());
   auto reader = base::SpanReader(buffer);
   while (reader.remaining() > 0u) {
     uint8_t precision_and_table_id;
@@ -238,11 +238,11 @@
 
 // |dc_table| and |ac_table| are already initialized to 0 in ParseJpegPicture.
 static bool ParseDHT(base::span<const uint8_t> buffer,
-                     JpegHuffmanTable* dc_table,
-                     JpegHuffmanTable* ac_table) {
+                     base::span<JpegHuffmanTable> dc_table,
+                     base::span<JpegHuffmanTable> ac_table) {
   // Spec B.2.4.2 Huffman table-specification syntax
-  DCHECK(dc_table);
-  DCHECK(ac_table);
+  DCHECK(!dc_table.empty());
+  DCHECK(!ac_table.empty());
   auto reader = base::SpanReader(buffer);
   while (reader.remaining() > 0u) {
     uint8_t table_class_and_id;
diff --git a/media/parsers/vp8_parser.cc b/media/parsers/vp8_parser.cc
index 7eaa751..54627fad 100644
--- a/media/parsers/vp8_parser.cc
+++ b/media/parsers/vp8_parser.cc
@@ -12,6 +12,7 @@
 
 #include "media/parsers/vp8_parser.h"
 
+#include <array>
 #include <cstring>
 
 #include "base/check_op.h"
@@ -703,17 +704,17 @@
   },
 };
 
-const uint8_t kMVUpdateProbs[kNumMVContexts][kNumMVProbs] =
-{
-  {
-    237, 246, 253, 253, 254, 254, 254, 254, 254,
-    254, 254, 254, 254, 254, 250, 250, 252, 254, 254,
-  },
-  {
-    231, 243, 245, 253, 254, 254, 254, 254, 254,
-    254, 254, 254, 254, 254, 251, 251, 254, 254, 254,
-  },
-};
+const std::array<std::array<const uint8_t, kNumMVProbs>, kNumMVContexts>
+    kMVUpdateProbs = {{
+        {
+            237, 246, 253, 253, 254, 254, 254, 254, 254, 254,
+            254, 254, 254, 254, 250, 250, 252, 254, 254,
+        },
+        {
+            231, 243, 245, 253, 254, 254, 254, 254, 254, 254,
+            254, 254, 254, 254, 251, 251, 254, 254, 254,
+        },
+    }};
 
 const uint8_t kDefaultMVProbs[kNumMVContexts][kNumMVProbs] = {
   {
diff --git a/media/parsers/vp8_parser.h b/media/parsers/vp8_parser.h
index 9f936ca..df68fd5 100644
--- a/media/parsers/vp8_parser.h
+++ b/media/parsers/vp8_parser.h
@@ -11,6 +11,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <array>
+
 #include "base/memory/raw_ptr.h"
 #include "media/base/media_export.h"
 #include "media/parsers/vp8_bool_decoder.h"
@@ -31,7 +33,7 @@
   bool update_segment_feature_data;
   SegmentFeatureMode segment_feature_mode;
 
-  int8_t quantizer_update_value[kMaxMBSegments];
+  std::array<int8_t, kMaxMBSegments> quantizer_update_value;
   int8_t lf_update_value[kMaxMBSegments];
   static const int kDefaultSegmentProb = 255;
   uint8_t segment_prob[kNumMBFeatureTreeProbs];
@@ -155,7 +157,7 @@
   raw_ptr<const uint8_t, AllowPtrArithmetic | DanglingUntriaged> data = nullptr;
   size_t frame_size = 0;
 
-  size_t dct_partition_sizes[kMaxDCTPartitions] = {};
+  std::array<size_t, kMaxDCTPartitions> dct_partition_sizes = {};
   // Offset in bytes from data.
   off_t first_part_offset = 0;
   // Offset in bits from first_part_offset.
diff --git a/media/parsers/vp9_parser.h b/media/parsers/vp9_parser.h
index 60bb0e9cb..ac494862 100644
--- a/media/parsers/vp9_parser.h
+++ b/media/parsers/vp9_parser.h
@@ -21,6 +21,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <array>
 #include <memory>
 
 #include "base/containers/circular_deque.h"
@@ -98,10 +99,10 @@
   bool update_data;
   bool abs_or_delta_update;
   bool feature_enabled[kNumSegments][SEG_LVL_MAX];
-  int16_t feature_data[kNumSegments][SEG_LVL_MAX];
+  std::array<std::array<int16_t, SEG_LVL_MAX>, kNumSegments> feature_data;
 
-  int16_t y_dequant[kNumSegments][2];
-  int16_t uv_dequant[kNumSegments][2];
+  std::array<std::array<int16_t, 2>, kNumSegments> y_dequant;
+  std::array<std::array<int16_t, 2>, kNumSegments> uv_dequant;
 
   bool FeatureEnabled(size_t seg_id, SegmentLevelFeature feature) const {
     return feature_enabled[seg_id][feature];
@@ -120,9 +121,9 @@
 
   bool delta_enabled;
   bool delta_update;
-  bool update_ref_deltas[VP9_FRAME_MAX];
-  int8_t ref_deltas[VP9_FRAME_MAX];
-  bool update_mode_deltas[kNumModeDeltas];
+  std::array<bool, VP9_FRAME_MAX> update_ref_deltas;
+  std::array<int8_t, VP9_FRAME_MAX> ref_deltas;
+  std::array<bool, kNumModeDeltas> update_mode_deltas;
   int8_t mode_deltas[kNumModeDeltas];
 
   // Calculated from above fields.
@@ -222,7 +223,7 @@
   bool intra_only = false;
   uint8_t reset_frame_context = 0;
   uint8_t refresh_frame_flags = 0;
-  uint8_t ref_frame_idx[kVp9NumRefsPerFrame] = {};
+  std::array<uint8_t, kVp9NumRefsPerFrame> ref_frame_idx = {};
   bool ref_frame_sign_bias[Vp9RefType::VP9_FRAME_MAX] = {false};
   bool allow_high_precision_mv = false;
   Vp9InterpolationFilter interpolation_filter{Vp9InterpolationFilter::EIGHTTAP};
diff --git a/media/remoting/fake_remoter.cc b/media/remoting/fake_remoter.cc
index e60deb17..13e81bf5 100644
--- a/media/remoting/fake_remoter.cc
+++ b/media/remoting/fake_remoter.cc
@@ -11,6 +11,7 @@
 
 #include <memory>
 
+#include "base/containers/span.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "base/functional/callback_helpers.h"
@@ -84,7 +85,7 @@
 
   // Checks if frame buffer is correct or not.
   bool return_value = true;
-  const uint8_t* buffer = media_buffer_span.data();
+  base::span<const uint8_t> buffer = media_buffer_span;
   for (size_t i = 0; i < media_buffer_span.size(); ++i) {
     uint32_t value = static_cast<uint32_t>(i & 0xFF);
     if (value != static_cast<uint32_t>(buffer[i])) {
diff --git a/media/renderers/paint_canvas_video_renderer_unittest.cc b/media/renderers/paint_canvas_video_renderer_unittest.cc
index 960a191..fc5f84f 100644
--- a/media/renderers/paint_canvas_video_renderer_unittest.cc
+++ b/media/renderers/paint_canvas_video_renderer_unittest.cc
@@ -15,6 +15,7 @@
 #include <array>
 
 #include "base/containers/heap_array.h"
+#include "base/containers/span.h"
 #include "base/functional/bind.h"
 #include "base/logging.h"
 #include "base/memory/aligned_memory.h"
@@ -103,9 +104,9 @@
 
 // Returns a functor that retrieves a SkColor for a given pixel, from raw RGBA
 // data.
-static auto ColorGetter(uint8_t* pixels, const gfx::Size& size) {
+static auto ColorGetter(base::span<uint8_t> pixels, const gfx::Size& size) {
   return [pixels, size](size_t x, size_t y) {
-    uint8_t* p = pixels + (size.width() * y + x) * 4;
+    base::span<uint8_t> p = pixels.subspan((size.width() * y + x) * 4);
     return SkColorSetARGB(p[3], p[0], p[1], p[2]);
   };
 }
@@ -1323,7 +1324,7 @@
 
   base::HeapArray<uint8_t> pixels =
       ReadbackTexture(destination_gl, texture, expected_size);
-  auto get_color = ColorGetter(pixels.data(), expected_size);
+  auto get_color = ColorGetter(pixels, expected_size);
 
   // Avoid checking around the seams.
   EXPECT_EQ(SK_ColorBLACK, get_color(0, 0));
@@ -1355,7 +1356,7 @@
 
   base::HeapArray<uint8_t> pixels =
       ReadbackTexture(destination_gl, texture, expected_size);
-  auto get_color = ColorGetter(pixels.data(), expected_size);
+  auto get_color = ColorGetter(pixels, expected_size);
 
   // Avoid checking around the seams.
   EXPECT_EQ(SK_ColorBLACK, get_color(0, 5));
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc
index 9f67288..e95670d 100644
--- a/media/video/gpu_memory_buffer_video_frame_pool.cc
+++ b/media/video/gpu_memory_buffer_video_frame_pool.cc
@@ -17,6 +17,7 @@
 #include <algorithm>
 #include <array>
 #include <atomic>
+#include <cstdint>
 #include <list>
 #include <memory>
 #include <utility>
@@ -25,6 +26,7 @@
 #include "base/bits.h"
 #include "base/command_line.h"
 #include "base/containers/circular_deque.h"
+#include "base/containers/span.h"
 #include "base/feature_list.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
@@ -35,6 +37,7 @@
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/not_fatal_until.h"
+#include "base/numerics/safe_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/time/default_tick_clock.h"
@@ -346,35 +349,36 @@
   return std::max<size_t>((kBytesPerCopyTarget / bytes_per_row) & ~1, 1);
 }
 
-void CopyRowsToI420Buffer(int first_row,
-                          int rows,
-                          int bytes_per_row,
+void CopyRowsToI420Buffer(size_t first_row,
+                          size_t rows,
+                          size_t bytes_per_row,
                           size_t bit_depth,
                           const uint8_t* source,
-                          int source_stride,
-                          uint8_t* output,
-                          int dest_stride) {
+                          size_t source_stride,
+                          base::span<uint8_t> output,
+                          size_t dest_stride) {
   TRACE_EVENT2("media", "CopyRowsToI420Buffer", "bytes_per_row", bytes_per_row,
                "rows", rows);
 
-  if (!output)
+  if (output.empty()) {
     return;
+  }
 
-  DCHECK_NE(dest_stride, 0);
-  DCHECK_LE(bytes_per_row, std::abs(dest_stride));
+  DCHECK_NE(dest_stride, 0u);
+  DCHECK_LE(bytes_per_row, dest_stride);
   DCHECK_LE(bytes_per_row, source_stride);
   DCHECK_GE(bit_depth, 8u);
 
-  if (bit_depth == 8) {
+  if (bit_depth == 8u) {
     libyuv::CopyPlane(source + source_stride * first_row, source_stride,
-                      output + dest_stride * first_row, dest_stride,
-                      bytes_per_row, rows);
+                      output.subspan(dest_stride * first_row).data(),
+                      dest_stride, bytes_per_row, rows);
   } else {
-    const int scale = 0x10000 >> (bit_depth - 8);
+    const int scale = 0x10000 >> (bit_depth - 8u);
     libyuv::Convert16To8Plane(
         reinterpret_cast<const uint16_t*>(source + source_stride * first_row),
-        source_stride / 2, output + dest_stride * first_row, dest_stride, scale,
-        bytes_per_row, rows);
+        source_stride / 2, output.subspan(dest_stride * first_row).data(),
+        dest_stride, scale, bytes_per_row, rows);
   }
 }
 
@@ -382,14 +386,15 @@
                           int rows,
                           int width,
                           const VideoFrame* source_frame,
-                          uint8_t* dest_y,
+                          base::span<uint8_t> dest_y,
                           int dest_stride_y,
-                          uint8_t* dest_uv,
+                          base::span<uint8_t> dest_uv,
                           int dest_stride_uv) {
   TRACE_EVENT2("media", "CopyRowsToP010Buffer", "width", width, "rows", rows);
 
-  if (!dest_y || !dest_uv)
+  if (dest_y.empty() || dest_uv.empty()) {
     return;
+  }
 
   DCHECK_NE(dest_stride_y, 0);
   DCHECK_NE(dest_stride_uv, 0);
@@ -413,9 +418,14 @@
 
   libyuv::I010ToP010(
       y_plane, y_plane_stride, u_plane, u_plane_stride, v_plane, v_plane_stride,
-      reinterpret_cast<uint16_t*>(dest_y + first_row * dest_stride_y),
+      reinterpret_cast<uint16_t*>(
+          dest_y.subspan(base::checked_cast<size_t>(first_row * dest_stride_y))
+              .data()),
       dest_stride_y / 2,
-      reinterpret_cast<uint16_t*>(dest_uv + (first_row / 2) * dest_stride_uv),
+      reinterpret_cast<uint16_t*>(dest_uv
+                                      .subspan(base::checked_cast<size_t>(
+                                          (first_row / 2) * dest_stride_uv))
+                                      .data()),
       dest_stride_uv / 2, width, rows);
 }
 
@@ -424,14 +434,15 @@
                           int width,
                           size_t bit_depth,
                           const VideoFrame* source_frame,
-                          uint8_t* dest_y,
+                          base::span<uint8_t> dest_y,
                           int dest_stride_y,
-                          uint8_t* dest_uv,
+                          base::span<uint8_t> dest_uv,
                           int dest_stride_uv) {
   TRACE_EVENT2("media", "CopyRowsToNV12Buffer", "width", width, "rows", rows);
 
-  if (!dest_y || !dest_uv)
+  if (dest_y.empty() || dest_uv.empty()) {
     return;
+  }
 
   DCHECK_NE(dest_stride_y, 0);
   DCHECK_NE(dest_stride_uv, 0);
@@ -458,14 +469,18 @@
           source_frame->visible_data(VideoFrame::Plane::kY) +
               first_row * source_frame->stride(VideoFrame::Plane::kY),
           source_frame->stride(VideoFrame::Plane::kY),
-          dest_y + first_row * dest_stride_y, dest_stride_y, bytes_per_row_y,
-          rows_y);
+          dest_y.subspan(base::checked_cast<size_t>(first_row * dest_stride_y))
+              .data(),
+          dest_stride_y, bytes_per_row_y, rows_y);
       libyuv::CopyPlane(
           source_frame->visible_data(VideoFrame::Plane::kUV) +
               first_row / 2 * source_frame->stride(VideoFrame::Plane::kUV),
           source_frame->stride(VideoFrame::Plane::kUV),
-          dest_uv + first_row / 2 * dest_stride_uv, dest_stride_uv,
-          bytes_per_row_uv, rows_uv);
+          dest_uv
+              .subspan(
+                  base::checked_cast<size_t>(first_row / 2 * dest_stride_uv))
+              .data(),
+          dest_stride_uv, bytes_per_row_uv, rows_uv);
 
       return;
     }
@@ -480,9 +495,13 @@
         source_frame->visible_data(VideoFrame::Plane::kV) +
             first_row / 2 * source_frame->stride(VideoFrame::Plane::kV),
         source_frame->stride(VideoFrame::Plane::kV),
-        dest_y + first_row * dest_stride_y, dest_stride_y,
-        dest_uv + first_row / 2 * dest_stride_uv, dest_stride_uv,
-        bytes_per_row_y, rows_y);
+        dest_y.subspan(base::checked_cast<size_t>(first_row * dest_stride_y))
+            .data(),
+        dest_stride_y,
+        dest_uv
+            .subspan(base::checked_cast<size_t>(first_row / 2 * dest_stride_uv))
+            .data(),
+        dest_stride_uv, bytes_per_row_y, rows_y);
   } else {
     DCHECK_LE(static_cast<size_t>(width * 2),
               source_frame->stride(VideoFrame::Plane::kY));
@@ -503,11 +522,17 @@
     const size_t v_plane_stride =
         source_frame->stride(VideoFrame::Plane::kV) / 2;
 
-    libyuv::I010ToNV12(y_plane, y_plane_stride, u_plane, u_plane_stride,
-                       v_plane, v_plane_stride,
-                       dest_y + first_row * dest_stride_y, dest_stride_y,
-                       dest_uv + (first_row / 2) * dest_stride_uv,
-                       dest_stride_uv, width, rows);
+    libyuv::I010ToNV12(
+        y_plane, y_plane_stride, u_plane, u_plane_stride, v_plane,
+        v_plane_stride,
+        dest_y.subspan(base::checked_cast<size_t>(first_row * dest_stride_y))
+            .data(),
+        dest_stride_y,
+        dest_uv
+            .subspan(
+                base::checked_cast<size_t>((first_row / 2) * dest_stride_uv))
+            .data(),
+        dest_stride_uv, width, rows);
   }
 }
 
@@ -516,12 +541,13 @@
                            int rows,
                            int width,
                            const VideoFrame* source_frame,
-                           uint8_t* output,
+                           base::span<uint8_t> output,
                            int dest_stride) {
   TRACE_EVENT2("media", "CopyRowsToRGB10Buffer", "bytes_per_row", width * 2,
                "rows", rows);
-  if (!output)
+  if (output.empty()) {
     return;
+  }
 
   DCHECK_NE(dest_stride, 0);
   DCHECK_LE(width, std::abs(dest_stride / 2));
@@ -542,7 +568,9 @@
   size_t u_plane_stride = source_frame->stride(VideoFrame::Plane::kU) / 2;
   size_t v_plane_stride = source_frame->stride(VideoFrame::Plane::kV) / 2;
 
-  uint8_t* dest_rgb10 = output + first_row * dest_stride;
+  uint8_t* dest_rgb10 =
+      output.subspan(base::checked_cast<size_t>(first_row * dest_stride))
+          .data();
 
   SkYUVColorSpace yuv_cs = kRec601_Limited_SkYUVColorSpace;
   source_frame->ColorSpace().ToSkYUVColorSpace(source_frame->BitDepth(),
@@ -907,7 +935,7 @@
   auto* scoped_mapping = frame_resource->scoped_mapping.get();
 
   // To handle plane 0 of the underlying buffer.
-  uint8_t* memory_ptr0 = scoped_mapping->GetMemoryForPlane(0).data();
+  base::span<uint8_t> memory_ptr0 = scoped_mapping->GetMemoryForPlane(0);
   size_t stride0 = scoped_mapping->Stride(0);
 
   switch (output_format) {
@@ -932,12 +960,12 @@
         const size_t plane_bytes_per_row =
             VideoFrame::RowBytes(src_plane, pixel_format, coded_size.width());
 
-        CopyRowsToI420Buffer(
-            plane_row_start, plane_rows_to_copy, plane_bytes_per_row,
-            video_frame->BitDepth(), video_frame->visible_data(src_plane),
-            video_frame->stride(src_plane),
-            scoped_mapping->GetMemoryForPlane(dst_plane).data(),
-            scoped_mapping->Stride(dst_plane));
+        CopyRowsToI420Buffer(plane_row_start, plane_rows_to_copy,
+                             plane_bytes_per_row, video_frame->BitDepth(),
+                             video_frame->visible_data(src_plane),
+                             video_frame->stride(src_plane),
+                             scoped_mapping->GetMemoryForPlane(dst_plane),
+                             scoped_mapping->Stride(dst_plane));
       }
       break;
     }
@@ -945,14 +973,14 @@
     case GpuVideoAcceleratorFactories::OutputFormat::P010:
       CopyRowsToP010Buffer(row, rows_to_copy, coded_size.width(), video_frame,
                            memory_ptr0, stride0,
-                           scoped_mapping->GetMemoryForPlane(1).data(),
+                           scoped_mapping->GetMemoryForPlane(1),
                            scoped_mapping->Stride(1));
       break;
 
     case GpuVideoAcceleratorFactories::OutputFormat::NV12:
       CopyRowsToNV12Buffer(row, rows_to_copy, coded_size.width(),
                            video_frame->BitDepth(), video_frame, memory_ptr0,
-                           stride0, scoped_mapping->GetMemoryForPlane(1).data(),
+                           stride0, scoped_mapping->GetMemoryForPlane(1),
                            scoped_mapping->Stride(1));
       break;
     case GpuVideoAcceleratorFactories::OutputFormat::XB30:
diff --git a/net/base/cache_type.h b/net/base/cache_type.h
index 480a47af..11648d15 100644
--- a/net/base/cache_type.h
+++ b/net/base/cache_type.h
@@ -5,6 +5,8 @@
 #ifndef NET_BASE_CACHE_TYPE_H_
 #define NET_BASE_CACHE_TYPE_H_
 
+#include "net/disk_cache/buildflags.h"
+
 namespace net {
 
 // The types of caches that can be created.
@@ -29,7 +31,10 @@
 enum BackendType {
   CACHE_BACKEND_DEFAULT,
   CACHE_BACKEND_BLOCKFILE,  // The |BackendImpl|.
-  CACHE_BACKEND_SIMPLE  // The |SimpleBackendImpl|.
+  CACHE_BACKEND_SIMPLE,     // The |SimpleBackendImpl|.
+#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
+  CACHE_BACKEND_EXPERIMENTAL_SQL,
+#endif  // ENABLE_DISK_CACHE_SQL_BACKEND
 };
 
 }  // namespace net
diff --git a/net/base/features.cc b/net/base/features.cc
index 3b08a7a..18af067f 100644
--- a/net/base/features.cc
+++ b/net/base/features.cc
@@ -10,6 +10,7 @@
 #include "base/feature_list.h"
 #include "build/build_config.h"
 #include "net/base/cronet_buildflags.h"
+#include "net/disk_cache/buildflags.h"
 #include "net/net_buildflags.h"
 
 #if BUILDFLAG(IS_WIN)
@@ -719,11 +720,15 @@
              base::FEATURE_DISABLED_BY_DEFAULT);
 constexpr base::FeatureParam<DiskCacheBackend>::Option
     kDiskCacheBackendOptions[] = {
+        {DiskCacheBackend::kDefault, "default"},
         {DiskCacheBackend::kSimple, "simple"},
         {DiskCacheBackend::kBlockfile, "blockfile"},
+#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
+        {DiskCacheBackend::kSql, "sql"},
+#endif  // ENABLE_DISK_CACHE_SQL_BACKEND
 };
 const base::FeatureParam<DiskCacheBackend> kDiskCacheBackendParam{
-    &kDiskCacheBackendExperiment, "backend", DiskCacheBackend::kBlockfile,
+    &kDiskCacheBackendExperiment, "backend", DiskCacheBackend::kDefault,
     &kDiskCacheBackendOptions};
 
 BASE_FEATURE(kIgnoreHSTSForLocalhost,
@@ -848,6 +853,11 @@
                    "http_proxy_connect_job",
                    false);
 BASE_FEATURE_PARAM(bool,
+                   kNetTaskSchedulerHttpCacheTransaction,
+                   &kNetTaskScheduler,
+                   "http_cache_transaction",
+                   false);
+BASE_FEATURE_PARAM(bool,
                    kNetTaskSchedulerHttpStreamFactoryJob,
                    &kNetTaskScheduler,
                    "http_stream_factory_job",
diff --git a/net/base/features.h b/net/base/features.h
index 0b674b7..441d85f2 100644
--- a/net/base/features.h
+++ b/net/base/features.h
@@ -16,6 +16,7 @@
 #include "build/build_config.h"
 #include "crypto/crypto_buildflags.h"
 #include "net/base/net_export.h"
+#include "net/disk_cache/buildflags.h"
 #include "net/net_buildflags.h"
 
 namespace net::features {
@@ -742,8 +743,12 @@
 
 // Finch experiment to select a disk cache backend.
 enum class DiskCacheBackend {
+  kDefault,
   kSimple,
   kBlockfile,
+#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
+  kSql,
+#endif  // ENABLE_DISK_CACHE_SQL_BACKEND
 };
 NET_EXPORT BASE_DECLARE_FEATURE(kDiskCacheBackendExperiment);
 NET_EXPORT extern const base::FeatureParam<DiskCacheBackend>
@@ -864,6 +869,8 @@
 // for specific classes.
 NET_EXPORT BASE_DECLARE_FEATURE(kNetTaskScheduler);
 NET_EXPORT BASE_DECLARE_FEATURE_PARAM(bool,
+                                      kNetTaskSchedulerHttpCacheTransaction);
+NET_EXPORT BASE_DECLARE_FEATURE_PARAM(bool,
                                       kNetTaskSchedulerHttpProxyConnectJob);
 NET_EXPORT BASE_DECLARE_FEATURE_PARAM(bool,
                                       kNetTaskSchedulerHttpStreamFactoryJob);
diff --git a/net/base/proxy_chain.cc b/net/base/proxy_chain.cc
index 0dc4b6d..c40fc7f 100644
--- a/net/base/proxy_chain.cc
+++ b/net/base/proxy_chain.cc
@@ -31,9 +31,7 @@
 }
 }  // namespace
 
-ProxyChain::ProxyChain() {
-  proxy_server_list_ = std::nullopt;
-}
+ProxyChain::ProxyChain() = default;
 
 ProxyChain::ProxyChain(const ProxyChain& other) = default;
 ProxyChain::ProxyChain(ProxyChain&& other) noexcept = default;
@@ -56,25 +54,30 @@
   }
 }
 
-bool ProxyChain::InitFromPickle(base::PickleIterator* pickle_iter) {
-  if (!pickle_iter->ReadInt(&ip_protection_chain_id_)) {
-    return false;
+// static
+std::optional<ProxyChain> ProxyChain::InitFromPickle(
+    base::PickleIterator& pickle_iter) {
+  int ip_protection_chain_id;
+  if (!pickle_iter.ReadInt(&ip_protection_chain_id)) {
+    return std::nullopt;
   }
   size_t chain_length = 0;
-  if (!pickle_iter->ReadLength(&chain_length)) {
-    return false;
+  if (!pickle_iter.ReadLength(&chain_length)) {
+    return std::nullopt;
   }
 
   std::vector<ProxyServer> proxy_server_list;
   for (size_t i = 0; i < chain_length; ++i) {
-    proxy_server_list.push_back(ProxyServer::CreateFromPickle(pickle_iter));
+    proxy_server_list.push_back(ProxyServer::CreateFromPickle(&pickle_iter));
   }
-  proxy_server_list_ = std::move(proxy_server_list);
-  if (!IsValidInternal()) {
-    proxy_server_list_ = std::nullopt;
-    return false;
+
+  ProxyChain chain =
+      ProxyChain(std::move(proxy_server_list), ip_protection_chain_id,
+                 /*opaque_data=*/std::nullopt);
+  if (!chain.IsValid()) {
+    return std::nullopt;
   }
-  return true;
+  return chain;
 }
 
 void ProxyChain::Persist(base::Pickle* pickle) const {
@@ -107,15 +110,19 @@
   ProxyChain new_chain =
       ProxyChain({proxy_server_list_->begin(), proxy_server_list_->end() - 1},
                  ip_protection_chain_id_, opaque_data_);
-  return std::make_pair(new_chain, std::ref(proxy_server_list_->back()));
+  CHECK(new_chain.IsValid());
+  return std::make_pair(std::move(new_chain),
+                        std::ref(proxy_server_list_->back()));
 }
 
 ProxyChain ProxyChain::Prefix(size_t len) const {
   DCHECK(IsValid());
   DCHECK_LE(len, length());
-  return ProxyChain(
+  auto new_chain = ProxyChain(
       {proxy_server_list_->begin(), proxy_server_list_->begin() + len},
       ip_protection_chain_id_, opaque_data_);
+  CHECK(new_chain.IsValid());
+  return new_chain;
 }
 
 const ProxyServer& ProxyChain::First() const {
@@ -162,7 +169,9 @@
     : proxy_server_list_(std::move(proxy_server_list)),
       ip_protection_chain_id_(ip_protection_chain_id),
       opaque_data_(opaque_data) {
-  CHECK(IsValidInternal());
+  if (!IsValidInternal()) {
+    *this = ProxyChain();
+  }
 }
 
 bool ProxyChain::IsValidInternal() const {
diff --git a/net/base/proxy_chain.h b/net/base/proxy_chain.h
index dd1c219..8b8d3ee 100644
--- a/net/base/proxy_chain.h
+++ b/net/base/proxy_chain.h
@@ -74,6 +74,8 @@
   // Creates a `ProxyChain` for use by the IP Protection feature. This is used
   // for metrics collection and for special handling.  If not given, the
   // chain_id defaults to 0 which corresponds to an un-identified chain.
+  // If the resulting `ProxyChain` is deemed to be invalid, an invalid
+  // `ProxyChain` is returned and `chain_id` is not used.
   static ProxyChain ForIpProtection(std::vector<ProxyServer> proxy_server_list,
                                     int chain_id = 0) {
     return ProxyChain(std::move(proxy_server_list), chain_id,
@@ -81,7 +83,9 @@
   }
 
   // Creates a `ProxyChain` with `opaque_data` attached to it. This can be later
-  // on retrieved via `opaque_data()`.
+  // on retrieved via `opaque_data()`. If the resulting `ProxyChain` is deemed
+  // to be invalid, an invalid `ProxyChain` is returned and `opaque_data` is not
+  // used.
   static ProxyChain WithOpaqueData(std::vector<ProxyServer> proxy_server_list,
                                    int opaque_data) {
     return ProxyChain(std::move(proxy_server_list),
@@ -89,11 +93,12 @@
                       opaque_data);
   }
 
-  // Initialize from a pickle that contains data generated by a call to the
-  // `Persist` method.
+  // Attempt to create a new `ProxyChain` from a pickle that contains data
+  // generated by a call to the `Persist` method.
   //
-  // Returns true upon success, otherwise returns false.
-  bool InitFromPickle(base::PickleIterator* pickle_iter);
+  // Returns a `ProxyChain` upon success, otherwise returns `std::nullopt`.
+  static std::optional<ProxyChain> InitFromPickle(
+      base::PickleIterator& pickle_iter);
 
   // Call this method to persist `ProxyChain`. Illegal to call this on an
   // invalid object.
diff --git a/net/base/proxy_chain_unittest.cc b/net/base/proxy_chain_unittest.cc
index 8c49be2ea0..23e559f 100644
--- a/net/base/proxy_chain_unittest.cc
+++ b/net/base/proxy_chain_unittest.cc
@@ -446,7 +446,7 @@
   // sequence of schemes.
   EXPECT_FALSE(ProxyChain({https1, quic2}).IsValid());
   EXPECT_FALSE(ProxyChain({https1, https2, quic1, quic2}).IsValid());
-  // ProxyChain cannot contains socks server. Only QUIC and HTTPS.
+  // Multi-hop ProxyChains cannot contain a SOCKS server. Only QUIC and HTTPS.
   EXPECT_FALSE(ProxyChain({socks, https1}).IsValid());
   EXPECT_FALSE(ProxyChain({socks, https1, https2}).IsValid());
   EXPECT_FALSE(ProxyChain({https1, socks}).IsValid());
@@ -460,18 +460,15 @@
   EXPECT_TRUE(
       ProxyChain::ForIpProtection({quic1, quic2, https1, https2}).IsValid());
 
-  // IP protection CHECKs on failure instead of just creating an invalid chain.
   // QUIC cannot follow HTTPS proxy server.
-  EXPECT_CHECK_DEATH(ProxyChain::ForIpProtection({https1, quic2}).IsValid());
-  EXPECT_CHECK_DEATH(
+  EXPECT_FALSE(ProxyChain::ForIpProtection({https1, quic2}).IsValid());
+  EXPECT_FALSE(
       ProxyChain::ForIpProtection({https1, https2, quic1, quic2}).IsValid());
   // Socks proxy server is not valid for multi-proxy chain.
-  EXPECT_CHECK_DEATH(ProxyChain::ForIpProtection({socks, https1}).IsValid());
-  EXPECT_CHECK_DEATH(
-      ProxyChain::ForIpProtection({socks, https1, https2}).IsValid());
-  EXPECT_CHECK_DEATH(ProxyChain::ForIpProtection({https1, socks}).IsValid());
-  EXPECT_CHECK_DEATH(
-      ProxyChain::ForIpProtection({https1, https2, socks}).IsValid());
+  EXPECT_FALSE(ProxyChain::ForIpProtection({socks, https1}).IsValid());
+  EXPECT_FALSE(ProxyChain::ForIpProtection({socks, https1, https2}).IsValid());
+  EXPECT_FALSE(ProxyChain::ForIpProtection({https1, socks}).IsValid());
+  EXPECT_FALSE(ProxyChain::ForIpProtection({https1, https2, socks}).IsValid());
 
 #if !BUILDFLAG(ENABLE_BRACKETED_PROXY_URIS)
   bool multi_proxy_chain_supported = false;
@@ -502,6 +499,11 @@
             is_multi_proxy_quic_supported);
   EXPECT_EQ(ProxyChain({quic1, quic2, https1, https2}).IsValid(),
             is_multi_proxy_quic_supported);
+
+  // `ProxyChain::WithOpaqueData` should not crash when the proxy server list
+  // is invalid.
+  EXPECT_FALSE(ProxyChain::WithOpaqueData({https1, quic2}, /*opaque_data=*/123)
+                   .IsValid());
 }
 
 TEST(ProxyChainTest, Unequal) {
@@ -582,9 +584,24 @@
   base::Pickle pickle;
   proxy_chain.Persist(&pickle);
   base::PickleIterator iter(pickle);
-  ProxyChain proxy_chain_from_pickle;
-  EXPECT_TRUE(proxy_chain_from_pickle.InitFromPickle(&iter));
-  EXPECT_EQ(proxy_chain, proxy_chain_from_pickle);
+  std::optional<ProxyChain> proxy_chain_from_pickle =
+      ProxyChain::InitFromPickle(iter);
+  ASSERT_TRUE(proxy_chain_from_pickle);
+  EXPECT_EQ(proxy_chain, *proxy_chain_from_pickle);
+}
+
+TEST(ProxyChainTest, PickleDirectIpProtection) {
+  ProxyChain proxy_chain =
+      ProxyChain::ForIpProtection(/*proxy_server_list=*/{});
+  base::Pickle pickle;
+  proxy_chain.Persist(&pickle);
+  base::PickleIterator iter(pickle);
+  std::optional<ProxyChain> proxy_chain_from_pickle =
+      ProxyChain::InitFromPickle(iter);
+  ASSERT_TRUE(proxy_chain_from_pickle);
+  EXPECT_EQ(proxy_chain, *proxy_chain_from_pickle);
+  EXPECT_TRUE(proxy_chain_from_pickle->is_for_ip_protection());
+  EXPECT_TRUE(proxy_chain_from_pickle->is_direct());
 }
 
 TEST(ProxyChainTest, PickleOneProxy) {
@@ -593,26 +610,54 @@
   base::Pickle pickle;
   proxy_chain.Persist(&pickle);
   base::PickleIterator iter(pickle);
-  ProxyChain proxy_chain_from_pickle;
-  EXPECT_TRUE(proxy_chain_from_pickle.InitFromPickle(&iter));
-  EXPECT_EQ(proxy_chain, proxy_chain_from_pickle);
+  std::optional<ProxyChain> proxy_chain_from_pickle =
+      ProxyChain::InitFromPickle(iter);
+  ASSERT_TRUE(proxy_chain_from_pickle);
+  EXPECT_EQ(proxy_chain, *proxy_chain_from_pickle);
+}
+
+TEST(ProxyChainTest, PickleOneProxyIpProtection) {
+  ProxyChain proxy_chain = ProxyChain::ForIpProtection(
+      {ProxyUriToProxyServer("foo:11", ProxyServer::SCHEME_HTTPS)});
+  base::Pickle pickle;
+  proxy_chain.Persist(&pickle);
+  base::PickleIterator iter(pickle);
+  std::optional<ProxyChain> proxy_chain_from_pickle =
+      ProxyChain::InitFromPickle(iter);
+  ASSERT_TRUE(proxy_chain_from_pickle);
+  EXPECT_EQ(proxy_chain, *proxy_chain_from_pickle);
 }
 
 TEST(ProxyChainTest, UnpickleInvalidProxy) {
   ProxyServer invalid_proxy_server;
-  // Manually pickle a proxcy chain with an invalid proxy server.
+  // Manually pickle a proxy chain with an invalid proxy server.
   base::Pickle pickle;
   pickle.WriteInt(ProxyChain::kNotIpProtectionChainId);
   pickle.WriteInt(1);  // Length of the chain
   invalid_proxy_server.Persist(&pickle);
 
   base::PickleIterator iter(pickle);
-  ProxyChain invalid_proxy_chain_from_pickle;
   // Unpickling should fail and leave us with an invalid proxy chain.
-  EXPECT_FALSE(invalid_proxy_chain_from_pickle.InitFromPickle(&iter));
+  EXPECT_FALSE(ProxyChain::InitFromPickle(iter));
   // Make sure that we unpickled the invalid proxy server.
   EXPECT_TRUE(iter.ReachedEnd());
-  EXPECT_FALSE(invalid_proxy_chain_from_pickle.IsValid());
+}
+
+// Same as above, but with an IP Protection chain ID. For consistency we'd like
+// the invalid proxy chain to match the default constructed one even if
+// unpickling fails for IP Protection chains.
+TEST(ProxyChainTest, UnpickleInvalidProxyIpProtection) {
+  ProxyServer invalid_proxy_server;
+  base::Pickle pickle;
+  pickle.WriteInt(ProxyChain::kMaxIpProtectionChainId);
+  pickle.WriteInt(1);  // Length of the chain
+  invalid_proxy_server.Persist(&pickle);
+
+  base::PickleIterator iter(pickle);
+  // Unpickling should fail and leave us with an invalid proxy chain.
+  EXPECT_FALSE(ProxyChain::InitFromPickle(iter));
+  // Make sure that we unpickled the invalid proxy server.
+  EXPECT_TRUE(iter.ReachedEnd());
 }
 
 #if !BUILDFLAG(ENABLE_BRACKETED_PROXY_URIS)
@@ -691,11 +736,26 @@
   base::Pickle pickle;
   proxy_chain.Persist(&pickle);
   base::PickleIterator iter(pickle);
-  ProxyChain proxy_chain_from_pickle;
-  EXPECT_TRUE(proxy_chain_from_pickle.InitFromPickle(&iter));
-  EXPECT_EQ(proxy_chain, proxy_chain_from_pickle);
+  std::optional<ProxyChain> proxy_chain_from_pickle =
+      ProxyChain::InitFromPickle(iter);
+  ASSERT_TRUE(proxy_chain_from_pickle);
+  EXPECT_EQ(proxy_chain, *proxy_chain_from_pickle);
 }
-#endif
+#endif  // BUILDFLAG(ENABLE_BRACKETED_PROXY_URIS)
+
+TEST(ProxyChainTest, UnpickleTwoProxiesIpProtection) {
+  ProxyChain proxy_chain = ProxyChain::ForIpProtection(
+      {ProxyUriToProxyServer("foo:11", ProxyServer::SCHEME_HTTPS),
+       ProxyUriToProxyServer("foo:22", ProxyServer::SCHEME_HTTPS)});
+
+  base::Pickle pickle;
+  proxy_chain.Persist(&pickle);
+  base::PickleIterator iter(pickle);
+  std::optional<ProxyChain> proxy_chain_from_pickle =
+      ProxyChain::InitFromPickle(iter);
+  ASSERT_TRUE(proxy_chain_from_pickle);
+  EXPECT_EQ(proxy_chain, *proxy_chain_from_pickle);
+}
 
 }  // namespace
 
diff --git a/net/cert/internal/trust_store_chrome.h b/net/cert/internal/trust_store_chrome.h
index 53e2c7fc..24db9871 100644
--- a/net/cert/internal/trust_store_chrome.h
+++ b/net/cert/internal/trust_store_chrome.h
@@ -14,10 +14,13 @@
 #include "base/version.h"
 #include "crypto/sha2.h"
 #include "net/base/net_export.h"
-#include "net/cert/root_store_proto_lite/root_store.pb.h"
 #include "third_party/boringssl/src/pki/trust_store.h"
 #include "third_party/boringssl/src/pki/trust_store_in_memory.h"
 
+namespace chrome_root_store {
+class RootStore;
+}
+
 namespace net {
 
 // Represents a ConstraintSet for compiled-in version of the root store.
diff --git a/net/disk_cache/backend_experiment.cc b/net/disk_cache/backend_experiment.cc
index a160a35..9cdfb43 100644
--- a/net/disk_cache/backend_experiment.cc
+++ b/net/disk_cache/backend_experiment.cc
@@ -25,4 +25,11 @@
              net::features::DiskCacheBackend::kBlockfile;
 }
 
+#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
+bool InSqlBackendExperimentGroup() {
+  return InBackendExperiment() && net::features::kDiskCacheBackendParam.Get() ==
+                                      net::features::DiskCacheBackend::kSql;
+}
+#endif  // ENABLE_DISK_CACHE_SQL_BACKEND
+
 }  // namespace disk_cache
diff --git a/net/disk_cache/backend_experiment.h b/net/disk_cache/backend_experiment.h
index e8a91f1..48230f1d 100644
--- a/net/disk_cache/backend_experiment.h
+++ b/net/disk_cache/backend_experiment.h
@@ -7,6 +7,7 @@
 
 #include "build/build_config.h"
 #include "net/base/net_export.h"
+#include "net/disk_cache/buildflags.h"
 
 namespace disk_cache {
 
@@ -26,6 +27,11 @@
 // True if assigned to the "blockfile" disk cache backend group.
 NET_EXPORT bool InBlockfileBackendExperimentGroup();
 
+#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
+// True if assigned to the "sql" disk cache backend group.
+NET_EXPORT bool InSqlBackendExperimentGroup();
+#endif  // ENABLE_DISK_CACHE_SQL_BACKEND
+
 }  // namespace disk_cache
 
 #endif  // NET_DISK_CACHE_BACKEND_EXPERIMENT_H_
diff --git a/net/disk_cache/blockfile/backend_impl.cc b/net/disk_cache/blockfile/backend_impl.cc
index 8095ecb..7c5873dc 100644
--- a/net/disk_cache/blockfile/backend_impl.cc
+++ b/net/disk_cache/blockfile/backend_impl.cc
@@ -74,6 +74,13 @@
                    "dump_without_crashing_frequency",
                    0.01);
 
+BASE_FEATURE_PARAM(
+    double,
+    kBlockfileCacheBackendDumpWithoutCrashingFrequencyOnInvalidLinks,
+    &kBlockfileCacheBackendDumpWithoutCrashing,
+    "dump_without_crashing_frequency_on_invalid_links",
+    0.01);
+
 int DesiredIndexTableLen(int32_t storage_size) {
   if (storage_size <= k64kEntriesStore)
     return kBaseTableLen;
@@ -1036,6 +1043,7 @@
   // We transmit positive numbers, instead of direct error codes.
   DCHECK_LE(error, 0);
   if (GetCacheType() == net::DISK_CACHE) {
+    SCOPED_CRASH_KEY_NUMBER("DiskCache", "disk_cache_error", error * -1);
     // TODO(crbug.com/433551601): Remove this once sufficient crash reports have
     // been gathered, and definitely before stable.
     if (error == ERR_INIT_FAILED) {
@@ -1056,6 +1064,18 @@
           base::debug::DumpWithoutCrashing();
         }
       }
+    } else if (error == ERR_INVALID_LINKS) {
+      static bool has_considered_dumping = false;
+      if (!has_considered_dumping) {
+        has_considered_dumping = true;
+        if (base::FeatureList::IsEnabled(
+                kBlockfileCacheBackendDumpWithoutCrashing) &&
+            base::ShouldRecordSubsampledMetric(
+                kBlockfileCacheBackendDumpWithoutCrashingFrequencyOnInvalidLinks
+                    .Get())) {
+          base::debug::DumpWithoutCrashing();
+        }
+      }
     }
     base::UmaHistogramExactLinear("DiskCache.0.Error", error * -1, 50);
   }
diff --git a/net/disk_cache/disk_cache.cc b/net/disk_cache/disk_cache.cc
index 06a0fd6..7d04b64 100644
--- a/net/disk_cache/disk_cache.cc
+++ b/net/disk_cache/disk_cache.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "net/disk_cache/disk_cache.h"
+
 #include <utility>
 
 #include "base/barrier_closure.h"
@@ -16,10 +18,12 @@
 #include "base/task/single_thread_task_runner.h"
 #include "base/task/thread_pool/thread_pool_instance.h"
 #include "build/build_config.h"
+#include "build/buildflag.h"
 #include "net/base/cache_type.h"
 #include "net/base/net_errors.h"
 #include "net/disk_cache/backend_cleanup_tracker.h"
 #include "net/disk_cache/blockfile/backend_impl.h"
+#include "net/disk_cache/buildflags.h"
 #include "net/disk_cache/cache_util.h"
 #include "net/disk_cache/disk_cache.h"
 #include "net/disk_cache/memory/mem_backend_impl.h"
@@ -27,6 +31,10 @@
 #include "net/disk_cache/simple/simple_file_enumerator.h"
 #include "net/disk_cache/simple/simple_util.h"
 
+#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
+#include "net/disk_cache/sql/sql_backend_impl.h"
+#endif  // ENABLE_DISK_CACHE_SQL_BACKEND
+
 namespace {
 
 using FileEnumerator = disk_cache::BackendFileOperations::FileEnumerator;
@@ -152,6 +160,18 @@
     return;
   }
 
+#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
+  if (backend_type_ == net::CACHE_BACKEND_EXPERIMENTAL_SQL) {
+    auto sql_cache =
+        std::make_unique<disk_cache::SqlBackendImpl>(path_, max_bytes_, type_);
+    auto* sql_cache_ptr = sql_cache.get();
+    created_cache_ = std::move(sql_cache);
+    sql_cache_ptr->Init(
+        base::BindOnce(&CacheCreator::OnIOComplete, base::Unretained(this)));
+    return;
+  }
+#endif  // ENABLE_DISK_CACHE_SQL_BACKEND
+
 // Avoid references to blockfile functions on Android to reduce binary size.
 #if BUILDFLAG(IS_ANDROID)
   FailAttempt();
diff --git a/net/disk_cache/sql/sql_backend_constants.h b/net/disk_cache/sql/sql_backend_constants.h
index f35228e..bfbcec9 100644
--- a/net/disk_cache/sql/sql_backend_constants.h
+++ b/net/disk_cache/sql/sql_backend_constants.h
@@ -32,6 +32,17 @@
 inline constexpr base::FilePath::CharType kSqlBackendDatabaseFileName[] =
     FILE_PATH_LITERAL("sqldb");
 
+// The name of the fake index file. This file is created to signal the presence
+// of the SQL backend and to prevent other backends from trying to use the same
+// directory.
+inline constexpr base::FilePath::CharType kSqlBackendFakeIndexFileName[] =
+    FILE_PATH_LITERAL("index");
+
+// The magic number for the fake index file. This is "SQLCache" in
+// little-endian.
+inline constexpr uint64_t kSqlBackendFakeIndexMagicNumber =
+    UINT64_C(0x65686361434c5153);
+
 // The oldest database schema version that the current code can read.
 // A database with a version older than this will be razed as it's considered
 // obsolete and the code no longer supports migrating from it.
diff --git a/net/disk_cache/sql/sql_backend_impl.cc b/net/disk_cache/sql/sql_backend_impl.cc
index 33aa3c9..0a34065 100644
--- a/net/disk_cache/sql/sql_backend_impl.cc
+++ b/net/disk_cache/sql/sql_backend_impl.cc
@@ -9,9 +9,14 @@
 
 #include "base/barrier_callback.h"
 #include "base/containers/flat_set.h"
+#include "base/containers/span.h"
+#include "base/files/file.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
 #include "base/functional/callback_helpers.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/notimplemented.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/task/task_runner.h"
@@ -26,6 +31,49 @@
 namespace disk_cache {
 namespace {
 
+using FakeIndexFileError = SqlBackendImpl::FakeIndexFileError;
+
+// Checks the fake index file, creating it if it doesn't exist. Returns an
+// error code if the file is corrupted or cannot be created.
+FakeIndexFileError CheckFakeIndexFileInternal(const base::FilePath& path) {
+  const base::FilePath file_path = path.Append(kSqlBackendFakeIndexFileName);
+  const std::optional<int64_t> file_size = base::GetFileSize(file_path);
+  if (file_size.has_value()) {
+    if (file_size != sizeof(kSqlBackendFakeIndexMagicNumber)) {
+      return FakeIndexFileError::kWrongFileSize;
+    }
+    base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
+    if (!file.IsValid()) {
+      return FakeIndexFileError::kOpenFileFailed;
+    }
+    uint64_t magic_number = 0;
+    if (!file.ReadAndCheck(0, base::byte_span_from_ref(magic_number))) {
+      return FakeIndexFileError::kReadFileFailed;
+    }
+    if (magic_number != kSqlBackendFakeIndexMagicNumber) {
+      return FakeIndexFileError::kWrongMagicNumber;
+    }
+    return FakeIndexFileError::kOkExisting;
+  }
+  base::File file(file_path, base::File::FLAG_CREATE | base::File::FLAG_WRITE);
+  if (!file.IsValid()) {
+    return FakeIndexFileError::kCreateFileFailed;
+  }
+  if (!file.WriteAndCheck(
+          0, base::byte_span_from_ref(kSqlBackendFakeIndexMagicNumber))) {
+    return FakeIndexFileError::kWriteFileFailed;
+  }
+  return FakeIndexFileError::kOkNew;
+}
+
+// Checks the fake index file and records a histogram of the result.
+bool CheckFakeIndexFile(const base::FilePath& path) {
+  FakeIndexFileError error = CheckFakeIndexFileInternal(path);
+  base::UmaHistogramEnumeration("Net.SqlDiskCache.FakeIndexFileError", error);
+  return error == FakeIndexFileError::kOkNew ||
+         error == FakeIndexFileError::kOkExisting;
+}
+
 // A helper to handle methods that may complete synchronously.
 //
 // This allows a caller to dispatch an async operation and immediately check if
@@ -219,6 +267,7 @@
                                int64_t max_bytes,
                                net::CacheType cache_type)
     : Backend(cache_type),
+      path_(path),
       background_task_runner_(base::ThreadPool::CreateSequencedTaskRunner(
           {base::MayBlock(), base::TaskPriority::USER_BLOCKING,
            base::TaskShutdownBehavior::BLOCK_SHUTDOWN})),
@@ -227,28 +276,41 @@
                                         GetCacheType(),
                                         background_task_runner_)) {
   DVLOG(1) << "SqlBackendImpl::SqlBackendImpl " << path;
-
-  // Schedule a one-time task to clean up doomed entries from previous sessions.
-  // This runs after a delay to avoid impacting startup performance.
-  base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
-      FROM_HERE,
-      base::BindOnce(&SqlBackendImpl::TriggerDeleteDoomedEntries,
-                     weak_factory_.GetWeakPtr()),
-      kSqlBackendDeleteDoomedEntriesDelay);
 }
 
 SqlBackendImpl::~SqlBackendImpl() = default;
 
 void SqlBackendImpl::Init(CompletionOnceCallback callback) {
-  // Initialize the underlying persistent store. The callback will be run with
-  // net::OK on success, or net::ERR_FAILED on failure.
-  store_->Initialize(base::BindOnce(
-      [](CompletionOnceCallback callback, SqlPersistentStore::Error result) {
-        return std::move(callback).Run(result == SqlPersistentStore::Error::kOk
-                                           ? net::OK
-                                           : net::ERR_FAILED);
-      },
-      std::move(callback)));
+  auto barrier_callback = base::BarrierCallback<bool>(
+      2, base::BindOnce(&SqlBackendImpl::OnInitialized,
+                        weak_factory_.GetWeakPtr(), std::move(callback)));
+
+  store_->Initialize(base::BindOnce([](SqlPersistentStore::Error result) {
+                       return result == SqlPersistentStore::Error::kOk;
+                     }).Then(barrier_callback));
+
+  base::ThreadPool::PostTaskAndReplyWithResult(
+      FROM_HERE,
+      {base::MayBlock(), base::TaskPriority::USER_BLOCKING,
+       base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
+      base::BindOnce(&CheckFakeIndexFile, path_),
+      base::OnceCallback<void(bool)>(barrier_callback));
+}
+
+void SqlBackendImpl::OnInitialized(CompletionOnceCallback callback,
+                                   const std::vector<bool>& results) {
+  const bool success = std::all_of(results.begin(), results.end(),
+                                   [](bool result) { return result; });
+  if (success) {
+    // Schedule a one-time task to clean up doomed entries from previous
+    // sessions. This runs after a delay to avoid impacting startup performance.
+    base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
+        FROM_HERE,
+        base::BindOnce(&SqlBackendImpl::TriggerDeleteDoomedEntries,
+                       weak_factory_.GetWeakPtr()),
+        kSqlBackendDeleteDoomedEntriesDelay);
+  }
+  std::move(callback).Run(success ? net::OK : net::ERR_FAILED);
 }
 
 int64_t SqlBackendImpl::MaxFileSize() const {
diff --git a/net/disk_cache/sql/sql_backend_impl.h b/net/disk_cache/sql/sql_backend_impl.h
index 3649f99..969f8c20 100644
--- a/net/disk_cache/sql/sql_backend_impl.h
+++ b/net/disk_cache/sql/sql_backend_impl.h
@@ -11,6 +11,7 @@
 #include <set>
 #include <vector>
 
+#include "base/files/file_path.h"
 #include "base/memory/raw_ref.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
@@ -40,6 +41,24 @@
 // yet implemented, returning `net::ERR_NOT_IMPLEMENTED`.
 class NET_EXPORT_PRIVATE SqlBackendImpl final : public Backend {
  public:
+  // An enumeration of errors that can occur during the fake index file check.
+  // These values are persisted to logs. Entries should not be renumbered and
+  // numeric values should never be reused.
+  //
+  // LINT.IfChange(FakeIndexFileError)
+  enum class FakeIndexFileError {
+    kOkNew = 0,
+    kOkExisting = 1,
+    kCreateFileFailed = 2,
+    kWriteFileFailed = 3,
+    kWrongFileSize = 4,
+    kOpenFileFailed = 5,
+    kReadFileFailed = 6,
+    kWrongMagicNumber = 7,
+    kMaxValue = kWrongMagicNumber,
+  };
+  // LINT.ThenChange(//tools/metrics/histograms/metadata/net/enums.xml:SqlDiskCacheFakeIndexFileError)
+
   SqlBackendImpl(const base::FilePath& path,
                  int64_t max_bytes,
                  net::CacheType cache_type);
@@ -49,7 +68,9 @@
 
   ~SqlBackendImpl() override;
 
-  // Finishes initialization. Always asynchronous.
+  // Initializes the backend, which includes initializing the persistent store
+  // and checking for a fake index file. These two operations are performed in
+  // parallel.
   void Init(CompletionOnceCallback callback);
 
   // Backend interface.
@@ -189,6 +210,9 @@
     std::optional<int64_t> body_end;
   };
 
+  void OnInitialized(CompletionOnceCallback callback,
+                     const std::vector<bool>& results);
+
   SqlEntryImpl* GetActiveEntry(const CacheEntryKey& key);
 
   // Checks if the cache size has exceeded the high watermark and, if so,
@@ -362,6 +386,8 @@
   void HandleDeleteDoomedEntriesOperation(
       std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);
 
+  const base::FilePath path_;
+
   // Task runner for all background SQLite operations.
   scoped_refptr<base::SequencedTaskRunner> background_task_runner_;
 
diff --git a/net/disk_cache/sql/sql_backend_impl_unittest.cc b/net/disk_cache/sql/sql_backend_impl_unittest.cc
index c0c841b6..10853a6 100644
--- a/net/disk_cache/sql/sql_backend_impl_unittest.cc
+++ b/net/disk_cache/sql/sql_backend_impl_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "net/disk_cache/sql/sql_backend_impl.h"
 
+#include "base/containers/span.h"
+#include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/location.h"
 #include "base/memory/scoped_refptr.h"
@@ -12,6 +14,7 @@
 #include "base/test/bind.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/task_environment.h"
+#include "base/test/test_file_util.h"
 #include "base/test/test_future.h"
 #include "net/base/io_buffer.h"
 #include "net/base/test_completion_callback.h"
@@ -30,6 +33,7 @@
 
 using testing::ElementsAre;
 using testing::Pair;
+using FakeIndexFileError = SqlBackendImpl::FakeIndexFileError;
 
 // Default max cache size for tests, 10 MB.
 inline constexpr int64_t kDefaultMaxBytes = 10 * 1024 * 1024;
@@ -73,6 +77,11 @@
   void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }
 
  protected:
+  std::unique_ptr<SqlBackendImpl> CreateBackend() {
+    return std::make_unique<SqlBackendImpl>(
+        temp_dir_.GetPath(), kDefaultMaxBytes, net::CacheType::DISK_CACHE);
+  }
+
   std::unique_ptr<SqlBackendImpl> CreateBackendAndInit(
       int64_t max_bytes = kDefaultMaxBytes) {
     auto backend = std::make_unique<SqlBackendImpl>(
@@ -89,6 +98,105 @@
   base::ScopedTempDir temp_dir_;
 };
 
+TEST_F(SqlBackendImplTest, InitWithNoFakeIndexFile) {
+  base::HistogramTester histogram_tester;
+  auto backend = CreateBackend();
+  base::test::TestFuture<int> future;
+  backend->Init(future.GetCallback());
+  ASSERT_EQ(future.Get(), net::OK);
+  histogram_tester.ExpectUniqueSample("Net.SqlDiskCache.FakeIndexFileError",
+                                      FakeIndexFileError::kOkNew, 1);
+
+  base::FilePath file_path =
+      temp_dir_.GetPath().Append(kSqlBackendFakeIndexFileName);
+  const std::optional<int64_t> file_size = base::GetFileSize(file_path);
+  ASSERT_TRUE(file_size.has_value());
+  EXPECT_EQ(*file_size, sizeof(kSqlBackendFakeIndexMagicNumber));
+  int64_t magic_number_from_file;
+  ASSERT_TRUE(base::ReadFile(file_path,
+                             base::byte_span_from_ref(magic_number_from_file)));
+  EXPECT_EQ(magic_number_from_file, kSqlBackendFakeIndexMagicNumber);
+}
+
+TEST_F(SqlBackendImplTest, InitWithFakeIndexFile) {
+  base::HistogramTester histogram_tester;
+  base::FilePath file_path =
+      temp_dir_.GetPath().Append(kSqlBackendFakeIndexFileName);
+  ASSERT_TRUE(base::WriteFile(
+      file_path, base::byte_span_from_ref(kSqlBackendFakeIndexMagicNumber)));
+
+  auto backend = CreateBackend();
+  base::test::TestFuture<int> future;
+  backend->Init(future.GetCallback());
+  ASSERT_EQ(future.Get(), net::OK);
+  histogram_tester.ExpectUniqueSample("Net.SqlDiskCache.FakeIndexFileError",
+                                      FakeIndexFileError::kOkExisting, 1);
+}
+
+TEST_F(SqlBackendImplTest, InitWithCorruptedFakeIndexFile) {
+  base::HistogramTester histogram_tester;
+  base::FilePath file_path =
+      temp_dir_.GetPath().Append(kSqlBackendFakeIndexFileName);
+  const int64_t kWrongMagicNumber = 0xDEADBEEFDEADBEEF;
+  ASSERT_TRUE(
+      base::WriteFile(file_path, base::byte_span_from_ref(kWrongMagicNumber)));
+
+  auto backend = CreateBackend();
+  base::test::TestFuture<int> future;
+  backend->Init(future.GetCallback());
+  ASSERT_EQ(future.Get(), net::ERR_FAILED);
+  histogram_tester.ExpectUniqueSample("Net.SqlDiskCache.FakeIndexFileError",
+                                      FakeIndexFileError::kWrongMagicNumber, 1);
+}
+
+TEST_F(SqlBackendImplTest, InitWithWrongSizeFakeIndexFile) {
+  base::HistogramTester histogram_tester;
+  base::FilePath file_path =
+      temp_dir_.GetPath().Append(kSqlBackendFakeIndexFileName);
+  const int32_t kWrongMagicNumber = 0xDEADBEEF;
+  ASSERT_TRUE(
+      base::WriteFile(file_path, base::byte_span_from_ref(kWrongMagicNumber)));
+
+  auto backend = CreateBackend();
+  base::test::TestFuture<int> future;
+  backend->Init(future.GetCallback());
+  ASSERT_EQ(future.Get(), net::ERR_FAILED);
+  histogram_tester.ExpectUniqueSample("Net.SqlDiskCache.FakeIndexFileError",
+                                      FakeIndexFileError::kWrongFileSize, 1);
+}
+
+TEST_F(SqlBackendImplTest, InitWithOpenFileFailed) {
+  base::HistogramTester histogram_tester;
+  base::FilePath file_path =
+      temp_dir_.GetPath().Append(kSqlBackendFakeIndexFileName);
+  ASSERT_TRUE(base::WriteFile(
+      file_path, base::byte_span_from_ref(kSqlBackendFakeIndexMagicNumber)));
+  base::FilePermissionRestorer permission_restorer(file_path);
+  // Make the file unreadable.
+  ASSERT_TRUE(base::MakeFileUnreadable(file_path));
+
+  auto backend = CreateBackend();
+  base::test::TestFuture<int> future;
+  backend->Init(future.GetCallback());
+  ASSERT_EQ(future.Get(), net::ERR_FAILED);
+  histogram_tester.ExpectUniqueSample("Net.SqlDiskCache.FakeIndexFileError",
+                                      FakeIndexFileError::kOpenFileFailed, 1);
+}
+
+TEST_F(SqlBackendImplTest, InitWithCreateFileFailed) {
+  base::HistogramTester histogram_tester;
+  base::FilePermissionRestorer permission_restorer(temp_dir_.GetPath());
+  // Make the directory unwrittable.
+  ASSERT_TRUE(base::MakeFileUnwritable(temp_dir_.GetPath()));
+
+  auto backend = CreateBackend();
+  base::test::TestFuture<int> future;
+  backend->Init(future.GetCallback());
+  ASSERT_EQ(future.Get(), net::ERR_FAILED);
+  histogram_tester.ExpectUniqueSample("Net.SqlDiskCache.FakeIndexFileError",
+                                      FakeIndexFileError::kCreateFileFailed, 1);
+}
+
 TEST_F(SqlBackendImplTest, MaxFileSizeSmallMax) {
   const int64_t kMaxBytes = 10 * 1024 * 1024;
   auto backend = CreateBackendAndInit(kMaxBytes);
diff --git a/net/dns/host_resolver_dns_task.cc b/net/dns/host_resolver_dns_task.cc
index bec87c29..7a32ae4 100644
--- a/net/dns/host_resolver_dns_task.cc
+++ b/net/dns/host_resolver_dns_task.cc
@@ -8,6 +8,7 @@
 #include <string_view>
 #include <variant>
 
+#include "base/feature_list.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/time/tick_clock.h"
@@ -26,6 +27,11 @@
 
 namespace net {
 
+// When enabled, query HTTPS RR first.
+BASE_FEATURE(kPrioritizeHttpsResourceRecord,
+             "PrioritizeHttpsResourceRecord",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 namespace {
 
 DnsResponse CreateFakeEmptyResponse(std::string_view hostname,
@@ -404,25 +410,38 @@
                                       TransactionErrorBehavior::kFatalOrEmpty);
   }
 
-  // Give AAAA/A queries a head start by pushing them to the queue first.
-  constexpr DnsQueryType kHighPriorityQueries[] = {DnsQueryType::AAAA,
-                                                   DnsQueryType::A};
-  for (DnsQueryType high_priority_query : kHighPriorityQueries) {
-    if (query_types.Has(high_priority_query)) {
-      query_types.Remove(high_priority_query);
-      transactions_needed_.emplace_back(high_priority_query);
-    }
-  }
-  for (DnsQueryType remaining_query : query_types) {
-    if (remaining_query == DnsQueryType::HTTPS) {
+  auto add_transaction = [&](DnsQueryType query) {
+    if (query == DnsQueryType::HTTPS) {
       // Ignore errors for these types. In most cases treating them normally
       // would only result in fallback to resolution without querying the
       // type. Instead, synthesize empty results.
       transactions_needed_.emplace_back(
-          remaining_query, TransactionErrorBehavior::kSynthesizeEmpty);
+          query, TransactionErrorBehavior::kSynthesizeEmpty);
     } else {
-      transactions_needed_.emplace_back(remaining_query);
+      transactions_needed_.emplace_back(query);
     }
+  };
+
+  if (query_types.Has(DnsQueryType::HTTPS) &&
+      (base::FeatureList::IsEnabled(kPrioritizeHttpsResourceRecord) ||
+       base::FeatureList::IsEnabled(features::kHappyEyeballsV3))) {
+    query_types.Remove(DnsQueryType::HTTPS);
+    add_transaction(DnsQueryType::HTTPS);
+  }
+
+  // Give AAAA/A queries a head start by pushing them to the queue first.
+  constexpr DnsQueryType kHighPriorityQueries[] = {DnsQueryType::AAAA,
+                                                   DnsQueryType::A};
+  for (DnsQueryType high_priority_query : kHighPriorityQueries) {
+    if (!query_types.Has(high_priority_query)) {
+      continue;
+    }
+    query_types.Remove(high_priority_query);
+    add_transaction(high_priority_query);
+  }
+
+  for (DnsQueryType remaining_query : query_types) {
+    add_transaction(remaining_query);
   }
 }
 
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index e0418bc..352a44d 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -47,6 +47,7 @@
 #include "net/base/load_flags.h"
 #include "net/base/load_timing_info.h"
 #include "net/base/net_errors.h"
+#include "net/base/task/task_runner.h"
 #include "net/base/trace_constants.h"
 #include "net/base/transport_info.h"
 #include "net/base/upload_data_stream.h"
@@ -109,6 +110,14 @@
   return method == "GET" || method == "HEAD";
 }
 
+const scoped_refptr<base::SingleThreadTaskRunner>& TaskRunner(
+    net::RequestPriority priority) {
+  if (features::kNetTaskSchedulerHttpCacheTransaction.Get()) {
+    return net::GetTaskRunner(priority);
+  }
+  return base::SingleThreadTaskRunner::GetCurrentDefault();
+}
+
 }  // namespace
 
 #define CACHE_STATUS_HISTOGRAMS(type)                                      \
@@ -1458,7 +1467,7 @@
   if ((bypass_lock_for_test_ && next_state_ == STATE_ADD_TO_ENTRY_COMPLETE) ||
       (bypass_lock_after_headers_for_test_ &&
        next_state_ == STATE_FINISH_HEADERS_COMPLETE)) {
-    base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
+    TaskRunner(priority_)->PostTask(
         FROM_HERE,
         base::BindOnce(&HttpCache::Transaction::OnCacheLockTimeout,
                        weak_factory_.GetWeakPtr(), entry_lock_waiting_since_));
@@ -1485,7 +1494,7 @@
       // the cache if at all possible. See http://crbug.com/408765
       timeout_milliseconds = 25;
     }
-    base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
+    TaskRunner(priority_)->PostDelayedTask(
         FROM_HERE,
         base::BindOnce(&HttpCache::Transaction::OnCacheLockTimeout,
                        weak_factory_.GetWeakPtr(), entry_lock_waiting_since_),
diff --git a/net/http/http_response_info.cc b/net/http/http_response_info.cc
index 0409b9e3..bee263e 100644
--- a/net/http/http_response_info.cc
+++ b/net/http/http_response_info.cc
@@ -369,9 +369,12 @@
       (extra_flags & RESPONSE_EXTRA_INFO_DID_USE_SHARED_DICTIONARY) != 0;
 
   if (extra_flags & RESPONSE_EXTRA_INFO_HAS_PROXY_CHAIN) {
-    if (!proxy_chain.InitFromPickle(&iter)) {
+    std::optional<ProxyChain> unpickled_proxy_chain =
+        ProxyChain::InitFromPickle(iter);
+    if (!unpickled_proxy_chain) {
       return false;
     }
+    proxy_chain = std::move(*unpickled_proxy_chain);
   }
 
   return true;
diff --git a/net/quic/quic_session_attempt_manager.cc b/net/quic/quic_session_attempt_manager.cc
index 7dd75a2..e1c35c2 100644
--- a/net/quic/quic_session_attempt_manager.cc
+++ b/net/quic/quic_session_attempt_manager.cc
@@ -86,11 +86,17 @@
             std::move(dns_aliases), session_creation_initiator,
             std::move(connection_management_config));
     QuicSessionAttempt* raw_attempt = attempt.get();
-    auto [_, inserted] = attempts_.emplace(std::move(attempt));
+    auto [it, inserted] = attempts_.emplace(std::move(attempt));
     CHECK(inserted);
     int rv = raw_attempt->Start(base::BindOnce(
         &Job::OnAttemptComplete, base::Unretained(this), raw_attempt));
     if (rv != ERR_IO_PENDING) {
+      // If the attempt failed synchronously but there are other attempts, wait
+      // for them to complete.
+      if (rv != OK && attempts_.size() > 1) {
+        attempts_.erase(it);
+        return ERR_IO_PENDING;
+      }
       OnAttemptComplete(raw_attempt, rv);
     }
     return rv;
diff --git a/net/quic/quic_session_attempt_manager_unittest.cc b/net/quic/quic_session_attempt_manager_unittest.cc
index 6add7f32..443c8f6 100644
--- a/net/quic/quic_session_attempt_manager_unittest.cc
+++ b/net/quic/quic_session_attempt_manager_unittest.cc
@@ -227,6 +227,21 @@
   EXPECT_TRUE(requester.session());
 }
 
+TEST_P(QuicSessionAttemptManagerTest, RequestSessionSyncFailure) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndDisableFeature(net::features::kAsyncQuicSession);
+
+  InitializeWithDefaultProofVerifyDetails();
+
+  MockQuicData socket_data(version_);
+  socket_data.AddConnect(ASYNC, ERR_CONNECTION_REFUSED);
+  socket_data.AddSocketDataToFactory(socket_factory_.get());
+
+  SessionRequester requester = CreateRequester();
+  int result = requester.Request();
+  EXPECT_THAT(result, IsError(ERR_CONNECTION_REFUSED));
+}
+
 TEST_P(QuicSessionAttemptManagerTest, RequestSessionAsync) {
   InitializeWithDefaultProofVerifyDetails();
 
diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc
index f8e2a1b..32a7e09 100644
--- a/net/url_request/url_request_context_builder.cc
+++ b/net/url_request/url_request_context_builder.cc
@@ -20,6 +20,7 @@
 #include "base/task/thread_pool.h"
 #include "base/types/pass_key.h"
 #include "build/build_config.h"
+#include "build/buildflag.h"
 #include "net/base/cache_type.h"
 #include "net/base/features.h"
 #include "net/base/net_errors.h"
@@ -30,6 +31,7 @@
 #include "net/cert/multi_log_ct_verifier.h"
 #include "net/cert/sct_auditing_delegate.h"
 #include "net/cookies/cookie_monster.h"
+#include "net/disk_cache/buildflags.h"
 #include "net/dns/context_host_resolver.h"
 #include "net/dns/host_resolver.h"
 #include "net/dns/host_resolver_manager.h"
@@ -580,6 +582,10 @@
           break;
         case HttpCacheParams::IN_MEMORY:
           NOTREACHED();
+#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
+        case HttpCacheParams::DISK_EXPERIMENTAL_SQL:
+          backend_type = CACHE_BACKEND_EXPERIMENTAL_SQL;
+#endif  // ENABLE_DISK_CACHE_SQL_BACKEND
       }
       http_cache_backend = std::make_unique<HttpCache::DefaultBackend>(
           DISK_CACHE, backend_type, http_cache_params_.file_operations_factory,
diff --git a/net/url_request/url_request_context_builder.h b/net/url_request/url_request_context_builder.h
index 7a9022b..edd59a0c 100644
--- a/net/url_request/url_request_context_builder.h
+++ b/net/url_request/url_request_context_builder.h
@@ -36,6 +36,7 @@
 #include "net/base/network_delegate.h"
 #include "net/base/network_handle.h"
 #include "net/base/proxy_delegate.h"
+#include "net/disk_cache/buildflags.h"
 #include "net/disk_cache/disk_cache.h"
 #include "net/dns/host_resolver.h"
 #include "net/dns/stale_host_resolver.h"
@@ -109,6 +110,11 @@
       DISK_BLOCKFILE,
       // Disk cache using "simple" backend (SimpleBackendImpl).
       DISK_SIMPLE,
+#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
+      // Disk cache using "sql" backend (SqlBackendImpl).
+      // This is still under experiment.
+      DISK_EXPERIMENTAL_SQL,
+#endif  // ENABLE_DISK_CACHE_SQL_BACKEND
     };
 
     HttpCacheParams();
diff --git a/net/websockets/websocket_end_to_end_test.cc b/net/websockets/websocket_end_to_end_test.cc
index fdf7792..f2ee756fc 100644
--- a/net/websockets/websocket_end_to_end_test.cc
+++ b/net/websockets/websocket_end_to_end_test.cc
@@ -33,6 +33,7 @@
 #include "base/strings/string_view_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/task/single_thread_task_runner.h"
+#include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/test_future.h"
 #include "build/build_config.h"
@@ -958,11 +959,6 @@
   base::test::ScopedFeatureList features;
   features.InitAndEnableFeature(features::kUseDnsHttpsSvcb);
 
-  // SpawnedTestServer does not support ECH, while EmbeddedTestServer does not
-  // support WebSockets (https://crbug.com/1281277). Until that is fixed, test
-  // ECH by configuring a non-WebSockets HTTPS server. The WebSockets handshake
-  // will fail, but getting that far tests that ECH worked.
-
   // Configure a test server that speaks ECH.
   static constexpr char kRealName[] = "secret.example";
   static constexpr char kPublicName[] = "public.example";
@@ -974,14 +970,20 @@
       MakeTestEchKeys(kPublicName, /*max_name_len=*/128, &ech_config_list);
   ASSERT_TRUE(ssl_server_config.ech_keys);
 
+  // Only complete the handshake if ECH was actually used.
+  ssl_server_config.client_hello_callback_for_testing =
+      base::BindLambdaForTesting(
+          [&](const SSL_CLIENT_HELLO* client_hello) -> bool {
+            return SSL_ech_accepted(client_hello->ssl);
+          });
+
   EmbeddedTestServer test_server(EmbeddedTestServer::TYPE_HTTPS);
   test_server.SetSSLConfig(server_cert_config, ssl_server_config);
+  test_server::InstallDefaultWebSocketHandlers(&test_server);
   ASSERT_TRUE(test_server.Start());
 
-  GURL https_url = test_server.GetURL(kRealName, "/");
-  GURL::Replacements replacements;
-  replacements.SetSchemeStr(url::kWssScheme);
-  GURL wss_url = https_url.ReplaceComponents(replacements);
+  GURL wss_url =
+      test_server::GetWebSocketURL(test_server, kRealName, kEchoServer);
 
   auto host_resolver = std::make_unique<MockHostResolver>();
   MockHostResolverBase::RuleResolver::RuleKey resolve_key;
@@ -999,10 +1001,11 @@
       MockHostResolverBase::RuleResolver::RuleResult(std::vector{result}));
   context_builder_->set_host_resolver(std::move(host_resolver));
 
-  EXPECT_FALSE(ConnectAndWait(wss_url));
-  EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 404",
-            event_interface_->failure_message());
-}
-}  // namespace
+  EXPECT_TRUE(ConnectAndWait(wss_url));
 
+  // Expect request to have reached the server using the upgraded URL.
+  EXPECT_EQ(event_interface_->response()->url, wss_url);
+}
+
+}  // namespace
 }  // namespace net
diff --git a/sandbox/policy/linux/bpf_cros_amd_gpu_policy_linux.cc b/sandbox/policy/linux/bpf_cros_amd_gpu_policy_linux.cc
index 4fd379c..1ea2f0f 100644
--- a/sandbox/policy/linux/bpf_cros_amd_gpu_policy_linux.cc
+++ b/sandbox/policy/linux/bpf_cros_amd_gpu_policy_linux.cc
@@ -28,8 +28,8 @@
 namespace sandbox {
 namespace policy {
 
-CrosAmdGpuProcessPolicy::CrosAmdGpuProcessPolicy(bool allow_mremap)
-    : GpuProcessPolicy(allow_mremap) {}
+CrosAmdGpuProcessPolicy::CrosAmdGpuProcessPolicy(MremapPolicy mremap_policy)
+    : GpuProcessPolicy(mremap_policy) {}
 
 CrosAmdGpuProcessPolicy::~CrosAmdGpuProcessPolicy() {}
 
diff --git a/sandbox/policy/linux/bpf_cros_amd_gpu_policy_linux.h b/sandbox/policy/linux/bpf_cros_amd_gpu_policy_linux.h
index b8b1d9b..67c176c 100644
--- a/sandbox/policy/linux/bpf_cros_amd_gpu_policy_linux.h
+++ b/sandbox/policy/linux/bpf_cros_amd_gpu_policy_linux.h
@@ -15,7 +15,7 @@
 // This policy is for AMD GPUs running on Chrome OS.
 class SANDBOX_POLICY_EXPORT CrosAmdGpuProcessPolicy : public GpuProcessPolicy {
  public:
-  explicit CrosAmdGpuProcessPolicy(bool allow_mremap);
+  explicit CrosAmdGpuProcessPolicy(MremapPolicy mremap_policy);
 
   CrosAmdGpuProcessPolicy(const CrosAmdGpuProcessPolicy&) = delete;
   CrosAmdGpuProcessPolicy& operator=(const CrosAmdGpuProcessPolicy&) = delete;
diff --git a/sandbox/policy/linux/bpf_cros_arm_gpu_policy_linux.cc b/sandbox/policy/linux/bpf_cros_arm_gpu_policy_linux.cc
index 4d447ebb..4704ff7 100644
--- a/sandbox/policy/linux/bpf_cros_arm_gpu_policy_linux.cc
+++ b/sandbox/policy/linux/bpf_cros_arm_gpu_policy_linux.cc
@@ -26,9 +26,9 @@
 namespace sandbox {
 namespace policy {
 
-CrosArmGpuProcessPolicy::CrosArmGpuProcessPolicy(bool allow_mremap,
+CrosArmGpuProcessPolicy::CrosArmGpuProcessPolicy(MremapPolicy mremap_policy,
                                                  bool allow_shmat)
-    : GpuProcessPolicy(allow_mremap)
+    : GpuProcessPolicy(mremap_policy)
 #if defined(__arm__) || defined(__aarch64__)
       ,
       allow_shmat_(allow_shmat)
diff --git a/sandbox/policy/linux/bpf_cros_arm_gpu_policy_linux.h b/sandbox/policy/linux/bpf_cros_arm_gpu_policy_linux.h
index 1448897..df36eca 100644
--- a/sandbox/policy/linux/bpf_cros_arm_gpu_policy_linux.h
+++ b/sandbox/policy/linux/bpf_cros_arm_gpu_policy_linux.h
@@ -15,7 +15,7 @@
 // This policy is for Chrome OS ARM.
 class SANDBOX_POLICY_EXPORT CrosArmGpuProcessPolicy : public GpuProcessPolicy {
  public:
-  CrosArmGpuProcessPolicy(bool allow_mremap, bool allow_shmat);
+  CrosArmGpuProcessPolicy(MremapPolicy mremap_policy, bool allow_shmat);
 
   CrosArmGpuProcessPolicy(const CrosArmGpuProcessPolicy&) = delete;
   CrosArmGpuProcessPolicy& operator=(const CrosArmGpuProcessPolicy&) = delete;
diff --git a/sandbox/policy/linux/bpf_cros_intel_gpu_policy_linux.cc b/sandbox/policy/linux/bpf_cros_intel_gpu_policy_linux.cc
index 095c645..27ac4c049 100644
--- a/sandbox/policy/linux/bpf_cros_intel_gpu_policy_linux.cc
+++ b/sandbox/policy/linux/bpf_cros_intel_gpu_policy_linux.cc
@@ -20,8 +20,8 @@
 namespace sandbox {
 namespace policy {
 
-CrosIntelGpuProcessPolicy::CrosIntelGpuProcessPolicy(bool allow_mremap)
-    : GpuProcessPolicy(allow_mremap) {}
+CrosIntelGpuProcessPolicy::CrosIntelGpuProcessPolicy(MremapPolicy mremap_policy)
+    : GpuProcessPolicy(mremap_policy) {}
 
 CrosIntelGpuProcessPolicy::~CrosIntelGpuProcessPolicy() {}
 
diff --git a/sandbox/policy/linux/bpf_cros_intel_gpu_policy_linux.h b/sandbox/policy/linux/bpf_cros_intel_gpu_policy_linux.h
index 324eae6..e142da2f 100644
--- a/sandbox/policy/linux/bpf_cros_intel_gpu_policy_linux.h
+++ b/sandbox/policy/linux/bpf_cros_intel_gpu_policy_linux.h
@@ -15,7 +15,7 @@
 // This policy is for ChromeOS running on Intel GPUs.
 class SANDBOX_POLICY_EXPORT CrosIntelGpuProcessPolicy : public GpuProcessPolicy {
  public:
-  explicit CrosIntelGpuProcessPolicy(bool allow_mremap);
+  explicit CrosIntelGpuProcessPolicy(MremapPolicy mremap_policy);
 
   CrosIntelGpuProcessPolicy(const CrosIntelGpuProcessPolicy&) = delete;
   CrosIntelGpuProcessPolicy& operator=(const CrosIntelGpuProcessPolicy&) = delete;
diff --git a/sandbox/policy/linux/bpf_cros_nvidia_gpu_policy_linux.cc b/sandbox/policy/linux/bpf_cros_nvidia_gpu_policy_linux.cc
index f5104bba..c4e4614 100644
--- a/sandbox/policy/linux/bpf_cros_nvidia_gpu_policy_linux.cc
+++ b/sandbox/policy/linux/bpf_cros_nvidia_gpu_policy_linux.cc
@@ -20,8 +20,9 @@
 
 namespace sandbox::policy {
 
-CrosNvidiaGpuProcessPolicy::CrosNvidiaGpuProcessPolicy(bool allow_mremap)
-    : GpuProcessPolicy(allow_mremap) {}
+CrosNvidiaGpuProcessPolicy::CrosNvidiaGpuProcessPolicy(
+    MremapPolicy mremap_policy)
+    : GpuProcessPolicy(mremap_policy) {}
 
 CrosNvidiaGpuProcessPolicy::~CrosNvidiaGpuProcessPolicy() = default;
 
diff --git a/sandbox/policy/linux/bpf_cros_nvidia_gpu_policy_linux.h b/sandbox/policy/linux/bpf_cros_nvidia_gpu_policy_linux.h
index 2b61449..6dc412c3 100644
--- a/sandbox/policy/linux/bpf_cros_nvidia_gpu_policy_linux.h
+++ b/sandbox/policy/linux/bpf_cros_nvidia_gpu_policy_linux.h
@@ -15,7 +15,7 @@
 class SANDBOX_POLICY_EXPORT CrosNvidiaGpuProcessPolicy
     : public GpuProcessPolicy {
  public:
-  explicit CrosNvidiaGpuProcessPolicy(bool allow_mremap);
+  explicit CrosNvidiaGpuProcessPolicy(MremapPolicy mremap_policy);
 
   CrosNvidiaGpuProcessPolicy(const CrosNvidiaGpuProcessPolicy&) = delete;
   CrosNvidiaGpuProcessPolicy& operator=(const CrosNvidiaGpuProcessPolicy&) =
diff --git a/sandbox/policy/linux/bpf_cros_virtio_gpu_policy_linux.cc b/sandbox/policy/linux/bpf_cros_virtio_gpu_policy_linux.cc
index 1f385d90..b91c555 100644
--- a/sandbox/policy/linux/bpf_cros_virtio_gpu_policy_linux.cc
+++ b/sandbox/policy/linux/bpf_cros_virtio_gpu_policy_linux.cc
@@ -20,8 +20,9 @@
 
 namespace sandbox::policy {
 
-CrosVirtIoGpuProcessPolicy::CrosVirtIoGpuProcessPolicy(bool allow_mremap)
-    : GpuProcessPolicy(allow_mremap) {}
+CrosVirtIoGpuProcessPolicy::CrosVirtIoGpuProcessPolicy(
+    MremapPolicy mremap_policy)
+    : GpuProcessPolicy(mremap_policy) {}
 
 CrosVirtIoGpuProcessPolicy::~CrosVirtIoGpuProcessPolicy() = default;
 
diff --git a/sandbox/policy/linux/bpf_cros_virtio_gpu_policy_linux.h b/sandbox/policy/linux/bpf_cros_virtio_gpu_policy_linux.h
index 76cdab0..43e83d3 100644
--- a/sandbox/policy/linux/bpf_cros_virtio_gpu_policy_linux.h
+++ b/sandbox/policy/linux/bpf_cros_virtio_gpu_policy_linux.h
@@ -15,7 +15,7 @@
 class SANDBOX_POLICY_EXPORT CrosVirtIoGpuProcessPolicy
     : public GpuProcessPolicy {
  public:
-  explicit CrosVirtIoGpuProcessPolicy(bool allow_mremap);
+  explicit CrosVirtIoGpuProcessPolicy(MremapPolicy mremap_policy);
 
   CrosVirtIoGpuProcessPolicy(const CrosVirtIoGpuProcessPolicy&) = delete;
   CrosVirtIoGpuProcessPolicy& operator=(const CrosVirtIoGpuProcessPolicy&) =
diff --git a/sandbox/policy/linux/bpf_gpu_policy_linux.cc b/sandbox/policy/linux/bpf_gpu_policy_linux.cc
index c6caf2e9..aa14d6a 100644
--- a/sandbox/policy/linux/bpf_gpu_policy_linux.cc
+++ b/sandbox/policy/linux/bpf_gpu_policy_linux.cc
@@ -34,8 +34,8 @@
 namespace sandbox {
 namespace policy {
 
-GpuProcessPolicy::GpuProcessPolicy(bool allow_mremap)
-    : allow_mremap_(allow_mremap) {}
+GpuProcessPolicy::GpuProcessPolicy(MremapPolicy mremap_policy)
+    : mremap_policy_(mremap_policy) {}
 
 GpuProcessPolicy::~GpuProcessPolicy() {}
 
@@ -91,7 +91,7 @@
       return Allow();
     // XNNPACK needs mremap when building weight caches.
     case __NR_mremap:
-      if (allow_mremap_) {
+      if (mremap_policy_ == MremapPolicy::kAllow) {
         return RestrictMremapFlagsForODML();
       }
       break;
diff --git a/sandbox/policy/linux/bpf_gpu_policy_linux.h b/sandbox/policy/linux/bpf_gpu_policy_linux.h
index 472abb8..cf02752 100644
--- a/sandbox/policy/linux/bpf_gpu_policy_linux.h
+++ b/sandbox/policy/linux/bpf_gpu_policy_linux.h
@@ -12,9 +12,14 @@
 namespace sandbox {
 namespace policy {
 
+enum class MremapPolicy {
+  kBlock,
+  kAllow,
+};
+
 class SANDBOX_POLICY_EXPORT GpuProcessPolicy : public BPFBasePolicy {
  public:
-  explicit GpuProcessPolicy(bool allow_mremap);
+  explicit GpuProcessPolicy(MremapPolicy mremap_policy);
 
   GpuProcessPolicy(const GpuProcessPolicy&) = delete;
   GpuProcessPolicy& operator=(const GpuProcessPolicy&) = delete;
@@ -24,7 +29,7 @@
   bpf_dsl::ResultExpr EvaluateSyscall(int system_call_number) const override;
 
  private:
-  bool allow_mremap_;
+  MremapPolicy mremap_policy_;
 };
 
 }  // namespace policy
diff --git a/sandbox/policy/linux/sandbox_seccomp_bpf_linux.cc b/sandbox/policy/linux/sandbox_seccomp_bpf_linux.cc
index 0a62972..80299df 100644
--- a/sandbox/policy/linux/sandbox_seccomp_bpf_linux.cc
+++ b/sandbox/policy/linux/sandbox_seccomp_bpf_linux.cc
@@ -124,27 +124,27 @@
 
 std::unique_ptr<BPFBasePolicy> GetGpuProcessSandbox(
     const SandboxSeccompBPF::Options& options,
-    bool allow_mremap) {
+    MremapPolicy mremap_policy) {
   if (IsChromeOS() || UseChromecastSandboxAllowlist()) {
     if (IsArchitectureArm()) {
       return std::make_unique<CrosArmGpuProcessPolicy>(
-          allow_mremap, base::CommandLine::ForCurrentProcess()->HasSwitch(
-                            switches::kGpuSandboxAllowSysVShm));
+          mremap_policy, base::CommandLine::ForCurrentProcess()->HasSwitch(
+                             switches::kGpuSandboxAllowSysVShm));
     }
     if (options.use_amd_specific_policies) {
-      return std::make_unique<CrosAmdGpuProcessPolicy>(allow_mremap);
+      return std::make_unique<CrosAmdGpuProcessPolicy>(mremap_policy);
     }
     if (options.use_intel_specific_policies) {
-      return std::make_unique<CrosIntelGpuProcessPolicy>(allow_mremap);
+      return std::make_unique<CrosIntelGpuProcessPolicy>(mremap_policy);
     }
     if (options.use_nvidia_specific_policies) {
-      return std::make_unique<CrosNvidiaGpuProcessPolicy>(allow_mremap);
+      return std::make_unique<CrosNvidiaGpuProcessPolicy>(mremap_policy);
     }
     if (options.use_virtio_specific_policies) {
-      return std::make_unique<CrosVirtIoGpuProcessPolicy>(allow_mremap);
+      return std::make_unique<CrosVirtIoGpuProcessPolicy>(mremap_policy);
     }
   }
-  return std::make_unique<GpuProcessPolicy>(allow_mremap);
+  return std::make_unique<GpuProcessPolicy>(mremap_policy);
 }
 #endif  // !defined(IN_NACL_HELPER)
 
@@ -187,11 +187,11 @@
     const SandboxSeccompBPF::Options& options) {
   switch (sandbox_type) {
     case sandbox::mojom::Sandbox::kGpu:
-      return GetGpuProcessSandbox(options, /*allow_mremap=*/false);
+      return GetGpuProcessSandbox(options, MremapPolicy::kBlock);
     case sandbox::mojom::Sandbox::kRenderer:
       return std::make_unique<RendererProcessPolicy>();
     case sandbox::mojom::Sandbox::kOnDeviceModelExecution:
-      return GetGpuProcessSandbox(options, /*allow_mremap=*/true);
+      return GetGpuProcessSandbox(options, MremapPolicy::kAllow);
     case sandbox::mojom::Sandbox::kUtility:
       return std::make_unique<UtilityProcessPolicy>();
     case sandbox::mojom::Sandbox::kCdm:
@@ -228,7 +228,7 @@
       // TODO(b/255554267): we're using the GPU process sandbox policy for now
       // as a transition step. However, we should create a policy that's tighter
       // just for hardware video encoding.
-      return GetGpuProcessSandbox(options, /*allow_mremap=*/false);
+      return GetGpuProcessSandbox(options, MremapPolicy::kBlock);
 #endif  // BUILDFLAG(USE_LINUX_VIDEO_ACCELERATION)
 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 #if BUILDFLAG(IS_LINUX)
diff --git a/services/network/prefetch_url_loader_client_unittest.cc b/services/network/prefetch_url_loader_client_unittest.cc
index f1a6e89..619c010 100644
--- a/services/network/prefetch_url_loader_client_unittest.cc
+++ b/services/network/prefetch_url_loader_client_unittest.cc
@@ -204,9 +204,9 @@
   // `ssl_info` is omitted as it lacks an equality operator and it's not worth
   // implementing one just for this test.
   return equals(&S::error_code) && equals(&S::extended_error_code) &&
-         equals(&S::exists_in_cache) && equals(&S::exists_in_memory_cache) &&
-         equals(&S::encoded_data_length) && equals(&S::encoded_body_length) &&
-         equals(&S::decoded_body_length) && equals(&S::cors_error_status) &&
+         equals(&S::exists_in_cache) && equals(&S::encoded_data_length) &&
+         equals(&S::encoded_body_length) && equals(&S::decoded_body_length) &&
+         equals(&S::cors_error_status) &&
          equals(&S::private_network_access_preflight_result) &&
          equals(&S::trust_token_operation_status) &&
          equals(&S::blocked_by_response_reason) &&
diff --git a/services/network/public/cpp/network_param_mojom_traits_unittest.cc b/services/network/public/cpp/network_param_mojom_traits_unittest.cc
index fa8b8a4..5340aead 100644
--- a/services/network/public/cpp/network_param_mojom_traits_unittest.cc
+++ b/services/network/public/cpp/network_param_mojom_traits_unittest.cc
@@ -59,4 +59,34 @@
   }
 }
 
+// Ensure that attempting to deserialize a proxy chain with an invalid state
+// fails gracefully.
+TEST(ProxyChain, DeserializeProxyChainWithInvalidState) {
+  // Construct a network::mojom::ProxyChain with an invalid state (one that
+  // could not have been created by serialization of a net::ProxyChain).
+  network::mojom::ProxyChainPtr mojom_chain = network::mojom::ProxyChain::New();
+  std::vector<net::ProxyServer> proxy_servers{net::ProxyServer()};
+  mojom_chain->proxy_servers = std::make_optional(std::move(proxy_servers));
+  mojom_chain->ip_protection_chain_id =
+      net::ProxyChain::kNotIpProtectionChainId;
+
+  net::ProxyChain copied;
+  // Deserialization should fail gracefully without crashing.
+  EXPECT_FALSE(mojo::test::SerializeAndDeserialize<network::mojom::ProxyChain>(
+      mojom_chain, copied));
+}
+
+// Same as above but for an IP Protection proxy chain.
+TEST(ProxyChain, DeserializeProxyChainWithInvalidStateIpProtection) {
+  network::mojom::ProxyChainPtr mojom_chain = network::mojom::ProxyChain::New();
+  std::vector<net::ProxyServer> proxy_servers{net::ProxyServer()};
+  mojom_chain->proxy_servers = std::make_optional(std::move(proxy_servers));
+  mojom_chain->ip_protection_chain_id =
+      net::ProxyChain::kMaxIpProtectionChainId;
+
+  net::ProxyChain copied;
+  EXPECT_FALSE(mojo::test::SerializeAndDeserialize<network::mojom::ProxyChain>(
+      mojom_chain, copied));
+}
+
 }  // namespace network
diff --git a/services/network/public/cpp/url_loader_completion_status.cc b/services/network/public/cpp/url_loader_completion_status.cc
index 9bf10fc..dc1de7d5 100644
--- a/services/network/public/cpp/url_loader_completion_status.cc
+++ b/services/network/public/cpp/url_loader_completion_status.cc
@@ -35,7 +35,6 @@
   return error_code == rhs.error_code &&
          extended_error_code == rhs.extended_error_code &&
          exists_in_cache == rhs.exists_in_cache &&
-         exists_in_memory_cache == rhs.exists_in_memory_cache &&
          completion_time == rhs.completion_time &&
          encoded_data_length == rhs.encoded_data_length &&
          encoded_body_length == rhs.encoded_body_length &&
diff --git a/services/network/public/cpp/url_loader_completion_status.h b/services/network/public/cpp/url_loader_completion_status.h
index 041e93d..0e92a19c 100644
--- a/services/network/public/cpp/url_loader_completion_status.h
+++ b/services/network/public/cpp/url_loader_completion_status.h
@@ -57,9 +57,6 @@
   // cache.
   bool exists_in_cache = false;
 
-  // A copy of the data requested exists in the in-memory cache.
-  bool exists_in_memory_cache = false;
-
   // Time the request completed.
   base::TimeTicks completion_time;
 
diff --git a/services/network/public/cpp/url_loader_completion_status_mojom_traits.cc b/services/network/public/cpp/url_loader_completion_status_mojom_traits.cc
index dc0bf40..b60c376a 100644
--- a/services/network/public/cpp/url_loader_completion_status_mojom_traits.cc
+++ b/services/network/public/cpp/url_loader_completion_status_mojom_traits.cc
@@ -35,7 +35,6 @@
   out->error_code = data.error_code();
   out->extended_error_code = data.extended_error_code();
   out->exists_in_cache = data.exists_in_cache();
-  out->exists_in_memory_cache = data.exists_in_memory_cache();
   out->encoded_data_length = data.encoded_data_length();
   out->encoded_body_length = data.encoded_body_length();
   out->decoded_body_length = data.decoded_body_length();
diff --git a/services/network/public/cpp/url_loader_completion_status_mojom_traits.h b/services/network/public/cpp/url_loader_completion_status_mojom_traits.h
index fb3a065c..fd5e0fe 100644
--- a/services/network/public/cpp/url_loader_completion_status_mojom_traits.h
+++ b/services/network/public/cpp/url_loader_completion_status_mojom_traits.h
@@ -54,11 +54,6 @@
     return status.exists_in_cache;
   }
 
-  static bool exists_in_memory_cache(
-      const network::URLLoaderCompletionStatus& status) {
-    return status.exists_in_memory_cache;
-  }
-
   static const base::TimeTicks& completion_time(
       const network::URLLoaderCompletionStatus& status) {
     return status.completion_time;
diff --git a/services/network/public/mojom/url_loader_completion_status.mojom b/services/network/public/mojom/url_loader_completion_status.mojom
index 0eaa534..e1744bd 100644
--- a/services/network/public/mojom/url_loader_completion_status.mojom
+++ b/services/network/public/mojom/url_loader_completion_status.mojom
@@ -30,9 +30,6 @@
   // to represent what this field actually means.
   bool exists_in_cache = false;
 
-  // A copy of the data requested exists in the in-memory cache.
-  bool exists_in_memory_cache = false;
-
   // Time the request completed.
   mojo_base.mojom.TimeTicks completion_time;
 
diff --git a/services/webnn/ort/graph_builder_ort.cc b/services/webnn/ort/graph_builder_ort.cc
index 3653cfc..42014fa 100644
--- a/services/webnn/ort/graph_builder_ort.cc
+++ b/services/webnn/ort/graph_builder_ort.cc
@@ -1173,41 +1173,18 @@
 
 void GraphBuilderOrt::AddEluOperation(const mojom::Elu& elu) {
   const std::string node_name = GenerateNodeName(elu.label);
-  std::string input = GetOperandNameById(elu.input_operand_id);
+  const std::string input = GetOperandNameById(elu.input_operand_id);
   const std::string output = GetOperandNameById(elu.output_operand_id);
 
-  const OperandDescriptor& input_descriptor =
-      GetOperand(elu.input_operand_id).descriptor;
   CHECK(context_properties_.data_type_limits.elu_input.Supports(
-      input_descriptor));
-
-  // ONNX elu only supports 1-D input tensor, so we need to create a reshape
-  // node to convert the input tensor to 1-D tensor.
-  // TODO(crbug.com/430960849): Remove the workaround for elu's 1D input tensor
-  // limitation when the ONNX issue is fixed.
-  // https://github.com/onnx/onnx/issues/7119
-  bool need_reshape = input_descriptor.Rank() != 1;
-  std::vector<uint32_t> input_shape = input_descriptor.shape();
-  std::string elu_output = output;
-  if (need_reshape) {
-    std::array<uint32_t, 1> new_shape = {
-        base::checked_cast<uint32_t>(input_descriptor.NumberOfElements())};
-    input = CreateReshapeNode(input, new_shape);
-    elu_output = GenerateOperandName();
-  }
+      GetOperand(elu.input_operand_id).descriptor));
 
   std::array<ScopedOrtOpAttr, 1> attributes = {
       model_editor_.CreateAttribute(kAttrAlpha, elu.alpha)};
 
   std::array<const char*, 1> inputs = {input.c_str()};
-  std::array<const char*, 1> outputs = {elu_output.c_str()};
+  std::array<const char*, 1> outputs = {output.c_str()};
   model_editor_.AddNode(kOpTypeElu, node_name, inputs, outputs, attributes);
-
-  // Insert a reshape node to convert the output tensor back to the original
-  // shape.
-  if (need_reshape) {
-    InsertReshapeNode(elu_output, output, input_shape);
-  }
 }
 
 // TODO(crbug.com/426228071): Eliminate redundant cast ops for bool and uint8
diff --git a/services/webnn/tflite/graph_builder_tflite.cc b/services/webnn/tflite/graph_builder_tflite.cc
index 5ffa822..b39f5bb 100644
--- a/services/webnn/tflite/graph_builder_tflite.cc
+++ b/services/webnn/tflite/graph_builder_tflite.cc
@@ -4470,10 +4470,6 @@
       GetOperand(gather.input_operand_id).descriptor));
   CHECK(context_properties_.data_type_limits.gather_indices.Supports(
       GetOperand(gather.indices_operand_id).descriptor));
-  ASSIGN_OR_RETURN(const TensorInfo& indices_tensor_info,
-                   SerializeInputTensorInfo(gather.indices_operand_id));
-  const TensorIndex indices_tensor_index =
-      CastGatherIndices(indices_tensor_info);
 
   // The WebNN axis option is uint32 data type, but TFLite axis needs int32
   // type, so the axis need to be validated here to not overflow.
@@ -4496,6 +4492,22 @@
       fuse_dequantize
           ? quantized_output->index
           : SerializeOutputTensorInfo(gather.output_operand_id).index;
+
+  ASSIGN_OR_RETURN(const TensorInfo& indices_tensor_info,
+                   SerializeInputTensorInfo(gather.indices_operand_id));
+  TensorIndex indices_tensor_index;
+  if (indices_tensor_info.data_type == ::tflite::TensorType_UINT32 ||
+      indices_tensor_info.data_type == ::tflite::TensorType_INT64) {
+    ASSIGN_OR_RETURN(indices_tensor_index,
+                     SerializeGatherIndices<int64_t>(
+                         indices_tensor_info, input_tensor_info, gather.axis));
+  } else {
+    CHECK_EQ(indices_tensor_info.data_type, ::tflite::TensorType_INT32);
+    ASSIGN_OR_RETURN(indices_tensor_index,
+                     SerializeGatherIndices<int32_t>(
+                         indices_tensor_info, input_tensor_info, gather.axis));
+  }
+
   const OperatorCodeIndex operator_code_index =
       GetOperatorCodeIndex(::tflite::BuiltinOperator_GATHER);
   const std::array<TensorIndex, 2> op_inputs = {input_tensor_info.index,
@@ -4509,9 +4521,10 @@
 }
 
 template <typename DataType>
-auto GraphBuilderTflite::SerializeGatherNDIndices(
+auto GraphBuilderTflite::SerializeGatherIndices(
     const TensorInfo& indices_tensor_info,
-    const TensorInfo& input_tensor_info)
+    const TensorInfo& input_tensor_info,
+    std::optional<uint32_t> gather_axis)
     -> base::expected<TensorIndex, std::string> {
   // The values in `indices` are computed at runtime, so they can exceed the
   // boundary of the `axis` dimension of input. If unchecked, such indices will
@@ -4519,19 +4532,32 @@
   // to be in range of `-N` (inclusive) to `N` (exclusive), where `N =
   // input.dimensions[axis]`, but TFLite doesn't support the negative index
   // (index from the end of the `axis` dimension).
-  // TODO(crbug.com/373192621): Support negative indices to avoid the runtime
-  // error.
   const size_t indices_rank = indices_tensor_info.dimensions.size();
-  const size_t indices_nd = indices_tensor_info.dimensions[indices_rank - 1];
-  if (indices_nd == input_tensor_info.dimensions.size()) {
-    return base::unexpected(
-        "TFLite doesn't support to gather input into one dimension.");
-  }
+  const int32_t indices_nd =
+      gather_axis ? 1 : indices_tensor_info.dimensions[indices_rank - 1];
   base::FixedArray<DataType> min_values(indices_nd);
   base::FixedArray<DataType> max_values(indices_nd);
-  for (size_t axis = 0; axis < indices_nd; ++axis) {
-    min_values[axis] = -(input_tensor_info.dimensions[axis]);
-    max_values[axis] = input_tensor_info.dimensions[axis] - 1;
+  TensorIndex axis_boundary_tensor_index;
+  if (gather_axis) {
+    // Gather operation.
+    const DataType axis_boundary = input_tensor_info.dimensions[*gather_axis];
+    min_values[0] = -axis_boundary;
+    max_values[0] = axis_boundary - 1;
+    axis_boundary_tensor_index = SerializeTensorWithBuffer<DataType>(
+        /*buffer=*/std::array<DataType, 1>{axis_boundary},
+        /*dimensions=*/{});
+  } else {
+    // GatherND operation.
+    base::FixedArray<DataType> axes_boundary(indices_nd);
+    for (int32_t axis = 0; axis < indices_nd; ++axis) {
+      const DataType axis_boundary = input_tensor_info.dimensions[axis];
+      min_values[axis] = -axis_boundary;
+      max_values[axis] = axis_boundary - 1;
+      axes_boundary[axis] = axis_boundary;
+    }
+    axis_boundary_tensor_index = SerializeTensorWithBuffer<DataType>(
+        /*buffer=*/axes_boundary,
+        /*dimensions=*/{indices_nd});
   }
   TensorIndex indices_tensor_index = CastGatherIndices(indices_tensor_info);
   ::tflite::TensorType cast_tensor_type =
@@ -4545,7 +4571,28 @@
                  indices_tensor_info.dimensions),
       clamp_tensor_index, min_values, max_values));
 
-  return clamp_tensor_index;
+  // Shift negative indices to positive by the subgraph `where(lesser(indices,
+  // constant(0)), indices, add(indices, constant(input.dimensions[axis])))`.
+  TensorIndex lesser_tensor_index = SerializeTemporaryTensor(
+      indices_tensor_info.dimensions, ::tflite::TensorType_BOOL);
+  const TensorIndex zero_value_tensor_index =
+      SerializeTensorWithBuffer<DataType>(
+          /*buffer=*/std::array<DataType, 1>{0},
+          /*dimensions=*/{});
+  operators_.emplace_back(SerializeBinaryOperation(
+      ::tflite::BuiltinOperator_LESS, clamp_tensor_index,
+      zero_value_tensor_index, lesser_tensor_index));
+  TensorIndex add_tensor_index = SerializeTemporaryTensor(
+      indices_tensor_info.dimensions, cast_tensor_type);
+  operators_.emplace_back(SerializeBinaryOperation(
+      ::tflite::BuiltinOperator_ADD, clamp_tensor_index,
+      axis_boundary_tensor_index, add_tensor_index));
+  TensorIndex where_tensor_index = SerializeTemporaryTensor(
+      indices_tensor_info.dimensions, cast_tensor_type);
+  operators_.emplace_back(
+      SerializeWhereOperation(lesser_tensor_index, add_tensor_index,
+                              clamp_tensor_index, where_tensor_index));
+  return where_tensor_index;
 }
 
 auto GraphBuilderTflite::SerializeGatherNDOperation(
@@ -4655,13 +4702,13 @@
   if (indices_tensor_info.data_type == ::tflite::TensorType_UINT32 ||
       indices_tensor_info.data_type == ::tflite::TensorType_INT64) {
     ASSIGN_OR_RETURN(indices_tensor_index,
-                     SerializeGatherNDIndices<int64_t>(indices_tensor_info,
-                                                       input_tensor_info));
+                     SerializeGatherIndices<int64_t>(indices_tensor_info,
+                                                     input_tensor_info));
   } else {
     CHECK_EQ(indices_tensor_info.data_type, ::tflite::TensorType_INT32);
     ASSIGN_OR_RETURN(indices_tensor_index,
-                     SerializeGatherNDIndices<int32_t>(indices_tensor_info,
-                                                       input_tensor_info));
+                     SerializeGatherIndices<int32_t>(indices_tensor_info,
+                                                     input_tensor_info));
   }
 
   const TensorIndex output_tensor_index =
diff --git a/services/webnn/tflite/graph_builder_tflite.h b/services/webnn/tflite/graph_builder_tflite.h
index 6ded8ad..e10a9ae 100644
--- a/services/webnn/tflite/graph_builder_tflite.h
+++ b/services/webnn/tflite/graph_builder_tflite.h
@@ -285,9 +285,10 @@
 
   // Serialize gather_nd indices tensor.
   template <typename DataType>
-  base::expected<TensorIndex, std::string> SerializeGatherNDIndices(
+  base::expected<TensorIndex, std::string> SerializeGatherIndices(
       const TensorInfo& indices_tensor_info,
-      const TensorInfo& input_tensor_info);
+      const TensorInfo& input_tensor_info,
+      std::optional<uint32_t> gather_axis = std::nullopt);
   TensorIndex CastGatherIndices(const TensorInfo& indices_tensor_info);
 
   // This function is called by `SerializeGatherND` to serialize WebNN
diff --git a/testing/test.gni b/testing/test.gni
index 1ebfbd5..9883ddad 100644
--- a/testing/test.gni
+++ b/testing/test.gni
@@ -300,12 +300,9 @@
 
           fuzzer_args_joined = string_join(" ", _fuzzer_args)
 
-          NEWLINE = "$0x0A"
-
-          contents =
-              "const char* kFuzzerArgs = \"${fuzzer_args_joined}\";" + NEWLINE +
-              "const char* kFuzzerBinary = \"${_fuzzer_binary_name}\";" +
-              NEWLINE
+          contents = "const char* kFuzzerArgs = \"${fuzzer_args_joined}\";
+const char* kFuzzerBinary = \"${_fuzzer_binary_name}\";
+"
         }
 
         _additional_fuzz_deps = []
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 552884f..6946780 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -2931,21 +2931,6 @@
             ]
         }
     ],
-    "AutofillVirtualViewStructureAndroidPasskeyLongPress": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "AutofillVirtualViewStructureAndroidPasskeyLongPress"
-                    ]
-                }
-            ]
-        }
-    ],
     "AutomatedPasswordChangeStudy": [
         {
             "platforms": [
@@ -7465,28 +7450,6 @@
             ]
         }
     ],
-    "DSEPrewarm": [
-        {
-            "platforms": [
-                "chromeos",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled_20260624_Dogfood",
-                    "params": {
-                        "url": "https://www.google.com/",
-                        "zero_suggest_trigger": "true"
-                    },
-                    "enable_features": [
-                        "Prewarm"
-                    ]
-                }
-            ]
-        }
-    ],
     "DTCAntivirusSignalEnabled": [
         {
             "platforms": [
@@ -8634,6 +8597,29 @@
             ]
         }
     ],
+    "DiskCacheBackendExperiment": [
+        {
+            "platforms": [
+                "android",
+                "android_webview",
+                "chromeos",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Sql",
+                    "params": {
+                        "backend": "sql"
+                    },
+                    "enable_features": [
+                        "DiskCacheBackendExperiment"
+                    ]
+                }
+            ]
+        }
+    ],
     "DisplayEdgeToEdgeFullscreen": [
         {
             "platforms": [
@@ -9350,6 +9336,21 @@
             ]
         }
     ],
+    "EnablePixAccountLinking": [
+        {
+            "platforms": [
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "EnablePixAccountLinking"
+                    ]
+                }
+            ]
+        }
+    ],
     "EnablePolicyPromotionBanner": [
         {
             "platforms": [
@@ -15432,6 +15433,7 @@
                 {
                     "name": "Enabled",
                     "params": {
+                        "http_cache_transaction": "true",
                         "http_proxy_connect_job": "true",
                         "http_stream_factory_job": "true",
                         "http_stream_factory_job_controller": "true",
@@ -18517,6 +18519,26 @@
             ]
         }
     ],
+    "PrioritizeHttpsResourceRecord": [
+        {
+            "platforms": [
+                "android",
+                "chromeos",
+                "ios",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "PrioritizeHttpsResourceRecord"
+                    ]
+                }
+            ]
+        }
+    ],
     "PrivacySandboxActivityTypeStorage": [
         {
             "platforms": [
@@ -20080,6 +20102,22 @@
             ]
         }
     ],
+    "ReloadHiddenTabsWithActiveCrashedSubframes": [
+        {
+            "platforms": [
+                "android",
+                "android_webview"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "ReloadHiddenTabsWithActiveCrashedSubframes"
+                    ]
+                }
+            ]
+        }
+    ],
     "ReloadSelectionModel": [
         {
             "platforms": [
diff --git a/third_party/angle b/third_party/angle
index 214a48c4..9635df8 160000
--- a/third_party/angle
+++ b/third_party/angle
@@ -1 +1 @@
-Subproject commit 214a48c41a84799cdf7cf821fcb0e3a0fccd2b11
+Subproject commit 9635df8e92696c1434a7f2c5c4ea7dde84c38a6a
diff --git a/third_party/blink/renderer/bindings/core/v8/boxed_v8_module_test.cc b/third_party/blink/renderer/bindings/core/v8/boxed_v8_module_test.cc
index 1dd00ea..a8a187b 100644
--- a/third_party/blink/renderer/bindings/core/v8/boxed_v8_module_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/boxed_v8_module_test.cc
@@ -34,7 +34,7 @@
   EXPECT_TRUE(Traits::Equal(module_a, module_a));
   EXPECT_FALSE(Traits::Equal(module_a, module_b));
 
-  EXPECT_NE(WTF::GetHash(module_a), WTF::GetHash(module_b));
+  EXPECT_NE(GetHash(module_a), GetHash(module_b));
 }
 
 }  // namespace
diff --git a/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h b/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h
index 7ff1fb6b..862be20d 100644
--- a/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h
+++ b/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h
@@ -53,10 +53,10 @@
   }
 
   static unsigned GetHash(const v8::CpuProfileNode* node) {
-    return WTF::GetHash(node->GetFunctionNameStr()) ^
-           WTF::GetHash(node->GetScriptResourceNameStr()) ^
-           WTF::GetHash(node->GetLineNumber()) ^
-           WTF::GetHash(node->GetColumnNumber());
+    return blink::GetHash(node->GetFunctionNameStr()) ^
+           blink::GetHash(node->GetScriptResourceNameStr()) ^
+           blink::GetHash(node->GetLineNumber()) ^
+           blink::GetHash(node->GetColumnNumber());
   }
 
   static constexpr bool kSafeToCompareToEmptyOrDeleted = false;
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc b/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc
index c863f90..e9d3787 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc
@@ -64,7 +64,7 @@
   // later load the script from the cache and interpret it with a different
   // encoding, the cached data is not valid for that encoding.
   return (v8_cache_data_version | kind) +
-         (encoding.IsNull() ? 0 : WTF::GetHash(encoding));
+         (encoding.IsNull() ? 0 : GetHash(encoding));
 }
 
 bool TimestampIsRecent(const CachedMetadata* cached_metadata) {
diff --git a/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h b/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h
index 3e4584d..6aaa82b 100644
--- a/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h
+++ b/third_party/blink/renderer/core/accessibility/blink_ax_event_intent.h
@@ -109,7 +109,7 @@
 };
 
 struct CORE_EXPORT BlinkAXEventIntentHashTraits
-    : WTF::SimpleClassHashTraits<BlinkAXEventIntent> {
+    : SimpleClassHashTraits<BlinkAXEventIntent> {
   // Computes the hash of a BlinkAXEventIntent instance.
   static unsigned GetHash(const BlinkAXEventIntent& key);
   // Zeroed memory cannot be used for BlinkAXEventIntent.
diff --git a/third_party/blink/renderer/core/animation/length_property_functions.cc b/third_party/blink/renderer/core/animation/length_property_functions.cc
index a8a8c06..27971bb5 100644
--- a/third_party/blink/renderer/core/animation/length_property_functions.cc
+++ b/third_party/blink/renderer/core/animation/length_property_functions.cc
@@ -332,7 +332,7 @@
       success = true;
       break;
     case CSSPropertyID::kLetterSpacing:
-      // TODO(crbug.com/327740939): Change to |style.SpecifiedLetterSpacing()|
+      // TODO(crbug.com/327740939): Change to |style.ComputedLetterSpacing()|
       result = Length::Fixed(style.LetterSpacing());
       success = true;
       break;
diff --git a/third_party/blink/renderer/core/animation/property_handle.cc b/third_party/blink/renderer/core/animation/property_handle.cc
index 9af58bc..f3d3642 100644
--- a/third_party/blink/renderer/core/animation/property_handle.cc
+++ b/third_party/blink/renderer/core/animation/property_handle.cc
@@ -27,7 +27,7 @@
     case kHandleCSSProperty:
       return static_cast<int>(css_property_->PropertyID());
     case kHandleCSSCustomProperty:
-      return WTF::GetHash(property_name_);
+      return blink::GetHash(property_name_);
     default:
       NOTREACHED();
   }
diff --git a/third_party/blink/renderer/core/canvas_interventions/canvas_interventions_helper.cc b/third_party/blink/renderer/core/canvas_interventions/canvas_interventions_helper.cc
index 619b65f1..160d714 100644
--- a/third_party/blink/renderer/core/canvas_interventions/canvas_interventions_helper.cc
+++ b/third_party/blink/renderer/core/canvas_interventions/canvas_interventions_helper.cc
@@ -93,7 +93,7 @@
   if (precursor_origin->IsOpaque()) {
     return String::Format(
         "opaque || %u",
-        WTF::GetHash(scoped_refptr<const SecurityOrigin>(precursor_origin)));
+        GetHash(scoped_refptr<const SecurityOrigin>(precursor_origin)));
   }
   // RegistrableDomain() returns null in a couple of cases, such as URLs with IP
   // addresses. In these cases we can safely return the host.
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5
index 2e22010b..7a974e8 100644
--- a/third_party/blink/renderer/core/css/css_properties.json5
+++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -3809,7 +3809,7 @@
       field_group: "inherited",
       field_template: "<length>",
       default_value: "Length::Fixed()",
-      getter: "SpecifiedLetterSpacing",
+      getter: "ComputedLetterSpacing",
       converter: "ConvertSpacing",
       computed_style_custom_functions: ["getter"],
       typedom_types: ["Keyword", "Length", "Percentage"],
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 0062510..2e4d05c 100644
--- a/third_party/blink/renderer/core/css/css_property_equality.cc
+++ b/third_party/blink/renderer/core/css/css_property_equality.cc
@@ -500,7 +500,7 @@
     case CSSPropertyID::kLeft:
       return a.Left() == b.Left();
     case CSSPropertyID::kLetterSpacing:
-      return a.SpecifiedLetterSpacing() == b.SpecifiedLetterSpacing();
+      return a.ComputedLetterSpacing() == b.ComputedLetterSpacing();
     case CSSPropertyID::kLightingColor:
       return a.LightingColor() == b.LightingColor();
     case CSSPropertyID::kLineBreak:
diff --git a/third_party/blink/renderer/core/css/css_property_name.cc b/third_party/blink/renderer/core/css/css_property_name.cc
index 30ebcef..4babfd7 100644
--- a/third_party/blink/renderer/core/css/css_property_name.cc
+++ b/third_party/blink/renderer/core/css/css_property_name.cc
@@ -41,7 +41,7 @@
 
 unsigned CSSPropertyName::GetHash() const {
   if (IsCustomProperty()) {
-    return WTF::GetHash(custom_property_name_);
+    return blink::GetHash(custom_property_name_);
   }
   return value_;
 }
diff --git a/third_party/blink/renderer/core/css/css_property_value_set.h b/third_party/blink/renderer/core/css/css_property_value_set.h
index 370b33f..3ca34dac 100644
--- a/third_party/blink/renderer/core/css/css_property_value_set.h
+++ b/third_party/blink/renderer/core/css/css_property_value_set.h
@@ -130,17 +130,17 @@
   // Can never return HashTraits<unsigned>::EmptyValue() (it is used
   // internally).
   unsigned GetHash() const {
-    if (hash_ == WTF::HashTraits<unsigned>::EmptyValue()) {
+    if (hash_ == HashTraits<unsigned>::EmptyValue()) {
       hash_ = ComputeHash();
     }
     return hash_;
   }
   unsigned GetExistingHash() const {
-    DCHECK_NE(hash_, WTF::HashTraits<unsigned>::EmptyValue());
+    DCHECK_NE(hash_, HashTraits<unsigned>::EmptyValue());
     return hash_;
   }
   bool ModifiedSinceHashing() const {
-    return hash_ == WTF::HashTraits<unsigned>::DeletedValue();
+    return hash_ == HashTraits<unsigned>::DeletedValue();
   }
 
   bool Equals(const CSSPropertyValueSet& other) {
@@ -204,7 +204,7 @@
 
   // EmptyValue() means “not computed yet”. DeletedValue() means “invalid”
   // (see GetHash()).
-  mutable unsigned hash_ = WTF::HashTraits<unsigned>::EmptyValue();
+  mutable unsigned hash_ = HashTraits<unsigned>::EmptyValue();
 
   friend class PropertySetCSSStyleDeclaration;
 };
@@ -396,8 +396,8 @@
   CSSPropertyValue* FindCSSPropertyWithName(const CSSPropertyName&);
 
   void InvalidateHashIfComputed() {
-    if (hash_ != WTF::HashTraits<unsigned>::EmptyValue()) {
-      hash_ = WTF::HashTraits<unsigned>::DeletedValue();
+    if (hash_ != HashTraits<unsigned>::EmptyValue()) {
+      hash_ = HashTraits<unsigned>::DeletedValue();
     }
   }
 
diff --git a/third_party/blink/renderer/core/css/css_value_pool.h b/third_party/blink/renderer/core/css/css_value_pool.h
index 50998c0a4..78fd4ee 100644
--- a/third_party/blink/renderer/core/css/css_value_pool.h
+++ b/third_party/blink/renderer/core/css/css_value_pool.h
@@ -66,7 +66,7 @@
 
   // Special keys for deleted and empty values. Use white and transparent as
   // they're common colors and worth having an early-out for.
-  struct ColorHashTraitsForCSSValuePool : WTF::GenericHashTraits<Color> {
+  struct ColorHashTraitsForCSSValuePool : GenericHashTraits<Color> {
     STATIC_ONLY(ColorHashTraitsForCSSValuePool);
     static unsigned GetHash(const Color& key) { return key.GetHash(); }
     static Color EmptyValue() { return Color::kTransparent; }
diff --git a/third_party/blink/renderer/core/css/parser/find_length_of_declaration_list-inl.h b/third_party/blink/renderer/core/css/parser/find_length_of_declaration_list-inl.h
index 45cb90aefd..2fae49d 100644
--- a/third_party/blink/renderer/core/css/parser/find_length_of_declaration_list-inl.h
+++ b/third_party/blink/renderer/core/css/parser/find_length_of_declaration_list-inl.h
@@ -66,7 +66,7 @@
 }
 
 // For LChar, this is trivial; just load the bytes as-is.
-static inline __m128i LoadAndCollapseHighBytes(const LChar* ptr) {
+static inline __m128i LoadAndCollapseHighBytes(const blink::LChar* ptr) {
   return _mm_loadu_si128(reinterpret_cast<const __m128i*>(ptr));
 }
 
@@ -294,7 +294,7 @@
 }
 
 __attribute__((target("avx2"))) static inline __m256i
-LoadAndCollapseHighBytesAVX2(const LChar* ptr) {
+LoadAndCollapseHighBytesAVX2(const blink::LChar* ptr) {
   return _mm256_loadu_si256(reinterpret_cast<const __m256i*>(ptr));
 }
 
@@ -483,7 +483,7 @@
       vcombine_u64(vreinterpret_u64_u8(vqmovn_u16(vreinterpretq_u16_u8(x1))),
                    vreinterpret_u64_u8(vqmovn_u16(vreinterpretq_u16_u8(x2)))));
 }
-static inline uint8x16_t LoadAndCollapseHighBytes(const LChar* ptr) {
+static inline uint8x16_t LoadAndCollapseHighBytes(const blink::LChar* ptr) {
   uint8x16_t ret;
   UNSAFE_TODO(memcpy(&ret, ptr, sizeof(ret)));
   return ret;
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 a2ea50d..5024cbb 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
@@ -6334,7 +6334,7 @@
     bool allow_visited_style,
     CSSValuePhase value_phase) const {
   if (RuntimeEnabledFeatures::CSSLetterAndWordSpacingPercentageEnabled()) {
-    const Length& spacing = style.SpecifiedLetterSpacing();
+    const Length& spacing = style.ComputedLetterSpacing();
     if (spacing.IsFixed()) {
       if (spacing.IsZero()) {
         return CSSIdentifierValue::Create(CSSValueID::kNormal);
diff --git a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc
index 3b24fca..c33327d1 100644
--- a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc
+++ b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc
@@ -51,14 +51,14 @@
   DCHECK(!std::any_of(hashes.begin(), hashes.end(),
                       [](const MatchedPropertiesHash& hash) {
                         return hash.hash ==
-                               WTF::HashTraits<unsigned>::DeletedValue();
+                               HashTraits<unsigned>::DeletedValue();
                       }))
       << "This should have been checked in AddMatchedProperties()";
   unsigned hash = StringHasher::HashMemory(base::as_byte_span(hashes));
 
   // See CSSPropertyValueSet::ComputeHash() for asserts that this is safe.
-  if (hash == WTF::HashTraits<unsigned>::EmptyValue() ||
-      hash == WTF::HashTraits<unsigned>::DeletedValue()) {
+  if (hash == HashTraits<unsigned>::EmptyValue() ||
+      hash == HashTraits<unsigned>::DeletedValue()) {
     hash ^= 0x80000000;
   }
 
diff --git a/third_party/blink/renderer/core/dom/node_lists_node_data.h b/third_party/blink/renderer/core/dom/node_lists_node_data.h
index 6e6f1efc..a2123da 100644
--- a/third_party/blink/renderer/core/dom/node_lists_node_data.h
+++ b/third_party/blink/renderer/core/dom/node_lists_node_data.h
@@ -63,9 +63,9 @@
   struct NodeListAtomicCacheMapEntryHashTraits
       : HashTraits<std::pair<CollectionType, AtomicString>> {
     static unsigned GetHash(const NamedNodeListKey& entry) {
-      return WTF::GetHash(entry.second == CSSSelector::UniversalSelectorAtom()
-                              ? g_star_atom
-                              : entry.second) +
+      return blink::GetHash(entry.second == CSSSelector::UniversalSelectorAtom()
+                                ? g_star_atom
+                                : entry.second) +
              entry.first;
     }
     static constexpr bool kSafeToCompareToEmptyOrDeleted =
diff --git a/third_party/blink/renderer/core/dom/weak_identifier_map.h b/third_party/blink/renderer/core/dom/weak_identifier_map.h
index 6fa398c..3c4f8160 100644
--- a/third_party/blink/renderer/core/dom/weak_identifier_map.h
+++ b/third_party/blink/renderer/core/dom/weak_identifier_map.h
@@ -98,8 +98,9 @@
 
   void ObjectDestroyed(T* object) {
     IdentifierType identifier = object_to_identifier_.Take(object);
-    if (!WTF::IsHashTraitsEmptyValue<HashTraits<IdentifierType>>(identifier))
+    if (!IsHashTraitsEmptyValue<HashTraits<IdentifierType>>(identifier)) {
       identifier_to_object_.erase(identifier);
+    }
     DCHECK_EQ(object_to_identifier_.size(), identifier_to_object_.size());
   }
 
diff --git a/third_party/blink/renderer/core/frame/font_matching_metrics.h b/third_party/blink/renderer/core/frame/font_matching_metrics.h
index cb02027..ae6d70b9a 100644
--- a/third_party/blink/renderer/core/frame/font_matching_metrics.h
+++ b/third_party/blink/renderer/core/frame/font_matching_metrics.h
@@ -50,10 +50,10 @@
 // A helper that defines the hash function and the invalid 'empty value' that
 // HashMap should use internally.
 struct IdentifiableTokenKeyHashTraits
-    : WTF::SimpleClassHashTraits<IdentifiableTokenKey> {
+    : SimpleClassHashTraits<IdentifiableTokenKey> {
   static unsigned GetHash(const IdentifiableTokenKey& key) {
-    return WTF::GetHash(key.token.ToUkmMetricValue()) ^
-           WTF::GetHash((key.is_deleted_value << 1) + key.is_empty_value);
+    return blink::GetHash(key.token.ToUkmMetricValue()) ^
+           blink::GetHash((key.is_deleted_value << 1) + key.is_empty_value);
   }
   static const bool kEmptyValueIsZero = false;
   static IdentifiableTokenKey EmptyValue() { return IdentifiableTokenKey(); }
diff --git a/third_party/blink/renderer/core/html/anchor_element_metrics.cc b/third_party/blink/renderer/core/html/anchor_element_metrics.cc
index dfca3d01..72fb2fa 100644
--- a/third_party/blink/renderer/core/html/anchor_element_metrics.cc
+++ b/third_party/blink/renderer/core/html/anchor_element_metrics.cc
@@ -180,8 +180,8 @@
 // destroyed and a new one is created with the same address. We don't mind this
 // issue as the anchor ID is only used for metric collection.
 uint32_t AnchorElementId(const HTMLAnchorElementBase& element) {
-  uint32_t id = WTF::GetHash(&element);
-  if (WTF::IsHashTraitsEmptyOrDeletedValue<HashTraits<uint32_t>>(id)) {
+  uint32_t id = GetHash(&element);
+  if (IsHashTraitsEmptyOrDeletedValue<HashTraits<uint32_t>>(id)) {
     // Anchor IDs are used in HashMaps, so we can't have sentinel values. If the
     // hash happens to be a sentinel value, we return an arbitrary value
     // instead.
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
index e6ecedba..576bfeb 100644
--- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
+++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
@@ -386,18 +386,9 @@
   if (RenderingContext()->did_print_in_current_task() || IsPrinting()) {
     reason = FlushReason::kCanvasPushFrameWhilePrinting;
   }
-  RenderingContext()->GetResourceProviderForCanvas2D()->FlushCanvas(reason);
 
-  // If the context is lost, we don't know if we should be producing GPU or
-  // software frames, until we get a new context, since the compositor will
-  // be trying to get a new context and may change modes.
-  if (!RenderingContext()->GetResourceProviderForCanvas2D()->IsValid()) {
-    return false;
-  }
-
-  scoped_refptr<CanvasResource> frame = RenderingContext()
-                                            ->GetResourceProviderForCanvas2D()
-                                            ->ProduceCanvasResource(reason);
+  scoped_refptr<CanvasResource> frame =
+      RenderingContext()->PaintRenderingResultsToResource(kBackBuffer, reason);
   if (!frame || !frame->IsValid()) {
     return false;
   }
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_descriptor.h b/third_party/blink/renderer/core/html/custom/custom_element_descriptor.h
index 746f0bc..b6aadda 100644
--- a/third_party/blink/renderer/core/html/custom/custom_element_descriptor.h
+++ b/third_party/blink/renderer/core/html/custom/custom_element_descriptor.h
@@ -55,7 +55,7 @@
   bool IsAutonomous() const { return name_ == local_name_; }
 
  private:
-  friend struct WTF::HashTraits<blink::CustomElementDescriptor>;
+  friend struct HashTraits<CustomElementDescriptor>;
   AtomicString name_;
   AtomicString local_name_;
 };
diff --git a/third_party/blink/renderer/core/html/parser/literal_buffer.h b/third_party/blink/renderer/core/html/parser/literal_buffer.h
index c48bd10..7b89f87f 100644
--- a/third_party/blink/renderer/core/html/parser/literal_buffer.h
+++ b/third_party/blink/renderer/core/html/parser/literal_buffer.h
@@ -36,7 +36,7 @@
 // UCharLiteralBuffer.
 template <typename T, blink::wtf_size_t kInlineSize>
 class LiteralBufferBase {
-  static_assert(std::is_same<LChar, T>::value || std::is_same<UChar, T>::value,
+  static_assert(std::is_same_v<blink::LChar, T> || std::is_same_v<UChar, T>,
                 "T must be a character type");
 
  public:
@@ -182,7 +182,7 @@
 };
 
 template <blink::wtf_size_t kInlineSize>
-class LCharLiteralBuffer : public LiteralBufferBase<LChar, kInlineSize> {
+class LCharLiteralBuffer : public LiteralBufferBase<blink::LChar, kInlineSize> {
  public:
   LCharLiteralBuffer() = default;
   LCharLiteralBuffer(const LCharLiteralBuffer& other) { *this = other; }
@@ -207,7 +207,7 @@
   // Clear without freeing any storage.
   ALWAYS_INLINE void clear() { this->ClearImpl(); }
 
-  ALWAYS_INLINE void AddChar(LChar val) { this->AddCharImpl(val); }
+  ALWAYS_INLINE void AddChar(blink::LChar val) { this->AddCharImpl(val); }
 
   blink::String AsString() const { return blink::String(*this); }
 };
diff --git a/third_party/blink/renderer/core/inspector/inspector_diff.h b/third_party/blink/renderer/core/inspector/inspector_diff.h
index e65257d2..bd5cae0 100644
--- a/third_party/blink/renderer/core/inspector/inspector_diff.h
+++ b/third_party/blink/renderer/core/inspector/inspector_diff.h
@@ -12,7 +12,7 @@
 namespace blink {
 
 using InspectorIndexMap =
-    HashMap<unsigned, unsigned, WTF::IntWithZeroKeyHashTraits<unsigned>>;
+    HashMap<unsigned, unsigned, IntWithZeroKeyHashTraits<unsigned>>;
 
 // A general-purpose comparator between 2 arrays for the inspector
 class CORE_EXPORT InspectorDiff {
diff --git a/third_party/blink/renderer/core/inspector/inspector_preload_agent.cc b/third_party/blink/renderer/core/inspector/inspector_preload_agent.cc
index b41f809..47ca45e 100644
--- a/third_party/blink/renderer/core/inspector/inspector_preload_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_preload_agent.cc
@@ -60,7 +60,7 @@
 }
 
 struct PreloadingAttemptKeyHashTraits
-    : WTF::GenericHashTraits<PreloadingAttemptKey> {
+    : GenericHashTraits<PreloadingAttemptKey> {
   static unsigned GetHash(const PreloadingAttemptKey& key) {
     unsigned hash = blink::GetHash(key.action);
     hash = HashInts(hash, blink::GetHash(key.url));
diff --git a/third_party/blink/renderer/core/inspector/invalidation_set_to_selector_map.h b/third_party/blink/renderer/core/inspector/invalidation_set_to_selector_map.h
index 085fcce..1741141 100644
--- a/third_party/blink/renderer/core/inspector/invalidation_set_to_selector_map.h
+++ b/third_party/blink/renderer/core/inspector/invalidation_set_to_selector_map.h
@@ -41,8 +41,7 @@
     const StyleSheetContents* GetStyleSheetContents() const;
 
    private:
-    friend struct WTF::HashTraits<
-        blink::InvalidationSetToSelectorMap::IndexedSelector>;
+    friend struct HashTraits<InvalidationSetToSelectorMap::IndexedSelector>;
     Member<StyleRule> style_rule_;
     unsigned selector_index_;
   };
diff --git a/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc b/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc
index f632ec7..174b7983 100644
--- a/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc
+++ b/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc
@@ -61,7 +61,7 @@
 }  // namespace
 
 struct LegacyDOMSnapshotAgent::VectorStringHashTraits
-    : public WTF::GenericHashTraits<Vector<String>> {
+    : public GenericHashTraits<Vector<String>> {
   static unsigned GetHash(const Vector<String>& vec) {
     unsigned h = blink::GetHash(vec.size());
     for (const String& s : vec) {
diff --git a/third_party/blink/renderer/core/layout/flex/flex_layout_algorithm.cc b/third_party/blink/renderer/core/layout/flex/flex_layout_algorithm.cc
index 3a5bee99..1df0a81b 100644
--- a/third_party/blink/renderer/core/layout/flex/flex_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/flex/flex_layout_algorithm.cc
@@ -3081,15 +3081,16 @@
     // the available space in a non-forced break scenario. This is because the
     // available space is based on the previous row's end.
     flex_line->item_offset_adjustment -= (gap - available_space);
-  } else {
-    // In column flex containers, we may encounter a case where the available
-    // space is larger than the gap, yet an item still doesn't fit. In such
-    // cases, the entire gap has already been consumed in this fragmentainer, so
-    // no adjustment is needed. Adjustments should only be made when the gap
-    // exceeds the available space which means that part of the gap may appear
-    // in the next fragmentainer.
-    CHECK(is_column_);
   }
+
+  // In column flex containers, we may encounter a case where the available
+  // space is larger than the gap, yet an item still doesn't fit. In such
+  // cases, the entire gap has already been consumed in this fragmentainer, so
+  // no adjustment is needed. Adjustments should only be made when the gap
+  // exceeds the available space which means that part of the gap may appear
+  // in the next fragmentainer.
+  // TODO(crbug.com/434735271): Determine if we can accurately CHECK that this
+  // won't occur in a row-based flex container.
 }
 
 MinMaxSizesResult
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
index f433b50c..8ff8125 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -1318,7 +1318,7 @@
                                 style.Preserves3D() &&
                                 !state.rendering_context_id;
         if (new_rendering_context) {
-          state.rendering_context_id = WTF::GetHash(&object_);
+          state.rendering_context_id = GetHash(&object_);
         }
 
         // TODO(crbug.com/1185254): Make this work correctly for block
diff --git a/third_party/blink/renderer/core/scheduler/scripted_idle_task_controller.h b/third_party/blink/renderer/core/scheduler/scripted_idle_task_controller.h
index 64700e4..42f75e0 100644
--- a/third_party/blink/renderer/core/scheduler/scripted_idle_task_controller.h
+++ b/third_party/blink/renderer/core/scheduler/scripted_idle_task_controller.h
@@ -154,7 +154,7 @@
 
   static bool IsValidCallbackId(int id) {
     using Traits = HashTraits<CallbackId>;
-    return !WTF::IsHashTraitsEmptyOrDeletedValue<Traits, CallbackId>(id);
+    return !IsHashTraitsEmptyOrDeletedValue<Traits, CallbackId>(id);
   }
 
   // Not owned.
diff --git a/third_party/blink/renderer/core/script/module_record_resolver_impl.cc b/third_party/blink/renderer/core/script/module_record_resolver_impl.cc
index 5009b499..e9b8a17 100644
--- a/third_party/blink/renderer/core/script/module_record_resolver_impl.cc
+++ b/third_party/blink/renderer/core/script/module_record_resolver_impl.cc
@@ -22,7 +22,7 @@
 
   DVLOG(1) << "ModuleRecordResolverImpl::RegisterModuleScript(url="
            << module_script->BaseUrl().GetString()
-           << ", hash=" << WTF::GetHash(record) << ")";
+           << ", hash=" << GetHash(record) << ")";
 
   auto result = record_to_module_script_map_.Set(record, module_script);
 
@@ -40,7 +40,7 @@
   BoxedV8Module* record = MakeGarbageCollected<BoxedV8Module>(isolate, module);
   DVLOG(1) << "ModuleRecordResolverImpl::UnregisterModuleScript(url="
            << module_script->BaseUrl().GetString()
-           << ", hash=" << WTF::GetHash(record) << ")";
+           << ", hash=" << GetHash(record) << ")";
 
   record_to_module_script_map_.erase(record);
 }
@@ -63,8 +63,7 @@
   v8::Isolate* isolate = modulator_->GetScriptState()->GetIsolate();
   DVLOG(1) << "ModuleRecordResolverImpl::ResolveImpl(specifier=\""
            << module_request.specifier << ", referrer.hash="
-           << WTF::GetHash(
-                  MakeGarbageCollected<BoxedV8Module>(isolate, referrer))
+           << GetHash(MakeGarbageCollected<BoxedV8Module>(isolate, referrer))
            << ")";
 
   // <spec step="3">If referencingScriptOrModule is not null, then:</spec>
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h
index dd0afaa0..17d9303a 100644
--- a/third_party/blink/renderer/core/style/computed_style.h
+++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -906,11 +906,8 @@
 
   // letter-spacing
   float LetterSpacing() const { return GetFontDescription().LetterSpacing(); }
-  // TODO(crbug.com/327740939): Rename this like word spacing because
-  // `Specified` is a term that normally refers to specified styles which could
-  // be a relative length.
-  const Length& SpecifiedLetterSpacing() const {
-    return GetFontDescription().SpecifiedLetterSpacing();
+  const Length& ComputedLetterSpacing() const {
+    return GetFontDescription().ComputedLetterSpacing();
   }
 
   // word-spacing
diff --git a/third_party/blink/renderer/core/svg/svg_element.h b/third_party/blink/renderer/core/svg/svg_element.h
index 1f50bbd..f66acb9a 100644
--- a/third_party/blink/renderer/core/svg/svg_element.h
+++ b/third_party/blink/renderer/core/svg/svg_element.h
@@ -319,7 +319,7 @@
                                             key.NamespaceURI().Impl()};
       return HashComponents(components);
     }
-    return WTF::GetHash(key);
+    return blink::GetHash(key);
   }
   static bool Equal(const QualifiedName& a, const QualifiedName& b) {
     return a.Matches(b);
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
index 69b411fc..0bef43fe 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -1075,7 +1075,7 @@
     return nullptr;
   }
   AXID ax_id = it_id->value;
-  DCHECK(!WTF::IsHashTraitsDeletedValue<HashTraits<AXID>>(ax_id));
+  DCHECK(!IsHashTraitsDeletedValue<HashTraits<AXID>>(ax_id));
 
   auto it_result = objects_.find(ax_id);
   AXObject* result = it_result != objects_.end() ? it_result->value : nullptr;
@@ -1185,7 +1185,7 @@
       it_ax != inline_text_box_object_mapping_.end() ? it_ax->value : 0;
   if (!ax_id)
     return nullptr;
-  DCHECK(!WTF::IsHashTraitsEmptyOrDeletedValue<HashTraits<AXID>>(ax_id));
+  DCHECK(!IsHashTraitsEmptyOrDeletedValue<HashTraits<AXID>>(ax_id));
 
   auto it_result = objects_.find(ax_id);
   AXObject* result = it_result != objects_.end() ? it_result->value : nullptr;
@@ -2083,7 +2083,7 @@
     }
   } while (has_axid_generator_looped_ && objects_.Contains(obj_id));
 
-  DCHECK(!WTF::IsHashTraitsEmptyOrDeletedValue<HashTraits<AXID>>(obj_id));
+  DCHECK(!IsHashTraitsEmptyOrDeletedValue<HashTraits<AXID>>(obj_id));
 
   last_used_id = obj_id;
 
@@ -2114,7 +2114,7 @@
 }
 
 void AXObjectCacheImpl::RemoveReferencesToAXID(AXID obj_id) {
-  DCHECK(!WTF::IsHashTraitsDeletedValue<HashTraits<AXID>>(obj_id));
+  DCHECK(!IsHashTraitsDeletedValue<HashTraits<AXID>>(obj_id));
 
   // Clear AXIDs from maps. Note: do not need to erase id from
   // changed_bounds_ids_, a set which is cleared each time
diff --git a/third_party/blink/renderer/modules/cache_storage/cache.cc b/third_party/blink/renderer/modules/cache_storage/cache.cc
index 811d65d..62f7690 100644
--- a/third_party/blink/renderer/modules/cache_storage/cache.cc
+++ b/third_party/blink/renderer/modules/cache_storage/cache.cc
@@ -13,6 +13,7 @@
 #include "services/network/public/mojom/fetch_api.mojom-blink.h"
 #include "third_party/blink/public/common/cache_storage/cache_storage_utils.h"
 #include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/common/scheme_registry.h"
 #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
@@ -81,7 +82,8 @@
 void ValidateRequestForPut(const Request* request,
                            ExceptionState& exception_state) {
   const KURL& url = request->url();
-  if (!url.ProtocolIsInHTTPFamily()) {
+  if (!url.ProtocolIsInHTTPFamily() &&
+      !CommonSchemeRegistry::IsIsolatedAppScheme(url.Protocol().Ascii())) {
     exception_state.ThrowTypeError(
         StrCat({"Request scheme '", url.Protocol(), "' is unsupported"}));
     return;
diff --git a/third_party/blink/renderer/modules/cache_storage/cache_test.cc b/third_party/blink/renderer/modules/cache_storage/cache_test.cc
index 54f6d2ef..b9b02c0ac 100644
--- a/third_party/blink/renderer/modules/cache_storage/cache_test.cc
+++ b/third_party/blink/renderer/modules/cache_storage/cache_test.cc
@@ -17,6 +17,7 @@
 #include "mojo/public/cpp/bindings/associated_remote.h"
 #include "services/network/public/mojom/fetch_api.mojom-blink.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/scheme_registry.h"
 #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h"
 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
 #include "third_party/blink/public/platform/web_url_response.h"
@@ -794,6 +795,55 @@
             test_cache()->GetAndClearLastErrorWebCacheMethodCalled());
 }
 
+TEST_F(CacheStorageTest, AddIsolatedApp) {
+  CommonSchemeRegistry::RegisterURLSchemeAsIsolatedApp("isolated-app");
+  ScriptState::Scope scope(GetScriptState());
+  NonThrowableExceptionState exception_state;
+  auto* fetcher = MakeGarbageCollected<ScopedFetcherForTests>();
+  const String url =
+      "isolated-app://"
+      "aerugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaic/";
+  const String content_type = "text/plain";
+  const String content = "hello cache";
+
+  Cache* cache =
+      CreateCache(fetcher, std::make_unique<NotImplementedErrorCache>());
+
+  fetcher->SetExpectedFetchUrl(&url);
+
+  Request* request = NewRequestFromUrl(url);
+  Response* response =
+      Response::Create(GetScriptState(),
+                       BodyStreamBuffer::Create(
+                           GetScriptState(),
+                           MakeGarbageCollected<FormDataBytesConsumer>(content),
+                           nullptr, /*cached_metadata_handler=*/nullptr),
+                       content_type, ResponseInit::Create(), exception_state);
+  fetcher->SetResponse(response);
+
+  Vector<mojom::blink::BatchOperationPtr> expected_put_operations(
+      static_cast<size_t>(1));
+  {
+    mojom::blink::BatchOperationPtr put_operation =
+        mojom::blink::BatchOperation::New();
+
+    put_operation->operation_type = mojom::blink::OperationType::kPut;
+    put_operation->request = request->CreateFetchAPIRequest();
+    put_operation->response =
+        response->PopulateFetchAPIResponse(request->url());
+    expected_put_operations[0] = std::move(put_operation);
+  }
+  test_cache()->SetExpectedBatchOperations(&expected_put_operations);
+
+  auto add_result = cache->add(GetScriptState(), RequestToRequestInfo(request),
+                               exception_state);
+
+  EXPECT_EQ(kNotImplementedString, GetRejectString(add_result));
+  EXPECT_EQ(1u, fetcher->FetchCount());
+  EXPECT_EQ("dispatchBatch",
+            test_cache()->GetAndClearLastErrorWebCacheMethodCalled());
+}
+
 // Verify we don't create and trigger the AbortController when a single request
 // to add() addAll() fails.
 TEST_F(CacheStorageTest, AddAllAbortOne) {
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
index 477212a..5ea4225 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
@@ -653,7 +653,9 @@
 CanvasRenderingContext2D::PaintRenderingResultsToResource(
     SourceDrawingBuffer source_buffer,
     FlushReason reason) {
-  CHECK(IsCanvas2DResourceProviderValid());
+  if (!IsCanvas2DResourceProviderValid()) {
+    return nullptr;
+  }
   return resource_provider_->ProduceCanvasResource(reason);
 }
 
diff --git a/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h b/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h
index 25a7b28..80e6efc 100644
--- a/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h
+++ b/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h
@@ -121,7 +121,7 @@
 
   // Together the following keep track of the nextTouchId per Gamepad
   using TouchIdMap =
-      WTF::HashMap<uint32_t, uint32_t, WTF::IntWithZeroKeyHashTraits<uint32_t>>;
+      HashMap<uint32_t, uint32_t, IntWithZeroKeyHashTraits<uint32_t>>;
 
   std::array<TouchIdMap, device::Gamepads::kItemsLengthCap> touch_id_map_;
   std::array<uint32_t, device::Gamepads::kItemsLengthCap> next_touch_id_;
diff --git a/third_party/blink/renderer/modules/media/audio/audio_renderer_sink_cache_test.cc b/third_party/blink/renderer/modules/media/audio/audio_renderer_sink_cache_test.cc
index ec5bea5..92f8f0f 100644
--- a/third_party/blink/renderer/modules/media/audio/audio_renderer_sink_cache_test.cc
+++ b/third_party/blink/renderer/modules/media/audio/audio_renderer_sink_cache_test.cc
@@ -17,7 +17,10 @@
 #include "media/base/mock_audio_renderer_sink.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/testing/task_environment.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_media.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
 
 namespace blink {
 
@@ -78,15 +81,14 @@
   // Posts the task to the specified thread and runs current message loop until
   // the task is completed.
   void PostAndWaitUntilDone(const base::Thread& thread,
-                            base::OnceClosure task) {
+                            CrossThreadOnceClosure task) {
     base::WaitableEvent e{base::WaitableEvent::ResetPolicy::MANUAL,
                           base::WaitableEvent::InitialState::NOT_SIGNALED};
 
-    thread.task_runner()->PostTask(FROM_HERE, std::move(task));
-    thread.task_runner()->PostTask(
-        FROM_HERE,
-        base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&e)));
-
+    PostCrossThreadTask(*thread.task_runner(), FROM_HERE, std::move(task));
+    PostCrossThreadTask(*thread.task_runner(), FROM_HERE,
+                        CrossThreadBindOnce(&base::WaitableEvent::Signal,
+                                            CrossThreadUnretained(&e)));
     e.Wait();
   }
 
@@ -186,19 +188,19 @@
 
   // Request device information on the first thread.
   PostAndWaitUntilDone(
-      thread1,
-      base::BindOnce(base::IgnoreResult(&AudioRendererSinkCache::GetSinkInfo),
-                     base::Unretained(cache_.get()), kFrameToken,
-                     kDefaultDeviceId));
+      thread1, CrossThreadBindOnce(
+                   base::IgnoreResult(&AudioRendererSinkCache::GetSinkInfo),
+                   CrossThreadUnretained(cache_.get()), kFrameToken,
+                   CrossThreadUnretained(kDefaultDeviceId)));
 
   EXPECT_EQ(1u, sink_count());
 
   // Request the device information again on the second thread.
   PostAndWaitUntilDone(
-      thread2,
-      base::BindOnce(base::IgnoreResult(&AudioRendererSinkCache::GetSinkInfo),
-                     base::Unretained(cache_.get()), kFrameToken,
-                     kDefaultDeviceId));
+      thread2, CrossThreadBindOnce(
+                   base::IgnoreResult(&AudioRendererSinkCache::GetSinkInfo),
+                   CrossThreadUnretained(cache_.get()), kFrameToken,
+                   CrossThreadUnretained(kDefaultDeviceId)));
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc
index c1ebba8..8ca145d 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc
@@ -1677,22 +1677,25 @@
 
   webnn::OperandDataType data_type = descriptor.data_type();
   if (buffer->IsArrayBufferViewAllowShared()) {
-    if (GetArrayBufferViewType(data_type) !=
-        buffer->GetAsArrayBufferViewAllowShared().Get()->GetType()) {
+    DOMArrayBufferView::ViewType buffer_view_type =
+        buffer->GetAsArrayBufferViewAllowShared().Get()->GetType();
+    if (buffer_view_type != DOMArrayBufferView::ViewType::kTypeUint8 &&
+        buffer_view_type != GetArrayBufferViewType(data_type)) {
       if (data_type == webnn::OperandDataType::kFloat16 &&
-          buffer->GetAsArrayBufferViewAllowShared().Get()->GetType() ==
-              DOMArrayBufferView::ViewType::kTypeUint16) {
+          buffer_view_type == DOMArrayBufferView::ViewType::kTypeUint16) {
         // Passing a Uint16Array when the data type is float16 was supported
         // prior to Float16Array shipping. Maintain this special case to give
         // developers/frameworks time to migrate their code.
         // TODO(crbug.com/399459942): Remove this circa 2025Q3.
-        LogConsoleWarning(script_state,
-                          "Passing a Uint16Array instance for a float16 "
-                          "operand is deprecated. Use Float16Array instead.");
+        LogConsoleWarning(
+            script_state,
+            "Passing a Uint16Array instance for a float16 "
+            "operand is deprecated. Use Float16Array or Uint8Array instead.");
 
       } else {
         exception_state.ThrowTypeError(
-            "The buffer view type doesn't match the operand data type.");
+            "The buffer view must either match the operand data type or be a "
+            "Uint8Array.");
         return nullptr;
       }
     }
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame_monitor.h b/third_party/blink/renderer/modules/webcodecs/video_frame_monitor.h
index 8e8398e..50b891c 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_frame_monitor.h
+++ b/third_party/blink/renderer/modules/webcodecs/video_frame_monitor.h
@@ -96,8 +96,7 @@
   // key: unique ID of a frame.
   // value: reference count for the frame (among objects explicitly tracking
   //        the frame with VideoFrameMonitor).
-  struct VideoFrameIDHashTraits
-      : WTF::GenericHashTraits<media::VideoFrame::ID> {
+  struct VideoFrameIDHashTraits : GenericHashTraits<media::VideoFrame::ID> {
     static unsigned GetHash(media::VideoFrame::ID key) {
       static_assert(std::is_same_v<decltype(key.GetUnsafeValue()), uint64_t>);
       return HashInt(key.GetUnsafeValue());
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
index c2baf21..5d0f5f8 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -1666,8 +1666,12 @@
   // Note: we push a frame only if (a) there is fresh content to produce and
   // (b) we successfully produced that content.
   bool resource_provider_was_updated = false;
+
+  // CanvasResourceProviderBitmap returns null from ProduceCanvasResource(), so
+  // there is no point in using one here.
   auto* resource_provider = PaintRenderingResultsToResourceProvider(
-      kBackBuffer, &resource_provider_was_updated);
+      kBackBuffer, /*use_bitmap_provider=*/false,
+      &resource_provider_was_updated);
   if (resource_provider && resource_provider_was_updated) {
     const int width = GetDrawingBuffer()->Size().width();
     const int height = GetDrawingBuffer()->Size().height();
@@ -1934,8 +1938,8 @@
     return resource ? resource->Bitmap() : nullptr;
   }
 
-  CanvasResourceProvider* provider =
-      PaintRenderingResultsToResourceProvider(source_buffer);
+  CanvasResourceProvider* provider = PaintRenderingResultsToResourceProvider(
+      source_buffer, /*use_bitmap_provider=*/true);
 
   return provider ? provider->Snapshot(reason) : nullptr;
 }
@@ -1949,8 +1953,10 @@
                                           /*export_only_if_update=*/false);
   }
 
-  auto* resource_provider =
-      PaintRenderingResultsToResourceProvider(source_buffer);
+  // CanvasResourceProviderBitmap returns null from ProduceCanvasResource(), so
+  // there is no point in using one here.
+  auto* resource_provider = PaintRenderingResultsToResourceProvider(
+      source_buffer, /*use_bitmap_provider=*/false);
   if (resource_provider) {
     return resource_provider->ProduceCanvasResource(reason);
   }
@@ -1958,7 +1964,8 @@
 }
 
 std::unique_ptr<CanvasResourceProvider>
-WebGLRenderingContextBase::CreateCanvasResourceProvider() {
+WebGLRenderingContextBase::CreateCanvasResourceProvider(
+    bool use_bitmap_provider) {
   base::WeakPtr<CanvasResourceDispatcher> dispatcher =
       Host()->GetOrCreateResourceDispatcher()
           ? Host()->GetOrCreateResourceDispatcher()->GetWeakPtr()
@@ -2012,7 +2019,7 @@
             Host()->Size(), format, alpha_type, color_space, kShouldInitialize,
             SharedGpuContext::SharedImageInterfaceProvider(), Host());
   }
-  if (!provider) {
+  if (!provider && use_bitmap_provider) {
     provider = CanvasResourceProvider::CreateBitmapProvider(
         Host()->Size(), format, alpha_type, color_space, kShouldInitialize,
         Host());
@@ -2022,11 +2029,12 @@
 }
 
 CanvasResourceProvider*
-WebGLRenderingContextBase::GetOrCreateCanvasResourceProvider() {
+WebGLRenderingContextBase::GetOrCreateCanvasResourceProvider(
+    bool use_bitmap_provider) {
   auto* provider = resource_provider_.get();
   if (!provider && !did_fail_to_create_resource_provider_) {
     if (Host()->IsValidImageSize()) {
-      resource_provider_ = CreateCanvasResourceProvider();
+      resource_provider_ = CreateCanvasResourceProvider(use_bitmap_provider);
       Host()->UpdateMemoryUsage();
       provider = resource_provider_.get();
     }
@@ -2039,12 +2047,23 @@
                                     provider->GetType());
     }
   }
+  if (provider &&
+      provider->GetType() ==
+          CanvasResourceProvider::ResourceProviderType::kBitmap &&
+      !use_bitmap_provider) {
+    // In addition to not *creating* a CRPBitmap if `use_bitmap_provider` is
+    // false, ensure that we don't return a cached CRPBitmap that was created
+    // previously in a call from a callsite that still uses CRPBitmap.
+    return nullptr;
+  }
+
   return provider;
 }
 
 CanvasResourceProvider*
 WebGLRenderingContextBase::PaintRenderingResultsToResourceProvider(
     SourceDrawingBuffer source_buffer,
+    bool use_bitmap_provider,
     bool* resource_provider_was_updated /*=nullptr*/) {
   CHECK(!CanUseDrawingBufferSIWithoutCopyForLowLatency());
 
@@ -2077,7 +2096,7 @@
   must_paint_to_canvas_ = false;
 
   CanvasResourceProvider* resource_provider =
-      GetOrCreateCanvasResourceProvider();
+      GetOrCreateCanvasResourceProvider(use_bitmap_provider);
   if (!resource_provider)
     return nullptr;
 
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
index 32f2b28e..6cb4097 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
@@ -712,7 +712,8 @@
   bool CanUseDrawingBufferSIWithoutCopyForLowLatency();
   void PageVisibilityChanged() override;
   void SizeChanged() override;
-  std::unique_ptr<CanvasResourceProvider> CreateCanvasResourceProvider();
+  std::unique_ptr<CanvasResourceProvider> CreateCanvasResourceProvider(
+      bool use_bitmap_provider);
   scoped_refptr<StaticBitmapImage> PaintRenderingResultsToSnapshot(
       SourceDrawingBuffer source_buffer,
       FlushReason reason) override;
@@ -1959,9 +1960,11 @@
       SourceDrawingBuffer source_buffer,
       bool export_only_if_update);
 
-  CanvasResourceProvider* GetOrCreateCanvasResourceProvider();
+  CanvasResourceProvider* GetOrCreateCanvasResourceProvider(
+      bool use_bitmap_provider);
   CanvasResourceProvider* PaintRenderingResultsToResourceProvider(
       SourceDrawingBuffer source_buffer,
+      bool use_bitmap_provider,
       bool* resource_provider_was_updated = nullptr);
   void TexImageHelperMediaVideoFrame(
       TexImageParams,
diff --git a/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h b/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h
index 6f1171f..66618ce 100644
--- a/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h
+++ b/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h
@@ -50,7 +50,7 @@
  private:
   bool IsValidCallbackId(int id) {
     using Traits = HashTraits<CallbackId>;
-    return !WTF::IsHashTraitsEmptyOrDeletedValue<Traits, CallbackId>(id);
+    return !IsHashTraitsEmptyOrDeletedValue<Traits, CallbackId>(id);
   }
 
   using CallbackFrameRequestMap =
diff --git a/third_party/blink/renderer/platform/fonts/fallback_list_composite_key.h b/third_party/blink/renderer/platform/fonts/fallback_list_composite_key.h
index 6807813..fc33735 100644
--- a/third_party/blink/renderer/platform/fonts/fallback_list_composite_key.h
+++ b/third_party/blink/renderer/platform/fonts/fallback_list_composite_key.h
@@ -91,7 +91,7 @@
 };
 
 struct FallbackListCompositeKeyTraits
-    : WTF::SimpleClassHashTraits<FallbackListCompositeKey> {
+    : SimpleClassHashTraits<FallbackListCompositeKey> {
   static unsigned GetHash(const FallbackListCompositeKey& key) {
     return key.GetHash();
   }
diff --git a/third_party/blink/renderer/platform/fonts/font_description.h b/third_party/blink/renderer/platform/fonts/font_description.h
index d97518d..6eb31027 100644
--- a/third_party/blink/renderer/platform/fonts/font_description.h
+++ b/third_party/blink/renderer/platform/fonts/font_description.h
@@ -319,10 +319,7 @@
   const Length& ComputedWordSpacing() const { return word_spacing_; }
 
   float LetterSpacing() const;
-  // TODO(crbug.com/327740939): Rename this like word spacing because
-  // `Specified` is a term that normally refers to specified styles which could
-  // be a relative length.
-  const Length& SpecifiedLetterSpacing() const { return letter_spacing_; }
+  const Length& ComputedLetterSpacing() const { return letter_spacing_; }
 
   FontOrientation Orientation() const {
     return static_cast<FontOrientation>(fields_.orientation_);
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h b/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h
index 906ee743..2c60087 100644
--- a/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h
+++ b/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h
@@ -188,7 +188,7 @@
     return nullptr;
   }
 
-  struct SmallStringKeyHashTraits : WTF::SimpleClassHashTraits<SmallStringKey> {
+  struct SmallStringKeyHashTraits : SimpleClassHashTraits<SmallStringKey> {
     STATIC_ONLY(SmallStringKeyHashTraits);
     static unsigned GetHash(const SmallStringKey& key) { return key.GetHash(); }
     static const bool kEmptyValueIsZero = false;
diff --git a/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h b/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h
index 1816474..ce436c28 100644
--- a/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h
+++ b/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h
@@ -200,8 +200,8 @@
       if constexpr (Traits::kCanTraceConcurrently) {
         internal::ConcurrentBucket<Value> concurrent_bucket(
             array[i], Extractor::ExtractKeyToMemory);
-        if (!WTF::IsHashTraitsEmptyOrDeletedValue<
-                typename Table::KeyTraitsType>(*concurrent_bucket.key())) {
+        if (!IsHashTraitsEmptyOrDeletedValue<typename Table::KeyTraitsType>(
+                *concurrent_bucket.key())) {
           blink::TraceCollectionIfEnabled<
               weak_handling,
               typename internal::ConcurrentBucket<Value>::BucketType,
@@ -214,8 +214,7 @@
         // copying possibly ASAN-poisened fields. Such fields can exist in keys
         // in form of an `std::string` that uses container annotations to detect
         // OOB. A side effect is that we also avoid copying the key.
-        if (!WTF::IsHashTraitsEmptyOrDeletedValue<
-                typename Table::KeyTraitsType>(
+        if (!IsHashTraitsEmptyOrDeletedValue<typename Table::KeyTraitsType>(
                 Extractor::ExtractKey(array[i]))) {
           blink::TraceCollectionIfEnabled<weak_handling, Value, Traits>::Trace(
               visitor, &array[i]);
diff --git a/third_party/blink/renderer/platform/heap/heap_test_objects.h b/third_party/blink/renderer/platform/heap/heap_test_objects.h
index 4ff02b9..02e5062 100644
--- a/third_party/blink/renderer/platform/heap/heap_test_objects.h
+++ b/third_party/blink/renderer/platform/heap/heap_test_objects.h
@@ -128,7 +128,7 @@
     return other.Value() == Value();
   }
 
-  unsigned GetHash() { return WTF::GetHash(x_); }
+  unsigned GetHash() { return blink::GetHash(x_); }
 
  private:
   int x_;
diff --git a/third_party/blink/renderer/platform/heap/test/heap_compact_test.cc b/third_party/blink/renderer/platform/heap/test/heap_compact_test.cc
index 40138a20..d681059 100644
--- a/third_party/blink/renderer/platform/heap/test/heap_compact_test.cc
+++ b/third_party/blink/renderer/platform/heap/test/heap_compact_test.cc
@@ -37,7 +37,7 @@
     return other.Value() == Value();
   }
 
-  unsigned GetHash() { return WTF::GetHash(x_); }
+  unsigned GetHash() { return blink::GetHash(x_); }
 
   explicit IntWrapper(int x) : x_(x) {}
 
diff --git a/third_party/blink/renderer/platform/network/blink_schemeful_site.h b/third_party/blink/renderer/platform/network/blink_schemeful_site.h
index 0f348f11..8c712e2 100644
--- a/third_party/blink/renderer/platform/network/blink_schemeful_site.h
+++ b/third_party/blink/renderer/platform/network/blink_schemeful_site.h
@@ -76,7 +76,7 @@
   bool IsOpaque() const { return site_as_origin_->IsOpaque(); }
 
  private:
-  friend struct WTF::HashTraits<BlinkSchemefulSite>;
+  friend struct HashTraits<BlinkSchemefulSite>;
 
   // IPC serialization code needs to access internal origin.
   friend struct mojo::StructTraits<network::mojom::SchemefulSiteDataView,
diff --git a/third_party/blink/renderer/platform/network/ip_address_test.cc b/third_party/blink/renderer/platform/network/ip_address_test.cc
index 9a31b46..e4c05816 100644
--- a/third_party/blink/renderer/platform/network/ip_address_test.cc
+++ b/third_party/blink/renderer/platform/network/ip_address_test.cc
@@ -27,23 +27,18 @@
   EXPECT_NE(deleted_value, kIPAddr1);
   EXPECT_NE(deleted_value, kIPAddr2);
   EXPECT_TRUE(
-      WTF::IsHashTraitsDeletedValue<HashTraits<net::IPAddress>>(deleted_value));
+      IsHashTraitsDeletedValue<HashTraits<net::IPAddress>>(deleted_value));
 
   EXPECT_FALSE(
-      WTF::IsHashTraitsDeletedValue<HashTraits<net::IPAddress>>(kEmptyIPAddr));
-  EXPECT_FALSE(
-      WTF::IsHashTraitsDeletedValue<HashTraits<net::IPAddress>>(kIPAddr1));
-  EXPECT_FALSE(
-      WTF::IsHashTraitsDeletedValue<HashTraits<net::IPAddress>>(kIPAddr2));
+      IsHashTraitsDeletedValue<HashTraits<net::IPAddress>>(kEmptyIPAddr));
+  EXPECT_FALSE(IsHashTraitsDeletedValue<HashTraits<net::IPAddress>>(kIPAddr1));
+  EXPECT_FALSE(IsHashTraitsDeletedValue<HashTraits<net::IPAddress>>(kIPAddr2));
 
-  EXPECT_TRUE(
-      WTF::IsHashTraitsEmptyValue<HashTraits<net::IPAddress>>(kEmptyIPAddr));
+  EXPECT_TRUE(IsHashTraitsEmptyValue<HashTraits<net::IPAddress>>(kEmptyIPAddr));
   EXPECT_FALSE(
-      WTF::IsHashTraitsEmptyValue<HashTraits<net::IPAddress>>(deleted_value));
-  EXPECT_FALSE(
-      WTF::IsHashTraitsEmptyValue<HashTraits<net::IPAddress>>(kIPAddr1));
-  EXPECT_FALSE(
-      WTF::IsHashTraitsEmptyValue<HashTraits<net::IPAddress>>(kIPAddr2));
+      IsHashTraitsEmptyValue<HashTraits<net::IPAddress>>(deleted_value));
+  EXPECT_FALSE(IsHashTraitsEmptyValue<HashTraits<net::IPAddress>>(kIPAddr1));
+  EXPECT_FALSE(IsHashTraitsEmptyValue<HashTraits<net::IPAddress>>(kIPAddr2));
 
   // Should be a 1 out of 4 billion chance these collide.
   EXPECT_NE(HashTraits<net::IPAddress>::GetHash(kIPAddr1),
diff --git a/third_party/blink/renderer/platform/network/network_state_notifier.cc b/third_party/blink/renderer/platform/network/network_state_notifier.cc
index db84c9e..3e3be93d 100644
--- a/third_party/blink/renderer/platform/network/network_state_notifier.cc
+++ b/third_party/blink/renderer/platform/network/network_state_notifier.cc
@@ -375,7 +375,7 @@
   if (!host)
     return 1.0;
 
-  unsigned hash = WTF::GetHash(host) + RandomizationSalt();
+  unsigned hash = GetHash(host) + RandomizationSalt();
   double random_multiplier = 0.9 + static_cast<double>((hash % 21)) * 0.01;
   DCHECK_LE(0.90, random_multiplier);
   DCHECK_GE(1.10, random_multiplier);
diff --git a/third_party/blink/renderer/platform/privacy_budget/identifiability_digest_helpers.cc b/third_party/blink/renderer/platform/privacy_budget/identifiability_digest_helpers.cc
index 0613a2d..e16b75f7 100644
--- a/third_party/blink/renderer/platform/privacy_budget/identifiability_digest_helpers.cc
+++ b/third_party/blink/renderer/platform/privacy_budget/identifiability_digest_helpers.cc
@@ -21,7 +21,7 @@
 
   // Return the precomputed hash for the string. This makes this method O(1)
   // instead of O(n), at the cost of only using the lower 32 bits of the hash.
-  return IdentifiableToken(WTF::GetHash(in));
+  return IdentifiableToken(GetHash(in));
 }
 
 IdentifiableToken IdentifiabilitySensitiveStringToken(const String& in) {
@@ -30,7 +30,7 @@
 
   // Take the precomputed 32-bit hash, and xor the top and bottom halves to
   // produce a 16-bit hash.
-  const uint32_t original_hash = WTF::GetHash(in);
+  const uint32_t original_hash = GetHash(in);
   return IdentifiableToken(((original_hash & 0xFFFF0000) >> 16) ^
                            (original_hash & 0xFFFF));
 }
diff --git a/third_party/blink/renderer/platform/storage/blink_storage_key_hash.h b/third_party/blink/renderer/platform/storage/blink_storage_key_hash.h
index 30fcdb59..1205b7f4 100644
--- a/third_party/blink/renderer/platform/storage/blink_storage_key_hash.h
+++ b/third_party/blink/renderer/platform/storage/blink_storage_key_hash.h
@@ -17,14 +17,14 @@
     std::optional<base::UnguessableToken> nonce = storage_key->GetNonce();
     size_t nonce_hash = nonce ? base::UnguessableTokenHash()(*nonce) : 0;
     unsigned hash_codes[] = {
-      WTF::GetHash(storage_key->GetSecurityOrigin()),
-      WTF::GetHash(storage_key->GetTopLevelSite()),
-      static_cast<unsigned>(storage_key->GetAncestorChainBit()),
+        blink::GetHash(storage_key->GetSecurityOrigin()),
+        blink::GetHash(storage_key->GetTopLevelSite()),
+        static_cast<unsigned>(storage_key->GetAncestorChainBit()),
 #if ARCH_CPU_32_BITS
-      nonce_hash,
+        nonce_hash,
 #elif ARCH_CPU_64_BITS
-      static_cast<unsigned>(nonce_hash),
-      static_cast<unsigned>(nonce_hash >> 32),
+        static_cast<unsigned>(nonce_hash),
+        static_cast<unsigned>(nonce_hash >> 32),
 #else
 #error "Unknown bits"
 #endif
diff --git a/third_party/blink/renderer/platform/text_codec_fuzzer.cc b/third_party/blink/renderer/platform/text_codec_fuzzer.cc
index ae04148..5ae003f 100644
--- a/third_party/blink/renderer/platform/text_codec_fuzzer.cc
+++ b/third_party/blink/renderer/platform/text_codec_fuzzer.cc
@@ -67,7 +67,7 @@
       codec->Decode(byte_span, flush_behavior, stop_on_error, saw_error);
 
   // Treat as blink 8-bit string (latin1).
-  if (size % sizeof(LChar) == 0) {
+  if (size % sizeof(blink::LChar) == 0) {
     std::unique_ptr<blink::TextCodec> lchar_codec = NewTextCodec(encoding);
     lchar_codec->Encode(byte_span, unencodable_handling);
   }
diff --git a/third_party/blink/renderer/platform/weborigin/kurl.h b/third_party/blink/renderer/platform/weborigin/kurl.h
index 7f847f1..f05f9f1 100644
--- a/third_party/blink/renderer/platform/weborigin/kurl.h
+++ b/third_party/blink/renderer/platform/weborigin/kurl.h
@@ -251,7 +251,7 @@
   void WriteIntoTrace(perfetto::TracedValue context) const;
 
  private:
-  friend struct WTF::HashTraits<blink::KURL>;
+  friend struct HashTraits<KURL>;
 
   void Init(const KURL& base,
             const String& relative,
diff --git a/third_party/blink/renderer/platform/weborigin/security_origin.h b/third_party/blink/renderer/platform/weborigin/security_origin.h
index 00c403fe..926537ab 100644
--- a/third_party/blink/renderer/platform/weborigin/security_origin.h
+++ b/third_party/blink/renderer/platform/weborigin/security_origin.h
@@ -410,7 +410,7 @@
  private:
   // Various serialisation and test routines that need direct nonce access.
   friend struct mojo::UrlOriginAdapter;
-  friend struct WTF::HashTraits<scoped_refptr<const SecurityOrigin>>;
+  friend struct HashTraits<scoped_refptr<const SecurityOrigin>>;
   friend class SecurityOriginTest;
 
   // For calling GetNonceForSerialization().
diff --git a/third_party/blink/renderer/platform/weborigin/security_origin_test.cc b/third_party/blink/renderer/platform/weborigin/security_origin_test.cc
index 22ca6ce8..87b71a5 100644
--- a/third_party/blink/renderer/platform/weborigin/security_origin_test.cc
+++ b/third_party/blink/renderer/platform/weborigin/security_origin_test.cc
@@ -724,7 +724,7 @@
   scoped_refptr<const SecurityOrigin> copied = origin->IsolatedCopy();
   EXPECT_TRUE(origin->CanAccess(copied.get()));
   EXPECT_TRUE(origin->IsSameOriginWith(copied.get()));
-  EXPECT_EQ(WTF::GetHash(origin), WTF::GetHash(copied));
+  EXPECT_EQ(GetHash(origin), GetHash(copied));
   EXPECT_TRUE(
       HashTraits<scoped_refptr<const SecurityOrigin>>::Equal(origin, copied));
 }
diff --git a/third_party/blink/renderer/platform/wtf/BUILD.gn b/third_party/blink/renderer/platform/wtf/BUILD.gn
index 5a05be5..1b24575 100644
--- a/third_party/blink/renderer/platform/wtf/BUILD.gn
+++ b/third_party/blink/renderer/platform/wtf/BUILD.gn
@@ -53,6 +53,7 @@
     "bit_field.h",
     "bloom_filter.h",
     "casting.h",
+    "construct_traits.h",
     "container_annotations.h",
     "cross_thread_copier.cc",
     "cross_thread_copier.h",
diff --git a/third_party/blink/renderer/platform/wtf/construct_traits.h b/third_party/blink/renderer/platform/wtf/construct_traits.h
index bec66b1..2d84c82 100644
--- a/third_party/blink/renderer/platform/wtf/construct_traits.h
+++ b/third_party/blink/renderer/platform/wtf/construct_traits.h
@@ -51,9 +51,4 @@
 
 }  // namespace blink
 
-// TODO(crbug.com/422768753): Remove this `using` directive.
-namespace WTF {
-using blink::ConstructTraits;
-}  // namespace WTF
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_CONSTRUCT_TRAITS_H_
diff --git a/third_party/blink/renderer/platform/wtf/hash_traits.h b/third_party/blink/renderer/platform/wtf/hash_traits.h
index a32f498..9c54faa0 100644
--- a/third_party/blink/renderer/platform/wtf/hash_traits.h
+++ b/third_party/blink/renderer/platform/wtf/hash_traits.h
@@ -601,17 +601,4 @@
 
 }  // namespace blink
 
-// TODO(crbug.com/422768753): Remove these `using` directives.
-namespace WTF {
-using blink::ConstructHashTraitsDeletedValue;
-using blink::GenericHashTraits;
-using blink::GetHash;
-using blink::HashTraits;
-using blink::IntWithZeroKeyHashTraits;
-using blink::IsHashTraitsDeletedValue;
-using blink::IsHashTraitsEmptyOrDeletedValue;
-using blink::IsHashTraitsEmptyValue;
-using blink::SimpleClassHashTraits;
-}  // namespace WTF
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_HASH_TRAITS_H_
diff --git a/third_party/blink/renderer/platform/wtf/std_lib_extras.h b/third_party/blink/renderer/platform/wtf/std_lib_extras.h
index 1ad2616d..a1d2ee9f1 100644
--- a/third_party/blink/renderer/platform/wtf/std_lib_extras.h
+++ b/third_party/blink/renderer/platform/wtf/std_lib_extras.h
@@ -40,12 +40,14 @@
 #include "third_party/blink/renderer/platform/wtf/threading.h"
 #endif
 
-#define DEFINE_STATIC_LOCAL_IMPL(Type, Name, Arguments, allow_cross_thread)    \
-  static WTF::StaticSingleton<Type> s_##Name(                                  \
-      [&]() { return new WTF::StaticSingleton<Type>::WrapperType Arguments; }, \
-      [&](void* leaked_ptr) {                                                  \
-        new (leaked_ptr) WTF::StaticSingleton<Type>::WrapperType Arguments;    \
-      });                                                                      \
+#define DEFINE_STATIC_LOCAL_IMPL(Type, Name, Arguments, allow_cross_thread)   \
+  static blink::StaticSingleton<Type> s_##Name(                               \
+      [&]() {                                                                 \
+        return new blink::StaticSingleton<Type>::WrapperType Arguments;       \
+      },                                                                      \
+      [&](void* leaked_ptr) {                                                 \
+        new (leaked_ptr) blink::StaticSingleton<Type>::WrapperType Arguments; \
+      });                                                                     \
   Type& Name = s_##Name.Get(allow_cross_thread)
 
 // Use |DEFINE_STATIC_LOCAL()| to declare and define a static local variable
@@ -66,7 +68,7 @@
 #define DEFINE_THREAD_SAFE_STATIC_LOCAL(Type, Name, Arguments) \
   DEFINE_STATIC_LOCAL_IMPL(Type, Name, Arguments, true)
 
-namespace WTF {
+namespace blink {
 
 template <typename Type>
 class StaticSingleton final {
@@ -85,11 +87,11 @@
       : instance_(heap_new, placement_new)
 #if DCHECK_IS_ON()
         ,
-        safely_initialized_(blink::IsBeforeThreadCreated()),
-        thread_(blink::CurrentThread())
+        safely_initialized_(IsBeforeThreadCreated()),
+        thread_(CurrentThread())
 #endif
   {
-    static_assert(!blink::IsGarbageCollectedTypeV<Type>,
+    static_assert(!IsGarbageCollectedTypeV<Type>,
                   "Garbage collected objects must be wrapped in a Persistent");
     LEAK_SANITIZER_IGNORE_OBJECT(instance_.Get());
   }
@@ -114,7 +116,7 @@
     // keeps being called on the same thread if cross-thread
     // use is not permitted.
     return allow_cross_thread_use || safely_initialized_ ||
-           thread_ == blink::CurrentThread();
+           thread_ == CurrentThread();
   }
 #endif
   template <typename T, bool is_small = sizeof(T) <= 32>
@@ -149,8 +151,6 @@
 #endif
 };
 
-}  // namespace WTF
-
 // Use this to declare and define a static local pointer to a ref-counted object
 // so that it is leaked so that the object's destructors are not called at
 // exit.  This macro should be used with ref-counted objects rather than
@@ -175,24 +175,24 @@
  */
 #if defined(ARCH_CPU_ARMEL) && defined(COMPILER_GCC)
 template <typename Type>
-bool isPointerTypeAlignmentOkay(Type* ptr) {
+bool IsPointerTypeAlignmentOkay(Type* ptr) {
   return !(reinterpret_cast<intptr_t>(ptr) % __alignof__(Type));
 }
 
 template <typename TypePtr>
 TypePtr reinterpret_cast_ptr(void* ptr) {
-  DCHECK(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr)));
+  DCHECK(IsPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr)));
   return reinterpret_cast<TypePtr>(ptr);
 }
 
 template <typename TypePtr>
 TypePtr reinterpret_cast_ptr(const void* ptr) {
-  DCHECK(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr)));
+  DCHECK(IsPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr)));
   return reinterpret_cast<TypePtr>(ptr);
 }
 #else
 template <typename Type>
-bool isPointerTypeAlignmentOkay(Type*) {
+bool IsPointerTypeAlignmentOkay(Type*) {
   return true;
 }
 #define reinterpret_cast_ptr reinterpret_cast
@@ -202,7 +202,7 @@
 NO_SANITIZE_UNRELATED_CAST
 TypePtr unsafe_reinterpret_cast_ptr(void* ptr) {
 #if defined(ARCH_CPU_ARMEL) && defined(COMPILER_GCC)
-  DCHECK(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr)));
+  DCHECK(IsPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr)));
 #endif
   return reinterpret_cast<TypePtr>(ptr);
 }
@@ -211,13 +211,11 @@
 NO_SANITIZE_UNRELATED_CAST
 TypePtr unsafe_reinterpret_cast_ptr(const void* ptr) {
 #if defined(ARCH_CPU_ARMEL) && defined(COMPILER_GCC)
-  DCHECK(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr)));
+  DCHECK(IsPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr)));
 #endif
   return reinterpret_cast<TypePtr>(ptr);
 }
 
-namespace WTF {
-
 // Use the following macros to prevent errors caused by accidental
 // implicit casting of function arguments.  For example, this can
 // be used to prevent overflows from non-promoting conversions.
@@ -255,6 +253,6 @@
                 "Unsigned to signed conversion not allowed for types with " \
                 "identical size (could overflow).");
 
-}  // namespace WTF
+}  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_STD_LIB_EXTRAS_H_
diff --git a/third_party/blink/renderer/platform/wtf/text/wtf_uchar.h b/third_party/blink/renderer/platform/wtf/text/wtf_uchar.h
index 8e26215..d7124c6 100644
--- a/third_party/blink/renderer/platform/wtf/text/wtf_uchar.h
+++ b/third_party/blink/renderer/platform/wtf/text/wtf_uchar.h
@@ -22,7 +22,11 @@
 
 static_assert(sizeof(UChar) == 2, "UChar should be two bytes");
 
+namespace blink {
+
 // Define platform neutral 8 bit character type (L is for Latin-1).
 typedef unsigned char LChar;
 
+}  // namespace blink
+
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_WTF_UCHAR_H_
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests
index d8704fc5..e3a9d560 100644
--- a/third_party/blink/web_tests/NeverFixTests
+++ b/third_party/blink/web_tests/NeverFixTests
@@ -1914,6 +1914,9 @@
 virtual/prefetch-sw/external/wpt/speculation-rules/prefetch/anonymous-client.https.html [ Skip ]
 virtual/prefetch-sw/external/wpt/speculation-rules/prefetch/cross-origin-cookies-anonymous-client-ip-duplicate.https.html [ Skip ]
 
-# These tests test origin trial behavior that is only enabled on windows
+# These tests test origin trial behavior that is only enabled on windows.
 [ Mac ] http/tests/origin_trials/webexposed/incoming-call-notifications-origin-trial-interfaces.html [ Skip ]
 [ Linux ] http/tests/origin_trials/webexposed/incoming-call-notifications-origin-trial-interfaces.html [ Skip ]
+
+# The behavior is only available on Windows and Mac.
+[ Linux ] external/wpt/screen-capture/getdisplaymedia-restrictOwnAudio.https.html [ Skip ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index c18bfc8..634d990 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -3317,6 +3317,8 @@
 crbug.com/416704402 virtual/not-split-http-cache/external/wpt/fetch/http-cache/pragma-no-cache-with-cache-control.html [ Failure ]
 crbug.com/416704402 virtual/split-cache-by-include-credentials/external/wpt/fetch/http-cache/pragma-no-cache-with-cache-control.html [ Failure ]
 crbug.com/416704402 virtual/split-http-cache/external/wpt/fetch/http-cache/pragma-no-cache-with-cache-control.html [ Failure ]
+crbug.com/416704402 virtual/http-cache-default-backend/external/wpt/fetch/http-cache/pragma-no-cache-with-cache-control.html [ Failure ]
+crbug.com/416704402 virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/pragma-no-cache-with-cache-control.html [ Failure ]
 crbug.com/415669416 [ Mac15 ] external/wpt/css/css-position/sticky/position-sticky-fractional-offset.html [ Failure ]
 crbug.com/415738357 [ Linux ] external/wpt/webdriver/tests/bidi/emulation/set_geolocation_override/error.py [ Failure ]
 crbug.com/415738357 [ Linux ] external/wpt/webdriver/tests/bidi/emulation/set_geolocation_override/invalid.py [ Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index 05824d0..ae98f64 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -1614,6 +1614,44 @@
     "expires": "Jun 1, 2026"
   },
   {
+    "prefix": "http-cache-default-backend",
+    "platforms": [
+      "Linux",
+      "Mac",
+      "Win"
+    ],
+    "bases": [
+      "external/wpt/fetch/http-cache"
+    ],
+    "exclusive_tests": "ALL",
+    "args": [
+      "--enable-features=DiskCacheBackendExperiment:backend/default"
+    ],
+    "expires": "Jul 25, 2026",
+    "owners": [
+      "horo@chromium.org"
+    ]
+  },
+  {
+    "prefix": "http-cache-sql-backend",
+    "platforms": [
+      "Linux",
+      "Mac",
+      "Win"
+    ],
+    "bases": [
+      "external/wpt/fetch/http-cache"
+    ],
+    "exclusive_tests": "ALL",
+    "args": [
+      "--enable-features=DiskCacheBackendExperiment:backend/sql"
+    ],
+    "expires": "Jul 25, 2026",
+    "owners": [
+      "horo@chromium.org"
+    ]
+  },
+  {
     "prefix": "image-disabled",
     "owners": [
       "leimy@google.com"
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/auto-height-flex-item-in-multicol-crash.html b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/auto-height-flex-item-in-multicol-crash.html
new file mode 100644
index 0000000..82dec303
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-break/flexbox/auto-height-flex-item-in-multicol-crash.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<link rel="help" href="https://crbug.com/434735271">
+<link rel="help" href="https://crbug.com/433011988">
+<style>
+  #flex {
+    display: flex;
+    flex-wrap: wrap;
+    height: 200px;
+    align-content: flex-end;
+    gap: 60px;
+  }
+</style>
+<div style="width: 100px; height: 100px; columns: 2; column-gap: 0;">
+  <div id="flex">
+    <div style="height: auto; width: 20px;"></div>
+    T
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia-restrictOwnAudio.https.html b/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia-restrictOwnAudio.https.html
new file mode 100644
index 0000000..b4915de
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia-restrictOwnAudio.https.html
@@ -0,0 +1,56 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>getDisplayMedia</title>
+<meta name="timeout" content="long">
+<button id="button">User gesture</button>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script>
+  'use strict';
+
+const stopTracks = stream => stream.getTracks().forEach(track => track.stop());
+
+async function getDisplayMedia(constraints) {
+  const p = new Promise(r => button.onclick = r);
+  await test_driver.click(button);
+  await p;
+  return navigator.mediaDevices.getDisplayMedia(constraints);
+}
+
+test(() => {
+  const supportedConstraints =
+    navigator.mediaDevices.getSupportedConstraints();
+  assert_true(supportedConstraints.restrictOwnAudio);
+}, "restrictOwnAudio is supported");
+
+{
+  const restrictOwnAudio = [true, false];
+  restrictOwnAudio.forEach((restrictOwnAudio) => {
+    promise_test(async (t) => {
+      const stream = await getDisplayMedia({
+        audio: { restrictOwnAudio },
+      });
+      t.add_cleanup(() => stopTracks(stream));
+      const [videoTrack] = stream.getVideoTracks();
+      assert_false("restrictOwnAudio" in videoTrack.getSettings());
+      const [audioTrack] = stream.getAudioTracks();
+      const audioTrackSettings = audioTrack.getSettings();
+      assert_true("restrictOwnAudio" in audioTrackSettings);
+      assert_equals(
+        audioTrackSettings.restrictOwnAudio,
+        restrictOwnAudio
+      );
+      await audioTrack.applyConstraints();
+      // Removing constraints does not change the restrictOwnAudio setting.
+      assert_true("restrictOwnAudio" in audioTrackSettings);
+      assert_equals(
+        audioTrackSettings.restrictOwnAudio,
+        restrictOwnAudio
+      );
+    }, `getDisplayMedia({"audio":{"restrictOwnAudio":${restrictOwnAudio}}}) with getSettings`);
+  });
+}
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https.html b/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https.html
index 4a7c655..0051e4c 100644
--- a/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https.html
+++ b/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https.html
@@ -213,6 +213,9 @@
  {surfaceSwitching: "exclude"},
  {systemAudio: "include"},
  {systemAudio: "exclude"},
+ {windowAudio: "exclude"},
+ {windowAudio: "window"},
+ {windowAudio: "system"},
 ].forEach(constraints => promise_test(async t => {
   const stream = await getDisplayMedia(constraints);
   t.add_cleanup(() => stopTracks(stream));
@@ -222,6 +225,7 @@
  {selfBrowserSurface: "invalid"},
  {surfaceSwitching: "invalid"},
  {systemAudio: "invalid"},
+ {windowAudio: "invalid"},
  {monitorTypeSurfaces: "invalid"},
 ].forEach(constraints => promise_test(async t => {
   await test_driver.bless('getDisplayMedia()');
diff --git a/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/tensor.https.any.js b/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/tensor.https.any.js
index ea2cedb..4b6a4ab8 100644
--- a/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/tensor.https.any.js
+++ b/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/tensor.https.any.js
@@ -1762,6 +1762,35 @@
     const inputData = new Float32Array(sizeOfShape(shape)).fill(1.0);
     anotherMLContext.writeTensor(mlTensor, inputData);
 
+    const gpuTensorBuffer = await anotherMLContext.exportToGPU(mlTensor);
+
+    anotherGPUDevice.destroy();
+
+    gpuTensorBuffer.destroy();
+
+    await promise_rejects_dom(
+        t, 'InvalidStateError', anotherMLContext.readTensor(mlTensor));
+  }, `${testName} / destroy device after export`);
+
+  promise_test(async t => {
+    if (!isExportToGPUSupported) {
+      return;
+    }
+
+    let anotherGPUDevice = await gpuAdapter.requestDevice();
+    let anotherMLContext = await navigator.ml.createContext(anotherGPUDevice);
+
+    let mlTensor = await anotherMLContext.createTensor({
+      dataType: 'float32',
+      shape: shape,
+      exportableToGPU: true,
+      readable: true,
+      writable: true
+    });
+
+    const inputData = new Float32Array(sizeOfShape(shape)).fill(1.0);
+    anotherMLContext.writeTensor(mlTensor, inputData);
+
     anotherGPUDevice.destroy();
 
     await promise_rejects_dom(
diff --git a/third_party/blink/web_tests/external/wpt/webnn/validation_tests/constant.https.any.js b/third_party/blink/web_tests/external/wpt/webnn/validation_tests/constant.https.any.js
index f9e34ea..420fd9d 100644
--- a/third_party/blink/web_tests/external/wpt/webnn/validation_tests/constant.https.any.js
+++ b/third_party/blink/web_tests/external/wpt/webnn/validation_tests/constant.https.any.js
@@ -181,6 +181,26 @@
         '[constant] Throw if the operand data type isn\'t of type MLOperandDataType',
     descriptor: {dataType: 'int16', shape: [2, 3]},
     buffer: {type: Int16Array, byteLength: 6 * 2}
+  },
+  {
+    name:
+        '[constant] Uint8Array should be allowed for float32 operand data type',
+    descriptor: {dataType: 'float32', shape: [2, 3]},
+    buffer: {type: Uint8Array, byteLength: 6 * 4},
+    output: {dataType: 'float32', shape: [2, 3]}
+  },
+  {
+    name:
+        '[constant] Uint8Array should be allowed for float16 operand data type',
+    descriptor: {dataType: 'float16', shape: [2, 3]},
+    buffer: {type: Uint8Array, byteLength: 6 * 2},
+    output: {dataType: 'float16', shape: [2, 3]}
+  },
+  {
+    name: '[constant] Uint8Array should be allowed for int32 operand data type',
+    descriptor: {dataType: 'int32', shape: [2, 3]},
+    buffer: {type: Uint8Array, byteLength: 6 * 4},
+    output: {dataType: 'int32', shape: [2, 3]}
   }
 ];
 
diff --git a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gather.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gather.https.any_gpu-expected.txt
deleted file mode 100644
index ad40ec4..0000000
--- a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gather.https.any_gpu-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-[FAIL] gather float32 2D tensor and int32 0D negative indices default options
-  assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected -66.05901336669922 by ULP distance: expected a number less than or equal to 0n but got 1115954743n
-[FAIL] gather float32 2D tensor and int32 0D out-of-bound positive indices default options
-  assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected 90.2870101928711 by ULP distance: expected a number less than or equal to 0n but got 1119130355n
-[FAIL] gather float32 2D tensor and int32 0D out-of-bound negative indices default options
-  assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected -66.05901336669922 by ULP distance: expected a number less than or equal to 0n but got 1115954743n
-[FAIL] gather float16 2D tensor and int32 0D negative indices default options
-  assert_less_than_equal: assert_array_approx_equals_ulp: test gather float16 actual 0 should be close enough to expected -66.0625 by ULP distance: expected a number less than or equal to 0 but got 54305
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gatherND.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gatherND.https.any_gpu-expected.txt
deleted file mode 100644
index ed58e6a..0000000
--- a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gatherND.https.any_gpu-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-[FAIL] gatherND float32 4D input and 1D minimum indices
-  assert_less_than_equal: assert_array_approx_equals_ulp: test gatherND float32 actual 0 should be close enough to expected -66.05901336669922 by ULP distance: expected a number less than or equal to 0n but got 1115954743n
-[FAIL] gatherND float32 2D input and 2D negative indices
-  promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': TFLite doesn't support to gather input into one dimension."
-[FAIL] gatherND float32 1D input and 2D out-of-bounds indices
-  promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': TFLite doesn't support to gather input into one dimension."
-[FAIL] gatherND float16 4D input and 1D minimum indices
-  assert_less_than_equal: assert_array_approx_equals_ulp: test gatherND float16 actual 0 should be close enough to expected -66.0625 by ULP distance: expected a number less than or equal to 0 but got 54305
-[FAIL] gatherND float16 2D input and 2D negative indices
-  promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': TFLite doesn't support to gather input into one dimension."
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/README.md b/third_party/blink/web_tests/virtual/http-cache-default-backend/README.md
new file mode 100644
index 0000000..8ca800a
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/README.md
@@ -0,0 +1,4 @@
+# Overview
+
+This suite tests with `--enable-features=DiskCacheBackendExperiment:backend/default`.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cache-mode.any-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cache-mode.any-expected.txt
new file mode 100644
index 0000000..6a222db
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cache-mode.any-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] Fetch sends Cache-Control: no-cache and Pragma: no-cache when cache mode is no-store
+  assert_equals: request 1 header cache-control value is "undefined", not "no-cache" expected (string) "no-cache" but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cache-mode.any.serviceworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cache-mode.any.serviceworker-expected.txt
new file mode 100644
index 0000000..6a222db
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cache-mode.any.serviceworker-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] Fetch sends Cache-Control: no-cache and Pragma: no-cache when cache mode is no-store
+  assert_equals: request 1 header cache-control value is "undefined", not "no-cache" expected (string) "no-cache" but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cache-mode.any.sharedworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cache-mode.any.sharedworker-expected.txt
new file mode 100644
index 0000000..6a222db
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cache-mode.any.sharedworker-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] Fetch sends Cache-Control: no-cache and Pragma: no-cache when cache mode is no-store
+  assert_equals: request 1 header cache-control value is "undefined", not "no-cache" expected (string) "no-cache" but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cache-mode.any.worker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cache-mode.any.worker-expected.txt
new file mode 100644
index 0000000..6a222db
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cache-mode.any.worker-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] Fetch sends Cache-Control: no-cache and Pragma: no-cache when cache mode is no-store
+  assert_equals: request 1 header cache-control value is "undefined", not "no-cache" expected (string) "no-cache" but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cc-request.any-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cc-request.any-expected.txt
new file mode 100644
index 0000000..ee2d7c24
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cc-request.any-expected.txt
@@ -0,0 +1,19 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache doesn't use aged but fresh response when request contains Cache-Control: max-age=1
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't use fresh response with Age header when request contains Cache-Control: max-age that is greater than remaining freshness
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache does use aged stale response when request contains Cache-Control: max-stale that permits its use
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache does reuse stale response with Age header when request contains Cache-Control: max-stale that permits its use
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache doesn't reuse fresh response when request contains Cache-Control: min-fresh that wants it fresher
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't reuse fresh response with Age header when request contains Cache-Control: min-fresh that wants it fresher
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't reuse fresh response when request contains Cache-Control: no-store
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache generates 504 status code when nothing is in cache and request contains Cache-Control: only-if-cached
+  assert_equals: Response 1 status is 200, not 504 expected 504 but got 200
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cc-request.any.serviceworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cc-request.any.serviceworker-expected.txt
new file mode 100644
index 0000000..ee2d7c24
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cc-request.any.serviceworker-expected.txt
@@ -0,0 +1,19 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache doesn't use aged but fresh response when request contains Cache-Control: max-age=1
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't use fresh response with Age header when request contains Cache-Control: max-age that is greater than remaining freshness
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache does use aged stale response when request contains Cache-Control: max-stale that permits its use
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache does reuse stale response with Age header when request contains Cache-Control: max-stale that permits its use
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache doesn't reuse fresh response when request contains Cache-Control: min-fresh that wants it fresher
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't reuse fresh response with Age header when request contains Cache-Control: min-fresh that wants it fresher
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't reuse fresh response when request contains Cache-Control: no-store
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache generates 504 status code when nothing is in cache and request contains Cache-Control: only-if-cached
+  assert_equals: Response 1 status is 200, not 504 expected 504 but got 200
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cc-request.any.sharedworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cc-request.any.sharedworker-expected.txt
new file mode 100644
index 0000000..ee2d7c24
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cc-request.any.sharedworker-expected.txt
@@ -0,0 +1,19 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache doesn't use aged but fresh response when request contains Cache-Control: max-age=1
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't use fresh response with Age header when request contains Cache-Control: max-age that is greater than remaining freshness
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache does use aged stale response when request contains Cache-Control: max-stale that permits its use
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache does reuse stale response with Age header when request contains Cache-Control: max-stale that permits its use
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache doesn't reuse fresh response when request contains Cache-Control: min-fresh that wants it fresher
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't reuse fresh response with Age header when request contains Cache-Control: min-fresh that wants it fresher
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't reuse fresh response when request contains Cache-Control: no-store
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache generates 504 status code when nothing is in cache and request contains Cache-Control: only-if-cached
+  assert_equals: Response 1 status is 200, not 504 expected 504 but got 200
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cc-request.any.worker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cc-request.any.worker-expected.txt
new file mode 100644
index 0000000..ee2d7c24
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/cc-request.any.worker-expected.txt
@@ -0,0 +1,19 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache doesn't use aged but fresh response when request contains Cache-Control: max-age=1
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't use fresh response with Age header when request contains Cache-Control: max-age that is greater than remaining freshness
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache does use aged stale response when request contains Cache-Control: max-stale that permits its use
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache does reuse stale response with Age header when request contains Cache-Control: max-stale that permits its use
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache doesn't reuse fresh response when request contains Cache-Control: min-fresh that wants it fresher
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't reuse fresh response with Age header when request contains Cache-Control: min-fresh that wants it fresher
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't reuse fresh response when request contains Cache-Control: no-store
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache generates 504 status code when nothing is in cache and request contains Cache-Control: only-if-cached
+  assert_equals: Response 1 status is 200, not 504 expected 504 but got 200
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/credentials.tentative.any-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/credentials.tentative.any-expected.txt
new file mode 100644
index 0000000..aa1adfbc4
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/credentials.tentative.any-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[FAIL] same-origin: 2xAnonymous, 2xCredentialled, 1xAnonymous
+  assert_equals: Response 3 header Server-Request-Count is "1", not "2" expected "2" but got "1"
+[FAIL] same-origin: 2xCredentialled, 2xAnonymous, 1xCredentialled
+  assert_equals: Response 3 header Server-Request-Count is "1", not "2" expected "2" but got "1"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/credentials.tentative.any.serviceworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/credentials.tentative.any.serviceworker-expected.txt
new file mode 100644
index 0000000..aa1adfbc4
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/credentials.tentative.any.serviceworker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[FAIL] same-origin: 2xAnonymous, 2xCredentialled, 1xAnonymous
+  assert_equals: Response 3 header Server-Request-Count is "1", not "2" expected "2" but got "1"
+[FAIL] same-origin: 2xCredentialled, 2xAnonymous, 1xCredentialled
+  assert_equals: Response 3 header Server-Request-Count is "1", not "2" expected "2" but got "1"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/credentials.tentative.any.sharedworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/credentials.tentative.any.sharedworker-expected.txt
new file mode 100644
index 0000000..aa1adfbc4
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/credentials.tentative.any.sharedworker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[FAIL] same-origin: 2xAnonymous, 2xCredentialled, 1xAnonymous
+  assert_equals: Response 3 header Server-Request-Count is "1", not "2" expected "2" but got "1"
+[FAIL] same-origin: 2xCredentialled, 2xAnonymous, 1xCredentialled
+  assert_equals: Response 3 header Server-Request-Count is "1", not "2" expected "2" but got "1"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/credentials.tentative.any.worker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/credentials.tentative.any.worker-expected.txt
new file mode 100644
index 0000000..aa1adfbc4
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/credentials.tentative.any.worker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[FAIL] same-origin: 2xAnonymous, 2xCredentialled, 1xAnonymous
+  assert_equals: Response 3 header Server-Request-Count is "1", not "2" expected "2" but got "1"
+[FAIL] same-origin: 2xCredentialled, 2xAnonymous, 1xCredentialled
+  assert_equals: Response 3 header Server-Request-Count is "1", not "2" expected "2" but got "1"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/heuristic.any-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/heuristic.any-expected.txt
new file mode 100644
index 0000000..6a9fab0
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/heuristic.any-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache reuses an unknown response with Last-Modified based upon heuristic freshness when Cache-Control: public is present
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 204 No Content response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 404 Not Found response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 405 Method Not Allowed response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 414 URI Too Long response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 501 Not Implemented response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/heuristic.any.serviceworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/heuristic.any.serviceworker-expected.txt
new file mode 100644
index 0000000..6a9fab0
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/heuristic.any.serviceworker-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache reuses an unknown response with Last-Modified based upon heuristic freshness when Cache-Control: public is present
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 204 No Content response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 404 Not Found response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 405 Method Not Allowed response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 414 URI Too Long response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 501 Not Implemented response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/heuristic.any.sharedworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/heuristic.any.sharedworker-expected.txt
new file mode 100644
index 0000000..6a9fab0
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/heuristic.any.sharedworker-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache reuses an unknown response with Last-Modified based upon heuristic freshness when Cache-Control: public is present
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 204 No Content response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 404 Not Found response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 405 Method Not Allowed response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 414 URI Too Long response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 501 Not Implemented response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/heuristic.any.worker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/heuristic.any.worker-expected.txt
new file mode 100644
index 0000000..6a9fab0
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/heuristic.any.worker-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache reuses an unknown response with Last-Modified based upon heuristic freshness when Cache-Control: public is present
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 204 No Content response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 404 Not Found response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 405 Method Not Allowed response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 414 URI Too Long response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 501 Not Implemented response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/invalidate.any-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/invalidate.any-expected.txt
new file mode 100644
index 0000000..e52f607a
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/invalidate.any-expected.txt
@@ -0,0 +1,21 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache invalidates after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a POST
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a PUT
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a DELETE
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a POST
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a PUT
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a DELETE
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/invalidate.any.serviceworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/invalidate.any.serviceworker-expected.txt
new file mode 100644
index 0000000..e52f607a
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/invalidate.any.serviceworker-expected.txt
@@ -0,0 +1,21 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache invalidates after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a POST
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a PUT
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a DELETE
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a POST
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a PUT
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a DELETE
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/invalidate.any.sharedworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/invalidate.any.sharedworker-expected.txt
new file mode 100644
index 0000000..e52f607a
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/invalidate.any.sharedworker-expected.txt
@@ -0,0 +1,21 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache invalidates after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a POST
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a PUT
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a DELETE
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a POST
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a PUT
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a DELETE
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/invalidate.any.worker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/invalidate.any.worker-expected.txt
new file mode 100644
index 0000000..e52f607a
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/invalidate.any.worker-expected.txt
@@ -0,0 +1,21 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache invalidates after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a POST
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a PUT
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a DELETE
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a POST
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a PUT
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a DELETE
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/partial.any-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/partial.any-expected.txt
new file mode 100644
index 0000000..cf5c6e6e
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/partial.any-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache stores partial content and reuses it
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores complete response and serves smaller ranges from it with only-if-cached
+  promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (byte-range-spec)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (absent last-byte-pos)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (suffix-byte-range-spec)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial content and completes it
+  assert_equals: request 2 header range value is "undefined", not "bytes=5-" expected (string) "bytes=5-" but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/partial.any.serviceworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/partial.any.serviceworker-expected.txt
new file mode 100644
index 0000000..cf5c6e6e
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/partial.any.serviceworker-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache stores partial content and reuses it
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores complete response and serves smaller ranges from it with only-if-cached
+  promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (byte-range-spec)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (absent last-byte-pos)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (suffix-byte-range-spec)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial content and completes it
+  assert_equals: request 2 header range value is "undefined", not "bytes=5-" expected (string) "bytes=5-" but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/partial.any.sharedworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/partial.any.sharedworker-expected.txt
new file mode 100644
index 0000000..cf5c6e6e
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/partial.any.sharedworker-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache stores partial content and reuses it
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores complete response and serves smaller ranges from it with only-if-cached
+  promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (byte-range-spec)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (absent last-byte-pos)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (suffix-byte-range-spec)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial content and completes it
+  assert_equals: request 2 header range value is "undefined", not "bytes=5-" expected (string) "bytes=5-" but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/partial.any.worker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/partial.any.worker-expected.txt
new file mode 100644
index 0000000..cf5c6e6e
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/partial.any.worker-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache stores partial content and reuses it
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores complete response and serves smaller ranges from it with only-if-cached
+  promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (byte-range-spec)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (absent last-byte-pos)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (suffix-byte-range-spec)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial content and completes it
+  assert_equals: request 2 header range value is "undefined", not "bytes=5-" expected (string) "bytes=5-" but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/post-patch.any-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/post-patch.any-expected.txt
new file mode 100644
index 0000000..ff3614f
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/post-patch.any-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache uses content after PATCH request with response containing Content-Location and cache-allowing header
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache uses content after POST request with response containing Content-Location and cache-allowing header
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/post-patch.any.serviceworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/post-patch.any.serviceworker-expected.txt
new file mode 100644
index 0000000..ff3614f
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/post-patch.any.serviceworker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache uses content after PATCH request with response containing Content-Location and cache-allowing header
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache uses content after POST request with response containing Content-Location and cache-allowing header
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/post-patch.any.sharedworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/post-patch.any.sharedworker-expected.txt
new file mode 100644
index 0000000..ff3614f
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/post-patch.any.sharedworker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache uses content after PATCH request with response containing Content-Location and cache-allowing header
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache uses content after POST request with response containing Content-Location and cache-allowing header
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/post-patch.any.worker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/post-patch.any.worker-expected.txt
new file mode 100644
index 0000000..ff3614f
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/post-patch.any.worker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache uses content after PATCH request with response containing Content-Location and cache-allowing header
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache uses content after POST request with response containing Content-Location and cache-allowing header
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/vary.any-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/vary.any-expected.txt
new file mode 100644
index 0000000..5edeb6e
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/vary.any-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache doesn't invalidate existing Vary response
+  assert_less_than: Response 3 does not come from cache expected a number less than 3 but got 3
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/vary.any.serviceworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/vary.any.serviceworker-expected.txt
new file mode 100644
index 0000000..5edeb6e
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/vary.any.serviceworker-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache doesn't invalidate existing Vary response
+  assert_less_than: Response 3 does not come from cache expected a number less than 3 but got 3
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/vary.any.sharedworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/vary.any.sharedworker-expected.txt
new file mode 100644
index 0000000..5edeb6e
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/vary.any.sharedworker-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache doesn't invalidate existing Vary response
+  assert_less_than: Response 3 does not come from cache expected a number less than 3 but got 3
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/vary.any.worker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/vary.any.worker-expected.txt
new file mode 100644
index 0000000..5edeb6e
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-default-backend/external/wpt/fetch/http-cache/vary.any.worker-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache doesn't invalidate existing Vary response
+  assert_less_than: Response 3 does not come from cache expected a number less than 3 but got 3
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/README.md b/third_party/blink/web_tests/virtual/http-cache-sql-backend/README.md
new file mode 100644
index 0000000..54ab9eab
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/README.md
@@ -0,0 +1,4 @@
+# Overview
+
+This suite tests with `--enable-features=DiskCacheBackendExperiment:backend/sql`.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cache-mode.any-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cache-mode.any-expected.txt
new file mode 100644
index 0000000..6a222db
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cache-mode.any-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] Fetch sends Cache-Control: no-cache and Pragma: no-cache when cache mode is no-store
+  assert_equals: request 1 header cache-control value is "undefined", not "no-cache" expected (string) "no-cache" but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cache-mode.any.serviceworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cache-mode.any.serviceworker-expected.txt
new file mode 100644
index 0000000..6a222db
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cache-mode.any.serviceworker-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] Fetch sends Cache-Control: no-cache and Pragma: no-cache when cache mode is no-store
+  assert_equals: request 1 header cache-control value is "undefined", not "no-cache" expected (string) "no-cache" but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cache-mode.any.sharedworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cache-mode.any.sharedworker-expected.txt
new file mode 100644
index 0000000..6a222db
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cache-mode.any.sharedworker-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] Fetch sends Cache-Control: no-cache and Pragma: no-cache when cache mode is no-store
+  assert_equals: request 1 header cache-control value is "undefined", not "no-cache" expected (string) "no-cache" but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cache-mode.any.worker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cache-mode.any.worker-expected.txt
new file mode 100644
index 0000000..6a222db
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cache-mode.any.worker-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] Fetch sends Cache-Control: no-cache and Pragma: no-cache when cache mode is no-store
+  assert_equals: request 1 header cache-control value is "undefined", not "no-cache" expected (string) "no-cache" but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cc-request.any-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cc-request.any-expected.txt
new file mode 100644
index 0000000..ee2d7c24
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cc-request.any-expected.txt
@@ -0,0 +1,19 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache doesn't use aged but fresh response when request contains Cache-Control: max-age=1
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't use fresh response with Age header when request contains Cache-Control: max-age that is greater than remaining freshness
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache does use aged stale response when request contains Cache-Control: max-stale that permits its use
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache does reuse stale response with Age header when request contains Cache-Control: max-stale that permits its use
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache doesn't reuse fresh response when request contains Cache-Control: min-fresh that wants it fresher
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't reuse fresh response with Age header when request contains Cache-Control: min-fresh that wants it fresher
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't reuse fresh response when request contains Cache-Control: no-store
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache generates 504 status code when nothing is in cache and request contains Cache-Control: only-if-cached
+  assert_equals: Response 1 status is 200, not 504 expected 504 but got 200
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cc-request.any.serviceworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cc-request.any.serviceworker-expected.txt
new file mode 100644
index 0000000..ee2d7c24
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cc-request.any.serviceworker-expected.txt
@@ -0,0 +1,19 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache doesn't use aged but fresh response when request contains Cache-Control: max-age=1
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't use fresh response with Age header when request contains Cache-Control: max-age that is greater than remaining freshness
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache does use aged stale response when request contains Cache-Control: max-stale that permits its use
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache does reuse stale response with Age header when request contains Cache-Control: max-stale that permits its use
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache doesn't reuse fresh response when request contains Cache-Control: min-fresh that wants it fresher
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't reuse fresh response with Age header when request contains Cache-Control: min-fresh that wants it fresher
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't reuse fresh response when request contains Cache-Control: no-store
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache generates 504 status code when nothing is in cache and request contains Cache-Control: only-if-cached
+  assert_equals: Response 1 status is 200, not 504 expected 504 but got 200
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cc-request.any.sharedworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cc-request.any.sharedworker-expected.txt
new file mode 100644
index 0000000..ee2d7c24
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cc-request.any.sharedworker-expected.txt
@@ -0,0 +1,19 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache doesn't use aged but fresh response when request contains Cache-Control: max-age=1
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't use fresh response with Age header when request contains Cache-Control: max-age that is greater than remaining freshness
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache does use aged stale response when request contains Cache-Control: max-stale that permits its use
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache does reuse stale response with Age header when request contains Cache-Control: max-stale that permits its use
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache doesn't reuse fresh response when request contains Cache-Control: min-fresh that wants it fresher
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't reuse fresh response with Age header when request contains Cache-Control: min-fresh that wants it fresher
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't reuse fresh response when request contains Cache-Control: no-store
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache generates 504 status code when nothing is in cache and request contains Cache-Control: only-if-cached
+  assert_equals: Response 1 status is 200, not 504 expected 504 but got 200
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cc-request.any.worker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cc-request.any.worker-expected.txt
new file mode 100644
index 0000000..ee2d7c24
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/cc-request.any.worker-expected.txt
@@ -0,0 +1,19 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache doesn't use aged but fresh response when request contains Cache-Control: max-age=1
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't use fresh response with Age header when request contains Cache-Control: max-age that is greater than remaining freshness
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache does use aged stale response when request contains Cache-Control: max-stale that permits its use
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache does reuse stale response with Age header when request contains Cache-Control: max-stale that permits its use
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache doesn't reuse fresh response when request contains Cache-Control: min-fresh that wants it fresher
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't reuse fresh response with Age header when request contains Cache-Control: min-fresh that wants it fresher
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache doesn't reuse fresh response when request contains Cache-Control: no-store
+  assert_equals: Response 2 comes from cache expected 2 but got 1
+[FAIL] HTTP cache generates 504 status code when nothing is in cache and request contains Cache-Control: only-if-cached
+  assert_equals: Response 1 status is 200, not 504 expected 504 but got 200
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/credentials.tentative.any-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/credentials.tentative.any-expected.txt
new file mode 100644
index 0000000..aa1adfbc4
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/credentials.tentative.any-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[FAIL] same-origin: 2xAnonymous, 2xCredentialled, 1xAnonymous
+  assert_equals: Response 3 header Server-Request-Count is "1", not "2" expected "2" but got "1"
+[FAIL] same-origin: 2xCredentialled, 2xAnonymous, 1xCredentialled
+  assert_equals: Response 3 header Server-Request-Count is "1", not "2" expected "2" but got "1"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/credentials.tentative.any.serviceworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/credentials.tentative.any.serviceworker-expected.txt
new file mode 100644
index 0000000..aa1adfbc4
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/credentials.tentative.any.serviceworker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[FAIL] same-origin: 2xAnonymous, 2xCredentialled, 1xAnonymous
+  assert_equals: Response 3 header Server-Request-Count is "1", not "2" expected "2" but got "1"
+[FAIL] same-origin: 2xCredentialled, 2xAnonymous, 1xCredentialled
+  assert_equals: Response 3 header Server-Request-Count is "1", not "2" expected "2" but got "1"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/credentials.tentative.any.sharedworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/credentials.tentative.any.sharedworker-expected.txt
new file mode 100644
index 0000000..aa1adfbc4
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/credentials.tentative.any.sharedworker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[FAIL] same-origin: 2xAnonymous, 2xCredentialled, 1xAnonymous
+  assert_equals: Response 3 header Server-Request-Count is "1", not "2" expected "2" but got "1"
+[FAIL] same-origin: 2xCredentialled, 2xAnonymous, 1xCredentialled
+  assert_equals: Response 3 header Server-Request-Count is "1", not "2" expected "2" but got "1"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/credentials.tentative.any.worker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/credentials.tentative.any.worker-expected.txt
new file mode 100644
index 0000000..aa1adfbc4
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/credentials.tentative.any.worker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[FAIL] same-origin: 2xAnonymous, 2xCredentialled, 1xAnonymous
+  assert_equals: Response 3 header Server-Request-Count is "1", not "2" expected "2" but got "1"
+[FAIL] same-origin: 2xCredentialled, 2xAnonymous, 1xCredentialled
+  assert_equals: Response 3 header Server-Request-Count is "1", not "2" expected "2" but got "1"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/heuristic.any-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/heuristic.any-expected.txt
new file mode 100644
index 0000000..6a9fab0
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/heuristic.any-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache reuses an unknown response with Last-Modified based upon heuristic freshness when Cache-Control: public is present
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 204 No Content response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 404 Not Found response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 405 Method Not Allowed response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 414 URI Too Long response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 501 Not Implemented response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/heuristic.any.serviceworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/heuristic.any.serviceworker-expected.txt
new file mode 100644
index 0000000..6a9fab0
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/heuristic.any.serviceworker-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache reuses an unknown response with Last-Modified based upon heuristic freshness when Cache-Control: public is present
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 204 No Content response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 404 Not Found response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 405 Method Not Allowed response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 414 URI Too Long response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 501 Not Implemented response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/heuristic.any.sharedworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/heuristic.any.sharedworker-expected.txt
new file mode 100644
index 0000000..6a9fab0
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/heuristic.any.sharedworker-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache reuses an unknown response with Last-Modified based upon heuristic freshness when Cache-Control: public is present
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 204 No Content response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 404 Not Found response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 405 Method Not Allowed response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 414 URI Too Long response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 501 Not Implemented response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/heuristic.any.worker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/heuristic.any.worker-expected.txt
new file mode 100644
index 0000000..6a9fab0
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/heuristic.any.worker-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache reuses an unknown response with Last-Modified based upon heuristic freshness when Cache-Control: public is present
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 204 No Content response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 404 Not Found response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 405 Method Not Allowed response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 414 URI Too Long response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache reuses a 501 Not Implemented response with Last-Modified based upon heuristic freshness
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/invalidate.any-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/invalidate.any-expected.txt
new file mode 100644
index 0000000..e52f607a
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/invalidate.any-expected.txt
@@ -0,0 +1,21 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache invalidates after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a POST
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a PUT
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a DELETE
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a POST
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a PUT
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a DELETE
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/invalidate.any.serviceworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/invalidate.any.serviceworker-expected.txt
new file mode 100644
index 0000000..e52f607a
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/invalidate.any.serviceworker-expected.txt
@@ -0,0 +1,21 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache invalidates after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a POST
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a PUT
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a DELETE
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a POST
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a PUT
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a DELETE
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/invalidate.any.sharedworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/invalidate.any.sharedworker-expected.txt
new file mode 100644
index 0000000..e52f607a
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/invalidate.any.sharedworker-expected.txt
@@ -0,0 +1,21 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache invalidates after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a POST
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a PUT
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a DELETE
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a POST
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a PUT
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a DELETE
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/invalidate.any.worker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/invalidate.any.worker-expected.txt
new file mode 100644
index 0000000..e52f607a
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/invalidate.any.worker-expected.txt
@@ -0,0 +1,21 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache invalidates after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a POST
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a PUT
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from a DELETE
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Location URL after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a POST
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a PUT
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from a DELETE
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+[FAIL] HTTP cache invalidates Content-Location URL after a successful response from an unknown method
+  assert_equals: Response 3 comes from cache expected 3 but got 1
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/partial.any-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/partial.any-expected.txt
new file mode 100644
index 0000000..cf5c6e6e
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/partial.any-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache stores partial content and reuses it
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores complete response and serves smaller ranges from it with only-if-cached
+  promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (byte-range-spec)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (absent last-byte-pos)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (suffix-byte-range-spec)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial content and completes it
+  assert_equals: request 2 header range value is "undefined", not "bytes=5-" expected (string) "bytes=5-" but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/partial.any.serviceworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/partial.any.serviceworker-expected.txt
new file mode 100644
index 0000000..cf5c6e6e
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/partial.any.serviceworker-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache stores partial content and reuses it
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores complete response and serves smaller ranges from it with only-if-cached
+  promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (byte-range-spec)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (absent last-byte-pos)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (suffix-byte-range-spec)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial content and completes it
+  assert_equals: request 2 header range value is "undefined", not "bytes=5-" expected (string) "bytes=5-" but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/partial.any.sharedworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/partial.any.sharedworker-expected.txt
new file mode 100644
index 0000000..cf5c6e6e
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/partial.any.sharedworker-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache stores partial content and reuses it
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores complete response and serves smaller ranges from it with only-if-cached
+  promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (byte-range-spec)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (absent last-byte-pos)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (suffix-byte-range-spec)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial content and completes it
+  assert_equals: request 2 header range value is "undefined", not "bytes=5-" expected (string) "bytes=5-" but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/partial.any.worker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/partial.any.worker-expected.txt
new file mode 100644
index 0000000..cf5c6e6e
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/partial.any.worker-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache stores partial content and reuses it
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores complete response and serves smaller ranges from it with only-if-cached
+  promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (byte-range-spec)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (absent last-byte-pos)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial response and serves smaller ranges from it (suffix-byte-range-spec)
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache stores partial content and completes it
+  assert_equals: request 2 header range value is "undefined", not "bytes=5-" expected (string) "bytes=5-" but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/post-patch.any-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/post-patch.any-expected.txt
new file mode 100644
index 0000000..ff3614f
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/post-patch.any-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache uses content after PATCH request with response containing Content-Location and cache-allowing header
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache uses content after POST request with response containing Content-Location and cache-allowing header
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/post-patch.any.serviceworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/post-patch.any.serviceworker-expected.txt
new file mode 100644
index 0000000..ff3614f
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/post-patch.any.serviceworker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache uses content after PATCH request with response containing Content-Location and cache-allowing header
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache uses content after POST request with response containing Content-Location and cache-allowing header
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/post-patch.any.sharedworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/post-patch.any.sharedworker-expected.txt
new file mode 100644
index 0000000..ff3614f
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/post-patch.any.sharedworker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache uses content after PATCH request with response containing Content-Location and cache-allowing header
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache uses content after POST request with response containing Content-Location and cache-allowing header
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/post-patch.any.worker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/post-patch.any.worker-expected.txt
new file mode 100644
index 0000000..ff3614f
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/post-patch.any.worker-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache uses content after PATCH request with response containing Content-Location and cache-allowing header
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+[FAIL] HTTP cache uses content after POST request with response containing Content-Location and cache-allowing header
+  assert_less_than: Response 2 does not come from cache expected a number less than 2 but got 2
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/vary.any-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/vary.any-expected.txt
new file mode 100644
index 0000000..5edeb6e
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/vary.any-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache doesn't invalidate existing Vary response
+  assert_less_than: Response 3 does not come from cache expected a number less than 3 but got 3
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/vary.any.serviceworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/vary.any.serviceworker-expected.txt
new file mode 100644
index 0000000..5edeb6e
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/vary.any.serviceworker-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache doesn't invalidate existing Vary response
+  assert_less_than: Response 3 does not come from cache expected a number less than 3 but got 3
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/vary.any.sharedworker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/vary.any.sharedworker-expected.txt
new file mode 100644
index 0000000..5edeb6e
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/vary.any.sharedworker-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache doesn't invalidate existing Vary response
+  assert_less_than: Response 3 does not come from cache expected a number less than 3 but got 3
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/vary.any.worker-expected.txt b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/vary.any.worker-expected.txt
new file mode 100644
index 0000000..5edeb6e
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/http-cache-sql-backend/external/wpt/fetch/http-cache/vary.any.worker-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] HTTP cache doesn't invalidate existing Vary response
+  assert_less_than: Response 3 does not come from cache expected a number less than 3 but got 3
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gather.https.any_cpu-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gather.https.any_cpu-expected.txt
deleted file mode 100644
index ad40ec4..0000000
--- a/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gather.https.any_cpu-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-[FAIL] gather float32 2D tensor and int32 0D negative indices default options
-  assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected -66.05901336669922 by ULP distance: expected a number less than or equal to 0n but got 1115954743n
-[FAIL] gather float32 2D tensor and int32 0D out-of-bound positive indices default options
-  assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected 90.2870101928711 by ULP distance: expected a number less than or equal to 0n but got 1119130355n
-[FAIL] gather float32 2D tensor and int32 0D out-of-bound negative indices default options
-  assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected -66.05901336669922 by ULP distance: expected a number less than or equal to 0n but got 1115954743n
-[FAIL] gather float16 2D tensor and int32 0D negative indices default options
-  assert_less_than_equal: assert_array_approx_equals_ulp: test gather float16 actual 0 should be close enough to expected -66.0625 by ULP distance: expected a number less than or equal to 0 but got 54305
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gatherND.https.any_cpu-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gatherND.https.any_cpu-expected.txt
deleted file mode 100644
index ed58e6a..0000000
--- a/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gatherND.https.any_cpu-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-[FAIL] gatherND float32 4D input and 1D minimum indices
-  assert_less_than_equal: assert_array_approx_equals_ulp: test gatherND float32 actual 0 should be close enough to expected -66.05901336669922 by ULP distance: expected a number less than or equal to 0n but got 1115954743n
-[FAIL] gatherND float32 2D input and 2D negative indices
-  promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': TFLite doesn't support to gather input into one dimension."
-[FAIL] gatherND float32 1D input and 2D out-of-bounds indices
-  promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': TFLite doesn't support to gather input into one dimension."
-[FAIL] gatherND float16 4D input and 1D minimum indices
-  assert_less_than_equal: assert_array_approx_equals_ulp: test gatherND float16 actual 0 should be close enough to expected -66.0625 by ULP distance: expected a number less than or equal to 0 but got 54305
-[FAIL] gatherND float16 2D input and 2D negative indices
-  promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': TFLite doesn't support to gather input into one dimension."
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gather.https.any_npu-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gather.https.any_npu-expected.txt
deleted file mode 100644
index ad40ec4..0000000
--- a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gather.https.any_npu-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-[FAIL] gather float32 2D tensor and int32 0D negative indices default options
-  assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected -66.05901336669922 by ULP distance: expected a number less than or equal to 0n but got 1115954743n
-[FAIL] gather float32 2D tensor and int32 0D out-of-bound positive indices default options
-  assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected 90.2870101928711 by ULP distance: expected a number less than or equal to 0n but got 1119130355n
-[FAIL] gather float32 2D tensor and int32 0D out-of-bound negative indices default options
-  assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected -66.05901336669922 by ULP distance: expected a number less than or equal to 0n but got 1115954743n
-[FAIL] gather float16 2D tensor and int32 0D negative indices default options
-  assert_less_than_equal: assert_array_approx_equals_ulp: test gather float16 actual 0 should be close enough to expected -66.0625 by ULP distance: expected a number less than or equal to 0 but got 54305
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gatherND.https.any_npu-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gatherND.https.any_npu-expected.txt
deleted file mode 100644
index ed58e6a..0000000
--- a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gatherND.https.any_npu-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-[FAIL] gatherND float32 4D input and 1D minimum indices
-  assert_less_than_equal: assert_array_approx_equals_ulp: test gatherND float32 actual 0 should be close enough to expected -66.05901336669922 by ULP distance: expected a number less than or equal to 0n but got 1115954743n
-[FAIL] gatherND float32 2D input and 2D negative indices
-  promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': TFLite doesn't support to gather input into one dimension."
-[FAIL] gatherND float32 1D input and 2D out-of-bounds indices
-  promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': TFLite doesn't support to gather input into one dimension."
-[FAIL] gatherND float16 4D input and 1D minimum indices
-  assert_less_than_equal: assert_array_approx_equals_ulp: test gatherND float16 actual 0 should be close enough to expected -66.0625 by ULP distance: expected a number less than or equal to 0 but got 54305
-[FAIL] gatherND float16 2D input and 2D negative indices
-  promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': TFLite doesn't support to gather input into one dimension."
-Harness: the test ran to completion.
-
diff --git a/third_party/catapult b/third_party/catapult
index daf42e3..4e4076a 160000
--- a/third_party/catapult
+++ b/third_party/catapult
@@ -1 +1 @@
-Subproject commit daf42e3671a72fa6ea1ba1ef380b8fb40d7d0fe2
+Subproject commit 4e4076a0d7a836b779a094989e911a65b2a3c1ee
diff --git a/third_party/dawn b/third_party/dawn
index b322a35..fcda4f3 160000
--- a/third_party/dawn
+++ b/third_party/dawn
@@ -1 +1 @@
-Subproject commit b322a3577d95635eec4b4279de18431f119e3e5e
+Subproject commit fcda4f3d4b8c77aa0c0234d6abe629364949db97
diff --git a/third_party/depot_tools b/third_party/depot_tools
index 1b44e27..6d01946 160000
--- a/third_party/depot_tools
+++ b/third_party/depot_tools
@@ -1 +1 @@
-Subproject commit 1b44e27e7d4c63dfe83d10ed01d23824536e9811
+Subproject commit 6d019469b47bf20f564f6c1b2d7a1283a7d51efa
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src
index a69b76e7..ef0e719c 160000
--- a/third_party/devtools-frontend/src
+++ b/third_party/devtools-frontend/src
@@ -1 +1 @@
-Subproject commit a69b76e797b9aba0440520be85f0752fe35e965e
+Subproject commit ef0e719ca66bdf3c3a8767c3b4b981f4c56ba835
diff --git a/third_party/googletest/src b/third_party/googletest/src
index 32f9f4c..373af2e 160000
--- a/third_party/googletest/src
+++ b/third_party/googletest/src
@@ -1 +1 @@
-Subproject commit 32f9f4c82afa4249af66b55278df15c16b3031ea
+Subproject commit 373af2e3df71599b87a40ce0e37164523849166b
diff --git a/third_party/hunspell/BUILD.gn b/third_party/hunspell/BUILD.gn
index 0125a29..aa58f64 100644
--- a/third_party/hunspell/BUILD.gn
+++ b/third_party/hunspell/BUILD.gn
@@ -110,9 +110,6 @@
       "-Wno-null-conversion",
     ]
   }
-
-  # TODO(https://github.com/hunspell/hunspell/pull/1054): Remove this when the PR is merged.
-  use_libcxx_modules = false
 }
 
 fuzzer_test("hunspell_spell_fuzzer") {
diff --git a/third_party/hunspell/README.chromium b/third_party/hunspell/README.chromium
index 45c00967..8bffb4e2 100644
--- a/third_party/hunspell/README.chromium
+++ b/third_party/hunspell/README.chromium
@@ -1,6 +1,6 @@
 Name: hunspell
 URL: http://hunspell.sourceforge.net/
-Version: 6d7d19f
+Version: 96466a6
 Update Mechanism: Manual
 CPEPrefix: cpe:/a:hunspell_project:hunspell:1.7.2
 License: MPL-1.1
@@ -9,7 +9,7 @@
 Shipped: yes
 
 Description:
-This is a partial copy of Hunspell 6d7d19f with the following changes:
+This is a partial copy of Hunspell 96466a6 with the following changes:
 * Move README.md onto the README symlink.
 * Change src/hunspell/filemgr.hxx and src/hunspell/filemgr.cxx to use
   LineIterator.
@@ -36,7 +36,7 @@
 2) Checkout hunspell:
    $ git clone https://github.com/hunspell/hunspell.git
    $ cd hunspell
-   $ git checkout 6d7d19f
+   $ git checkout 96466a6
 3) Apply the existing patch:
    $ patch -p1 -i $CHROMIUM_HUNSPELL/google.patch
 4) Make your new changes inside the git hunspell directory.
diff --git a/third_party/hunspell/google.patch b/third_party/hunspell/google.patch
index 5c93497..f62172e7 100644
--- a/third_party/hunspell/google.patch
+++ b/third_party/hunspell/google.patch
@@ -194,7 +194,7 @@
    }
  
 diff --git a/src/hunspell/affixmgr.hxx b/src/hunspell/affixmgr.hxx
-index 0fc22a3..529077c 100644
+index 84caed1..bbc2948 100644
 --- a/src/hunspell/affixmgr.hxx
 +++ b/src/hunspell/affixmgr.hxx
 @@ -89,6 +89,40 @@
@@ -731,7 +731,7 @@
    return !aliasf.empty();
  }
 diff --git a/src/hunspell/hashmgr.hxx b/src/hunspell/hashmgr.hxx
-index 792b2f1..8590ee3 100644
+index 9e0975a..9ddf70f 100644
 --- a/src/hunspell/hashmgr.hxx
 +++ b/src/hunspell/hashmgr.hxx
 @@ -79,6 +79,13 @@
@@ -857,7 +857,7 @@
  
  #define ROTATE(v, q) \
 diff --git a/src/hunspell/hunspell.cxx b/src/hunspell/hunspell.cxx
-index 51e0937..c4a29fc 100644
+index 2bb1b94..271fa55 100644
 --- a/src/hunspell/hunspell.cxx
 +++ b/src/hunspell/hunspell.cxx
 @@ -77,21 +77,30 @@
@@ -909,7 +909,7 @@
    std::string affixpath;
 +#endif
    std::string encoding;
-   struct cs_info* csconv;
+   const struct cs_info* csconv;
    int langnum;
 @@ -140,6 +151,11 @@ private:
    int complexprefixes;
@@ -1082,7 +1082,7 @@
  int Hunspell_spell(Hunhandle* pHunspell, const char* word) {
    return reinterpret_cast<HunspellImpl*>(pHunspell)->spell(word);
 diff --git a/src/hunspell/hunspell.hxx b/src/hunspell/hunspell.hxx
-index 142017f..513c70c 100644
+index 267a745..49d3731 100644
 --- a/src/hunspell/hunspell.hxx
 +++ b/src/hunspell/hunspell.hxx
 @@ -76,6 +76,11 @@
@@ -1172,7 +1172,7 @@
  
  #include <string>
 diff --git a/src/hunspell/suggestmgr.cxx b/src/hunspell/suggestmgr.cxx
-index 5f480f9..ebffdf1 100644
+index 82b53d2..57c81a4 100644
 --- a/src/hunspell/suggestmgr.cxx
 +++ b/src/hunspell/suggestmgr.cxx
 @@ -84,7 +84,112 @@ const w_char W_VLINE = {'\0', '|'};
@@ -1356,7 +1356,7 @@
      for (j = 1; j <= n; j++) {
        if (((utf8) && (su[i - 1] == su2[j - 1])) ||
 diff --git a/src/hunspell/suggestmgr.hxx b/src/hunspell/suggestmgr.hxx
-index 7fa1a6b..369d6e3 100644
+index 0f8bcc5..b0184ff 100644
 --- a/src/hunspell/suggestmgr.hxx
 +++ b/src/hunspell/suggestmgr.hxx
 @@ -112,7 +112,11 @@ class SuggestMgr {
diff --git a/third_party/hunspell/src/hunspell/affixmgr.hxx b/third_party/hunspell/src/hunspell/affixmgr.hxx
index 529077c..bbc2948 100644
--- a/third_party/hunspell/src/hunspell/affixmgr.hxx
+++ b/third_party/hunspell/src/hunspell/affixmgr.hxx
@@ -133,7 +133,7 @@
   std::string keystring;
   std::string trystring;
   std::string encoding;
-  struct cs_info* csconv;
+  const struct cs_info* csconv;
   int utf8;
   int complexprefixes;
   FLAG compoundflag;
diff --git a/third_party/hunspell/src/hunspell/csutil.cxx b/third_party/hunspell/src/hunspell/csutil.cxx
index 4589e77..09cc3a5 100644
--- a/third_party/hunspell/src/hunspell/csutil.cxx
+++ b/third_party/hunspell/src/hunspell/csutil.cxx
@@ -74,6 +74,7 @@
 #include <cstring>
 #include <cstdio>
 #include <cctype>
+#include <iterator>
 #include <sstream>
 #if __cplusplus >= 202002L
 #include <bit>
@@ -685,7 +686,7 @@
 // encodings supported
 // supplying isupper, tolower, and toupper
 
-static struct cs_info iso1_tbl[] = {
+const struct cs_info iso1_tbl[] = {
     {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
     {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
     {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
@@ -773,7 +774,7 @@
     {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde},
     {0x00, 0xff, 0xff}};
 
-static struct cs_info iso2_tbl[] = {
+const struct cs_info iso2_tbl[] = {
     {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
     {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
     {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
@@ -861,7 +862,7 @@
     {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde},
     {0x00, 0xff, 0xff}};
 
-static struct cs_info iso3_tbl[] = {
+const struct cs_info iso3_tbl[] = {
     {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
     {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
     {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
@@ -949,7 +950,7 @@
     {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde},
     {0x00, 0xff, 0xff}};
 
-static struct cs_info iso4_tbl[] = {
+const struct cs_info iso4_tbl[] = {
     {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
     {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
     {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
@@ -1037,7 +1038,7 @@
     {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde},
     {0x00, 0xff, 0xff}};
 
-static struct cs_info iso5_tbl[] = {
+const struct cs_info iso5_tbl[] = {
     {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
     {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
     {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
@@ -1125,7 +1126,7 @@
     {0x00, 0xfc, 0xac}, {0x00, 0xfd, 0xfd}, {0x00, 0xfe, 0xae},
     {0x00, 0xff, 0xaf}};
 
-static struct cs_info iso6_tbl[] = {
+const struct cs_info iso6_tbl[] = {
     {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
     {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
     {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
@@ -1213,7 +1214,7 @@
     {0x00, 0xfc, 0xfc}, {0x00, 0xfd, 0xfd}, {0x00, 0xfe, 0xfe},
     {0x00, 0xff, 0xff}};
 
-static struct cs_info iso7_tbl[] = {
+const struct cs_info iso7_tbl[] = {
     {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
     {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
     {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
@@ -1301,7 +1302,7 @@
     {0x00, 0xfc, 0xbc}, {0x00, 0xfd, 0xbe}, {0x00, 0xfe, 0xbf},
     {0x00, 0xff, 0xff}};
 
-static struct cs_info iso8_tbl[] = {
+const struct cs_info iso8_tbl[] = {
     {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
     {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
     {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
@@ -1389,7 +1390,7 @@
     {0x00, 0xfc, 0xfc}, {0x00, 0xfd, 0xfd}, {0x00, 0xfe, 0xfe},
     {0x00, 0xff, 0xff}};
 
-static struct cs_info iso9_tbl[] = {
+const struct cs_info iso9_tbl[] = {
     {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
     {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
     {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
@@ -1477,7 +1478,7 @@
     {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0x49}, {0x00, 0xfe, 0xde},
     {0x00, 0xff, 0xff}};
 
-static struct cs_info iso10_tbl[] = {
+const struct cs_info iso10_tbl[] = {
     {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
     {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
     {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
@@ -1565,7 +1566,7 @@
     {0x00, 0xfc, 0xfc}, {0x00, 0xfd, 0xfd}, {0x00, 0xfe, 0xfe},
     {0x00, 0xff, 0xff}};
 
-static struct cs_info koi8r_tbl[] = {
+const struct cs_info koi8r_tbl[] = {
     {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
     {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
     {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
@@ -1653,7 +1654,7 @@
     {0x01, 0xdc, 0xfc}, {0x01, 0xdd, 0xfd}, {0x01, 0xde, 0xfe},
     {0x01, 0xdf, 0xff}};
 
-static struct cs_info koi8u_tbl[] = {
+const struct cs_info koi8u_tbl[] = {
     {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
     {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
     {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
@@ -1743,7 +1744,7 @@
     {0x01, 0xda, 0xfa}, {0x01, 0xdb, 0xfb}, {0x01, 0xdc, 0xfc},
     {0x01, 0xdd, 0xfd}, {0x01, 0xde, 0xfe}, {0x01, 0xdf, 0xff}};
 
-static struct cs_info cp1251_tbl[] = {
+const struct cs_info cp1251_tbl[] = {
     {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
     {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
     {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
@@ -1831,7 +1832,7 @@
     {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde},
     {0x00, 0xff, 0xdf}};
 
-static struct cs_info iso13_tbl[] = {
+const struct cs_info iso13_tbl[] = {
     {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
     {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
     {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
@@ -1919,7 +1920,7 @@
     {0x00, 0xFC, 0xDC}, {0x00, 0xFD, 0xDD}, {0x00, 0xFE, 0xDE},
     {0x00, 0xFF, 0xFF}};
 
-static struct cs_info iso14_tbl[] = {
+const struct cs_info iso14_tbl[] = {
     {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
     {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
     {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
@@ -2007,7 +2008,7 @@
     {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde},
     {0x00, 0xff, 0xff}};
 
-static struct cs_info iso15_tbl[] = {
+const struct cs_info iso15_tbl[] = {
     {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
     {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
     {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
@@ -2095,7 +2096,7 @@
     {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde},
     {0x00, 0xff, 0xbe}};
 
-static struct cs_info iscii_devanagari_tbl[] = {
+const struct cs_info iscii_devanagari_tbl[] = {
     {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
     {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
     {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
@@ -2183,7 +2184,7 @@
     {0x00, 0xfc, 0xfc}, {0x00, 0xfd, 0xfd}, {0x00, 0xfe, 0xfe},
     {0x00, 0xff, 0xff}};
 
-static struct cs_info tis620_tbl[] = {
+const struct cs_info tis620_tbl[] = {
     {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02},
     {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05},
     {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08},
@@ -2273,10 +2274,10 @@
 
 struct enc_entry {
   const char* enc_name;
-  struct cs_info* cs_table;
+  const struct cs_info* cs_table;
 };
 
-static struct enc_entry encds[] = {
+const struct enc_entry encds[] = {
     {"iso88591", iso1_tbl},  // ISO-8859-1
     {"iso88592", iso2_tbl},  // ISO-8859-2
     {"iso88593", iso3_tbl},  // ISO-8859-3
@@ -2323,11 +2324,11 @@
   *pBuf = '\0';
 }
 
-struct cs_info* get_current_cs(const std::string& es) {
+const struct cs_info* get_current_cs(const std::string& es) {
   char* normalized_encoding = new char[es.size() + 1];
   toAsciiLowerAndRemoveNonAlphanumeric(es.c_str(), normalized_encoding);
 
-  struct cs_info* ccs = NULL;
+  const struct cs_info* ccs = NULL;
   for (const auto& encd : encds) {
     if (strcmp(normalized_encoding, encd.enc_name) == 0) {
       ccs = encd.cs_table;
@@ -2350,7 +2351,7 @@
 // XXX This function was rewritten for mozilla. Instead of storing the
 // conversion tables static in this file, create them when needed
 // with help the mozilla backend.
-struct cs_info* get_current_cs(const std::string& es) {
+const struct cs_info* get_current_cs(const std::string& es) {
   struct cs_info* ccs = new cs_info[256];
   // Initialze the array with dummy data so that we wouldn't need
   // to return null in case of failures.
@@ -2437,7 +2438,7 @@
 
 // primitive isalpha() replacement for tokenization
 std::string get_casechars(const char* enc) {
-  struct cs_info* csconv = get_current_cs(enc);
+  const struct cs_info* csconv = get_current_cs(enc);
   std::string expw;
   for (int i = 0; i <= 255; ++i) {
     if (cupper(csconv, i) != clower(csconv, i)) {
@@ -2457,7 +2458,7 @@
   int num;
 };
 
-static struct lang_map lang2enc[] =
+const struct lang_map lang2enc[] =
     {{"ar", LANG_ar},    {"az", LANG_az},
      {"az_AZ", LANG_az},  // for back-compatibility
      {"bg", LANG_bg},    {"ca", LANG_ca},
@@ -2527,7 +2528,7 @@
 }
 
 /* get type of capitalization */
-int get_captype(const std::string& word, cs_info* csconv) {
+int get_captype(const std::string& word, const cs_info* csconv) {
   // now determine the capitalization type of the first nl letters
   size_t ncap = 0;
   size_t nneutral = 0;
diff --git a/third_party/hunspell/src/hunspell/csutil.hxx b/third_party/hunspell/src/hunspell/csutil.hxx
index 808087d1f..fd11266 100644
--- a/third_party/hunspell/src/hunspell/csutil.hxx
+++ b/third_party/hunspell/src/hunspell/csutil.hxx
@@ -189,7 +189,7 @@
                                                        int langnum);
 LIBHUNSPELL_DLL_EXPORTED int unicodeisalpha(unsigned short c);
 
-LIBHUNSPELL_DLL_EXPORTED struct cs_info* get_current_cs(const std::string& es);
+LIBHUNSPELL_DLL_EXPORTED const struct cs_info* get_current_cs(const std::string& es);
 
 // get language identifiers of language codes
 LIBHUNSPELL_DLL_EXPORTED int get_lang_num(const std::string& lang);
@@ -230,7 +230,7 @@
 mkallcap_utf(std::vector<w_char>& u, int langnum);
 
 // get type of capitalization
-LIBHUNSPELL_DLL_EXPORTED int get_captype(const std::string& q, cs_info*);
+LIBHUNSPELL_DLL_EXPORTED int get_captype(const std::string& q, const cs_info*);
 
 // get type of capitalization (UTF-8)
 LIBHUNSPELL_DLL_EXPORTED int get_captype_utf8(const std::vector<w_char>& q, int langnum);
diff --git a/third_party/hunspell/src/hunspell/hashmgr.hxx b/third_party/hunspell/src/hunspell/hashmgr.hxx
index 8590ee3..9ddf70fc 100644
--- a/third_party/hunspell/src/hunspell/hashmgr.hxx
+++ b/third_party/hunspell/src/hunspell/hashmgr.hxx
@@ -109,7 +109,7 @@
   int langnum;
   std::string enc;
   std::string lang;
-  struct cs_info* csconv;
+  const struct cs_info* csconv;
   std::string ignorechars;
   std::vector<w_char> ignorechars_utf16;
   std::vector<unsigned short*> aliasf; // flag vector `compression' with aliases
diff --git a/third_party/hunspell/src/hunspell/hunspell.cxx b/third_party/hunspell/src/hunspell/hunspell.cxx
index c4a29fc..271fa55 100644
--- a/third_party/hunspell/src/hunspell/hunspell.cxx
+++ b/third_party/hunspell/src/hunspell/hunspell.cxx
@@ -121,7 +121,7 @@
   int add_with_affix(const std::string& word, const std::string& example);
   int remove(const std::string& word);
   const std::string& get_version_cpp() const;
-  struct cs_info* get_csconv();
+  const struct cs_info* get_csconv() const;
 
   int spell(const char* word, int* info = NULL, char** root = NULL);
   int suggest(char*** slst, const char* word);
@@ -145,7 +145,7 @@
   std::string affixpath;
 #endif
   std::string encoding;
-  struct cs_info* csconv;
+  const struct cs_info* csconv;
   int langnum;
   int utf8;
   int complexprefixes;
@@ -1558,7 +1558,7 @@
   return pAMgr->get_version();
 }
 
-struct cs_info* HunspellImpl::get_csconv() {
+const struct cs_info* HunspellImpl::get_csconv() const {
   return csconv;
 }
 
@@ -2246,7 +2246,7 @@
   return m_Impl->get_version_cpp();
 }
 
-struct cs_info* Hunspell::get_csconv() {
+const struct cs_info* Hunspell::get_csconv() const {
   return m_Impl->get_csconv();
 }
 
diff --git a/third_party/hunspell/src/hunspell/hunspell.hxx b/third_party/hunspell/src/hunspell/hunspell.hxx
index 513c70c..49d3731 100644
--- a/third_party/hunspell/src/hunspell/hunspell.hxx
+++ b/third_party/hunspell/src/hunspell/hunspell.hxx
@@ -228,7 +228,7 @@
   const std::string& get_wordchars_cpp() const;
   const std::vector<w_char>& get_wordchars_utf16() const;
 
-  struct cs_info* get_csconv();
+  const struct cs_info* get_csconv() const;
   
   const char* get_version() const;
   const std::string& get_version_cpp() const;
diff --git a/third_party/hunspell/src/hunspell/suggestmgr.cxx b/third_party/hunspell/src/hunspell/suggestmgr.cxx
index ebffdf1..57c81a44 100644
--- a/third_party/hunspell/src/hunspell/suggestmgr.cxx
+++ b/third_party/hunspell/src/hunspell/suggestmgr.cxx
@@ -1257,13 +1257,13 @@
   class ngsuggest_guard
   {
     bool m_nonbmp;
-    cs_info* m_origconv;
+    const cs_info* m_origconv;
     int* m_utf8;
-    cs_info** m_csconv;
+    const cs_info** m_csconv;
 
     public:
 
-    ngsuggest_guard(bool nonbmp, cs_info* origconv, int* utf8, cs_info** csconv)
+    ngsuggest_guard(bool nonbmp, const cs_info* origconv, int* utf8, const cs_info** csconv)
       : m_nonbmp(nonbmp)
       , m_origconv(origconv)
       , m_utf8(utf8)
@@ -1328,7 +1328,7 @@
 
   // set character based ngram suggestion for words with non-BMP Unicode
   // characters
-  struct cs_info* origconv = csconv;
+  const struct cs_info* origconv = csconv;
   if (n == -1) {
     utf8 = 0;  // XXX not state-free
     if (!csconv)
diff --git a/third_party/hunspell/src/hunspell/suggestmgr.hxx b/third_party/hunspell/src/hunspell/suggestmgr.hxx
index 369d6e3d..b0184ff 100644
--- a/third_party/hunspell/src/hunspell/suggestmgr.hxx
+++ b/third_party/hunspell/src/hunspell/suggestmgr.hxx
@@ -103,7 +103,7 @@
 
   AffixMgr* pAMgr;
   unsigned int maxSug;
-  struct cs_info* csconv;
+  const struct cs_info* csconv;
   int utf8;
   int langnum;
   int nosplitsugs;
diff --git a/third_party/libc++abi/src b/third_party/libc++abi/src
index 00a1750..a6c815c6 160000
--- a/third_party/libc++abi/src
+++ b/third_party/libc++abi/src
@@ -1 +1 @@
-Subproject commit 00a175050b73903b2f00e460dd2c9751c4a0fd88
+Subproject commit a6c815c69d55ec59d020abde636754d120b402ad
diff --git a/third_party/llvm-libc/src b/third_party/llvm-libc/src
index f24be5d..14ca6ad 160000
--- a/third_party/llvm-libc/src
+++ b/third_party/llvm-libc/src
@@ -1 +1 @@
-Subproject commit f24be5deb774fae412aae70877b47fa6fcf19d28
+Subproject commit 14ca6ad7d68c47a6b7c18d53a6c69d4fa3a27571
diff --git a/third_party/rust/chromium_crates_io/Cargo.lock b/third_party/rust/chromium_crates_io/Cargo.lock
index 094097ac..d250a7bd 100644
--- a/third_party/rust/chromium_crates_io/Cargo.lock
+++ b/third_party/rust/chromium_crates_io/Cargo.lock
@@ -885,7 +885,7 @@
 
 [[package]]
 name = "serde_json"
-version = "1.0.140"
+version = "1.0.141"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "indexmap",
diff --git a/third_party/rust/chromium_crates_io/supply-chain/config.toml b/third_party/rust/chromium_crates_io/supply-chain/config.toml
index e43f140..0a85c0a 100644
--- a/third_party/rust/chromium_crates_io/supply-chain/config.toml
+++ b/third_party/rust/chromium_crates_io/supply-chain/config.toml
@@ -341,7 +341,7 @@
 [policy."serde_derive:1.0.219"]
 criteria = ["crypto-safe", "safe-to-deploy", "ub-risk-2"]
 
-[policy."serde_json:1.0.140"]
+[policy."serde_json:1.0.141"]
 criteria = ["crypto-safe", "safe-to-deploy", "ub-risk-2"]
 
 [policy."serde_json_lenient:0.2.4"]
diff --git a/third_party/rust/chromium_crates_io/vendor/serde_json-v1/.cargo_vcs_info.json b/third_party/rust/chromium_crates_io/vendor/serde_json-v1/.cargo_vcs_info.json
index 75e01f9d2..3bdbde9 100644
--- a/third_party/rust/chromium_crates_io/vendor/serde_json-v1/.cargo_vcs_info.json
+++ b/third_party/rust/chromium_crates_io/vendor/serde_json-v1/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "762783414e6c4f8d670c9d87eb04913efb80d3be"
+    "sha1": "6843c3660ec3394b15da016902e001f8381dfe92"
   },
   "path_in_vcs": ""
 }
\ No newline at end of file
diff --git a/third_party/rust/chromium_crates_io/vendor/serde_json-v1/.github/workflows/ci.yml b/third_party/rust/chromium_crates_io/vendor/serde_json-v1/.github/workflows/ci.yml
index 77d611a..340b652 100644
--- a/third_party/rust/chromium_crates_io/vendor/serde_json-v1/.github/workflows/ci.yml
+++ b/third_party/rust/chromium_crates_io/vendor/serde_json-v1/.github/workflows/ci.yml
@@ -106,6 +106,8 @@
     steps:
       - uses: actions/checkout@v4
       - uses: dtolnay/rust-toolchain@miri
+        with:
+          toolchain: nightly-2025-05-16  # https://github.com/rust-lang/miri/issues/4323
       - run: cargo miri setup
       - run: cargo miri test --target ${{matrix.target}}
       - run: cargo miri test --target ${{matrix.target}} --features preserve_order,float_roundtrip,arbitrary_precision,raw_value
diff --git a/third_party/rust/chromium_crates_io/vendor/serde_json-v1/Cargo.lock b/third_party/rust/chromium_crates_io/vendor/serde_json-v1/Cargo.lock
index 4f20a2ef..f46206b 100644
--- a/third_party/rust/chromium_crates_io/vendor/serde_json-v1/Cargo.lock
+++ b/third_party/rust/chromium_crates_io/vendor/serde_json-v1/Cargo.lock
@@ -4,9 +4,9 @@
 
 [[package]]
 name = "automod"
-version = "1.0.14"
+version = "1.0.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edf3ee19dbc0a46d740f6f0926bde8c50f02bdbc7b536842da28f6ac56513a8b"
+checksum = "ebb4bd301db2e2ca1f5be131c24eb8ebf2d9559bc3744419e93baf8ddea7e670"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -15,24 +15,24 @@
 
 [[package]]
 name = "cc"
-version = "1.2.16"
+version = "1.2.30"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c"
+checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7"
 dependencies = [
  "shlex",
 ]
 
 [[package]]
 name = "cfg-if"
-version = "1.0.0"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
 
 [[package]]
 name = "dissimilar"
-version = "1.0.9"
+version = "1.0.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d"
+checksum = "8975ffdaa0ef3661bfe02dbdcc06c9f829dfafe6a3c474de366a8d5e44276921"
 
 [[package]]
 name = "equivalent"
@@ -48,15 +48,15 @@
 
 [[package]]
 name = "hashbrown"
-version = "0.15.2"
+version = "0.15.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
+checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
 
 [[package]]
 name = "indexmap"
-version = "2.7.1"
+version = "2.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
+checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661"
 dependencies = [
  "equivalent",
  "hashbrown",
@@ -64,51 +64,51 @@
 
 [[package]]
 name = "indoc"
-version = "2.0.5"
+version = "2.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
+checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
 
 [[package]]
 name = "itoa"
-version = "1.0.14"
+version = "1.0.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
+checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
 
 [[package]]
 name = "libc"
-version = "0.2.170"
+version = "0.2.174"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
+checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
 
 [[package]]
 name = "memchr"
-version = "2.7.4"
+version = "2.7.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.94"
+version = "1.0.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
 dependencies = [
  "unicode-ident",
 ]
 
 [[package]]
 name = "psm"
-version = "0.1.25"
+version = "0.1.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f58e5423e24c18cc840e1c98370b3993c6649cd1678b4d24318bcf0a083cbe88"
+checksum = "6e944464ec8536cd1beb0bbfd96987eb5e3b72f2ecdafdc5c769a37f1fa2ae1f"
 dependencies = [
  "cc",
 ]
 
 [[package]]
 name = "quote"
-version = "1.0.39"
+version = "1.0.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
 dependencies = [
  "proc-macro2",
 ]
@@ -135,39 +135,39 @@
 
 [[package]]
 name = "rustversion"
-version = "1.0.19"
+version = "1.0.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
+checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
 
 [[package]]
 name = "ryu"
-version = "1.0.19"
+version = "1.0.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
+checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
 
 [[package]]
 name = "serde"
-version = "1.0.218"
+version = "1.0.219"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60"
+checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_bytes"
-version = "0.11.16"
+version = "0.11.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "364fec0df39c49a083c9a8a18a23a6bcfd9af130fe9fe321d18520a0d113e09e"
+checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96"
 dependencies = [
  "serde",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.218"
+version = "1.0.219"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b"
+checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -176,9 +176,9 @@
 
 [[package]]
 name = "serde_json"
-version = "1.0.139"
+version = "1.0.140"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6"
+checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
 dependencies = [
  "itoa",
  "memchr",
@@ -188,7 +188,7 @@
 
 [[package]]
 name = "serde_json"
-version = "1.0.140"
+version = "1.0.141"
 dependencies = [
  "automod",
  "indexmap",
@@ -207,9 +207,9 @@
 
 [[package]]
 name = "serde_spanned"
-version = "0.6.8"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
+checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83"
 dependencies = [
  "serde",
 ]
@@ -232,9 +232,9 @@
 
 [[package]]
 name = "stacker"
-version = "0.1.19"
+version = "0.1.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9156ebd5870ef293bfb43f91c7a74528d363ec0d424afe24160ed5a4343d08a"
+checksum = "cddb07e32ddb770749da91081d8d0ac3a16f1a569a18b20348cd371f5dead06b"
 dependencies = [
  "cc",
  "cfg-if",
@@ -245,9 +245,9 @@
 
 [[package]]
 name = "syn"
-version = "2.0.99"
+version = "2.0.104"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e02e925281e18ffd9d640e234264753c43edc62d64b2d4cf898f1bc5e75f3fc2"
+checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -271,49 +271,54 @@
 
 [[package]]
 name = "toml"
-version = "0.8.20"
+version = "0.9.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148"
-dependencies = [
- "serde",
- "serde_spanned",
- "toml_datetime",
- "toml_edit",
-]
-
-[[package]]
-name = "toml_datetime"
-version = "0.6.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "toml_edit"
-version = "0.22.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474"
+checksum = "ed0aee96c12fa71097902e0bb061a5e1ebd766a6636bb605ba401c45c1650eac"
 dependencies = [
  "indexmap",
  "serde",
  "serde_spanned",
  "toml_datetime",
+ "toml_parser",
+ "toml_writer",
  "winnow",
 ]
 
 [[package]]
-name = "trybuild"
-version = "1.0.103"
+name = "toml_datetime"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b812699e0c4f813b872b373a4471717d9eb550da14b311058a4d9cf4173cbca6"
+checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "toml_parser"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97200572db069e74c512a14117b296ba0a80a30123fbbb5aa1f4a348f639ca30"
+dependencies = [
+ "winnow",
+]
+
+[[package]]
+name = "toml_writer"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64"
+
+[[package]]
+name = "trybuild"
+version = "1.0.106"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "65af40ad689f2527aebbd37a0a816aea88ff5f774ceabe99de5be02f2f91dae2"
 dependencies = [
  "dissimilar",
  "glob",
  "serde",
  "serde_derive",
- "serde_json 1.0.139",
+ "serde_json 1.0.140",
  "target-triple",
  "termcolor",
  "toml",
@@ -321,9 +326,9 @@
 
 [[package]]
 name = "unicode-ident"
-version = "1.0.17"
+version = "1.0.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
 
 [[package]]
 name = "winapi-util"
@@ -409,9 +414,6 @@
 
 [[package]]
 name = "winnow"
-version = "0.7.3"
+version = "0.7.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1"
-dependencies = [
- "memchr",
-]
+checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95"
diff --git a/third_party/rust/chromium_crates_io/vendor/serde_json-v1/Cargo.toml b/third_party/rust/chromium_crates_io/vendor/serde_json-v1/Cargo.toml
index 2fa24f5e..ebf1e6de 100644
--- a/third_party/rust/chromium_crates_io/vendor/serde_json-v1/Cargo.toml
+++ b/third_party/rust/chromium_crates_io/vendor/serde_json-v1/Cargo.toml
@@ -13,7 +13,7 @@
 edition = "2021"
 rust-version = "1.56"
 name = "serde_json"
-version = "1.0.140"
+version = "1.0.141"
 authors = [
     "Erick Tryzelaar <erick.tryzelaar@gmail.com>",
     "David Tolnay <dtolnay@gmail.com>",
@@ -46,13 +46,13 @@
     "raw_value",
     "unbounded_depth",
 ]
+targets = ["x86_64-unknown-linux-gnu"]
 rustdoc-args = [
     "--generate-link-to-definition",
     "--extern-html-root-url=core=https://doc.rust-lang.org",
     "--extern-html-root-url=alloc=https://doc.rust-lang.org",
     "--extern-html-root-url=std=https://doc.rust-lang.org",
 ]
-targets = ["x86_64-unknown-linux-gnu"]
 
 [package.metadata.playground]
 features = [
diff --git a/third_party/rust/chromium_crates_io/vendor/serde_json-v1/Cargo.toml.orig b/third_party/rust/chromium_crates_io/vendor/serde_json-v1/Cargo.toml.orig
index 866c313..67794cd 100644
--- a/third_party/rust/chromium_crates_io/vendor/serde_json-v1/Cargo.toml.orig
+++ b/third_party/rust/chromium_crates_io/vendor/serde_json-v1/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "serde_json"
-version = "1.0.140"
+version = "1.0.141"
 authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
 categories = ["encoding", "parser-implementations", "no-std"]
 description = "A JSON serialization file format"
diff --git a/third_party/rust/chromium_crates_io/vendor/serde_json-v1/src/lib.rs b/third_party/rust/chromium_crates_io/vendor/serde_json-v1/src/lib.rs
index a9f82f2..5223afb 100644
--- a/third_party/rust/chromium_crates_io/vendor/serde_json-v1/src/lib.rs
+++ b/third_party/rust/chromium_crates_io/vendor/serde_json-v1/src/lib.rs
@@ -299,7 +299,7 @@
 //! [macro]: crate::json
 //! [`serde-json-core`]: https://github.com/rust-embedded-community/serde-json-core
 
-#![doc(html_root_url = "https://docs.rs/serde_json/1.0.140")]
+#![doc(html_root_url = "https://docs.rs/serde_json/1.0.141")]
 // Ignored clippy lints
 #![allow(
     clippy::collapsible_else_if,
@@ -366,6 +366,7 @@
 #![deny(missing_docs)]
 #![no_std]
 #![cfg_attr(docsrs, feature(doc_cfg))]
+#![allow(unknown_lints, mismatched_lifetime_syntaxes)]
 
 #[cfg(not(any(feature = "std", feature = "alloc")))]
 compile_error! {
diff --git a/third_party/rust/chromium_crates_io/vendor/serde_json-v1/src/read.rs b/third_party/rust/chromium_crates_io/vendor/serde_json-v1/src/read.rs
index 0748af4..f90d9f7 100644
--- a/third_party/rust/chromium_crates_io/vendor/serde_json-v1/src/read.rs
+++ b/third_party/rust/chromium_crates_io/vendor/serde_json-v1/src/read.rs
@@ -984,7 +984,7 @@
     scratch.reserve(4);
 
     // SAFETY: After the `reserve` call, `scratch` has at least 4 bytes of
-    // allocated but unintialized memory after its last initialized byte, which
+    // allocated but uninitialized memory after its last initialized byte, which
     // is where `ptr` points. All reachable match arms write `encoded_len` bytes
     // to that region and update the length accordingly, and `encoded_len` is
     // always <= 4.
diff --git a/third_party/rust/chromium_crates_io/vendor/serde_json-v1/src/ser.rs b/third_party/rust/chromium_crates_io/vendor/serde_json-v1/src/ser.rs
index 9b14389..de78b34e 100644
--- a/third_party/rust/chromium_crates_io/vendor/serde_json-v1/src/ser.rs
+++ b/third_party/rust/chromium_crates_io/vendor/serde_json-v1/src/ser.rs
@@ -7,7 +7,9 @@
 use alloc::string::ToString;
 use alloc::vec::Vec;
 use core::fmt::{self, Display};
+use core::hint;
 use core::num::FpCategory;
+use core::str;
 use serde::ser::{self, Impossible, Serialize};
 
 /// A structure for serializing Rust values into JSON.
@@ -1534,23 +1536,6 @@
     AsciiControl(u8),
 }
 
-impl CharEscape {
-    #[inline]
-    fn from_escape_table(escape: u8, byte: u8) -> CharEscape {
-        match escape {
-            self::BB => CharEscape::Backspace,
-            self::TT => CharEscape::Tab,
-            self::NN => CharEscape::LineFeed,
-            self::FF => CharEscape::FormFeed,
-            self::RR => CharEscape::CarriageReturn,
-            self::QU => CharEscape::Quote,
-            self::BS => CharEscape::ReverseSolidus,
-            self::UU => CharEscape::AsciiControl(byte),
-            _ => unreachable!(),
-        }
-    }
-}
-
 /// This trait abstracts away serializing the JSON control characters, which allows the user to
 /// optionally pretty print the JSON output.
 pub trait Formatter {
@@ -1784,30 +1769,33 @@
     {
         use self::CharEscape::*;
 
-        let s = match char_escape {
-            Quote => b"\\\"",
-            ReverseSolidus => b"\\\\",
-            Solidus => b"\\/",
-            Backspace => b"\\b",
-            FormFeed => b"\\f",
-            LineFeed => b"\\n",
-            CarriageReturn => b"\\r",
-            Tab => b"\\t",
+        let escape_char = match char_escape {
+            Quote => b'"',
+            ReverseSolidus => b'\\',
+            Solidus => b'/',
+            Backspace => b'b',
+            FormFeed => b'f',
+            LineFeed => b'n',
+            CarriageReturn => b'r',
+            Tab => b't',
+            AsciiControl(_) => b'u',
+        };
+
+        match char_escape {
             AsciiControl(byte) => {
                 static HEX_DIGITS: [u8; 16] = *b"0123456789abcdef";
                 let bytes = &[
                     b'\\',
-                    b'u',
+                    escape_char,
                     b'0',
                     b'0',
                     HEX_DIGITS[(byte >> 4) as usize],
                     HEX_DIGITS[(byte & 0xF) as usize],
                 ];
-                return writer.write_all(bytes);
+                writer.write_all(bytes)
             }
-        };
-
-        writer.write_all(s)
+            _ => writer.write_all(&[b'\\', escape_char]),
+        }
     }
 
     /// Writes the representation of a byte array. Formatters can choose whether
@@ -2097,31 +2085,51 @@
     W: ?Sized + io::Write,
     F: ?Sized + Formatter,
 {
-    let bytes = value.as_bytes();
+    let mut bytes = value.as_bytes();
 
-    let mut start = 0;
+    let mut i = 0;
+    while i < bytes.len() {
+        let (string_run, rest) = bytes.split_at(i);
+        let (&byte, rest) = rest.split_first().unwrap();
 
-    for (i, &byte) in bytes.iter().enumerate() {
         let escape = ESCAPE[byte as usize];
+
+        i += 1;
         if escape == 0 {
             continue;
         }
 
-        if start < i {
-            tri!(formatter.write_string_fragment(writer, &value[start..i]));
+        bytes = rest;
+        i = 0;
+
+        // Safety: string_run is a valid utf8 string, since we only split on ascii sequences
+        let string_run = unsafe { str::from_utf8_unchecked(string_run) };
+        if !string_run.is_empty() {
+            tri!(formatter.write_string_fragment(writer, string_run));
         }
 
-        let char_escape = CharEscape::from_escape_table(escape, byte);
+        let char_escape = match escape {
+            self::BB => CharEscape::Backspace,
+            self::TT => CharEscape::Tab,
+            self::NN => CharEscape::LineFeed,
+            self::FF => CharEscape::FormFeed,
+            self::RR => CharEscape::CarriageReturn,
+            self::QU => CharEscape::Quote,
+            self::BS => CharEscape::ReverseSolidus,
+            self::UU => CharEscape::AsciiControl(byte),
+            // Safety: the escape table does not contain any other type of character.
+            _ => unsafe { hint::unreachable_unchecked() },
+        };
         tri!(formatter.write_char_escape(writer, char_escape));
-
-        start = i + 1;
     }
 
-    if start == bytes.len() {
+    // Safety: bytes is a valid utf8 string, since we only split on ascii sequences
+    let string_run = unsafe { str::from_utf8_unchecked(bytes) };
+    if string_run.is_empty() {
         return Ok(());
     }
 
-    formatter.write_string_fragment(writer, &value[start..])
+    formatter.write_string_fragment(writer, string_run)
 }
 
 const BB: u8 = b'b'; // \x08
diff --git a/third_party/rust/serde_json/v1/BUILD.gn b/third_party/rust/serde_json/v1/BUILD.gn
index dc4e87a..e071289 100644
--- a/third_party/rust/serde_json/v1/BUILD.gn
+++ b/third_party/rust/serde_json/v1/BUILD.gn
@@ -61,7 +61,7 @@
   cargo_pkg_name = "serde_json"
   cargo_pkg_description = "A JSON serialization file format"
   cargo_pkg_repository = "https://github.com/serde-rs/json"
-  cargo_pkg_version = "1.0.140"
+  cargo_pkg_version = "1.0.141"
 
   allow_unsafe = true
 
diff --git a/third_party/rust/serde_json/v1/README.chromium b/third_party/rust/serde_json/v1/README.chromium
index 689d8723..a7318511 100644
--- a/third_party/rust/serde_json/v1/README.chromium
+++ b/third_party/rust/serde_json/v1/README.chromium
@@ -1,7 +1,7 @@
 Name: serde_json
 URL: https://crates.io/crates/serde_json
-Version: 1.0.140
-Revision: 762783414e6c4f8d670c9d87eb04913efb80d3be
+Version: 1.0.141
+Revision: 6843c3660ec3394b15da016902e001f8381dfe92
 Update Mechanism: Manual
 License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/serde_json-v1/LICENSE-APACHE
diff --git a/third_party/skia b/third_party/skia
index cdd8212..d30c79c 160000
--- a/third_party/skia
+++ b/third_party/skia
@@ -1 +1 @@
-Subproject commit cdd82125aabea8e9970f42b0fb55d104bc371520
+Subproject commit d30c79cd9594d24c87235250346dfa6b8503c28a
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 307ef31..b9f6b0c 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -4596,7 +4596,8 @@
   <int value="8" label="kRequestCancelledByRenderer"/>
   <int value="9" label="kRequestCancelledAfterTimeLimit"/>
   <int value="10" label="kBrowserShutdown"/>
-  <int value="11" label="kLoaderComplated"/>
+  <int value="11" label="kLoaderCompleted"/>
+  <int value="12" label="kRequestRetried"/>
 </enum>
 
 <!-- LINT.ThenChange(//content/public/browser/keep_alive_request_tracker.h:RequestStageType) -->
@@ -11562,6 +11563,7 @@
   <int value="-941056354" label="CdmStorageDatabase:enabled"/>
   <int value="-940931658" label="UseDMSAAForTilesAndroidGL:disabled"/>
   <int value="-940915510" label="IgnoreCSPInWebPaymentAPI:disabled"/>
+  <int value="-940438586" label="Webium:enabled"/>
   <int value="-940390151" label="RoundedDisplay:disabled"/>
   <int value="-939676447" label="CrostiniResetLxdDb:enabled"/>
   <int value="-939519091" label="TabStateFlatBuffer:disabled"/>
@@ -13800,6 +13802,7 @@
   <int value="-107856449"
       label="RequestDesktopSiteExceptionsDowngrade:enabled"/>
   <int value="-107735009" label="AndroidGoogleSansText:disabled"/>
+  <int value="-106870929" label="Webium:disabled"/>
   <int value="-106676514" label="LensOverlayEntrypointLabelAlt:enabled"/>
   <int value="-106631643" label="TurnOffStreamingMediaCachingAlways:disabled"/>
   <int value="-106373261" label="PaintPreviewDemo:enabled"/>
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml
index 4ccd5fd9..27b8b8ff 100644
--- a/tools/metrics/histograms/metadata/android/histograms.xml
+++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -1017,7 +1017,7 @@
 </histogram>
 
 <histogram name="Android.BackPress.MinimizeAppAndCloseTab"
-    enum="MinimizeAppAndCloseTabType" expires_after="M143">
+    enum="MinimizeAppAndCloseTabType" expires_after="2026-01-25">
   <owner>lazzzis@chromium.org</owner>
   <owner>src/chrome/browser/back_press/android/OWNERS</owner>
   <summary>
@@ -1027,7 +1027,7 @@
 </histogram>
 
 <histogram name="Android.BackPress.MinimizeAppAndCloseTab.CustomTab.{Task}"
-    enum="MinimizeAppAndCloseTabType" expires_after="M143">
+    enum="MinimizeAppAndCloseTabType" expires_after="2026-01-25">
   <owner>lazzzis@chromium.org</owner>
   <owner>src/chrome/browser/back_press/android/OWNERS</owner>
   <summary>
@@ -1237,7 +1237,7 @@
 </histogram>
 
 <histogram name="Android.ChildProcessConectionEventCounts"
-    enum="AndroidChildProcessConnectionEvents" expires_after="M143">
+    enum="AndroidChildProcessConnectionEvents" expires_after="2026-01-25">
   <owner>boliu@chromium.org</owner>
   <owner>yfriedman@chromium.org</owner>
   <summary>
@@ -1250,7 +1250,7 @@
 </histogram>
 
 <histogram name="Android.ChildProcessConnection.OnServiceConnectedCounts"
-    units="count" expires_after="M143">
+    units="count" expires_after="2026-01-25">
   <owner>boliu@chromium.org</owner>
   <owner>kawasin@chromium.org</owner>
   <owner>yfriedman@chromium.org</owner>
@@ -1265,7 +1265,7 @@
 </histogram>
 
 <histogram name="Android.ChildProcessRanking.{RankType}.Count" units="count"
-    expires_after="2025-11-02">
+    expires_after="2026-01-25">
   <owner>kawasin@google.com</owner>
   <owner>clank-performance-team@google.com</owner>
   <summary>
@@ -1725,7 +1725,7 @@
 </histogram>
 
 <histogram name="Android.DragDrop.FromWebContent.DropInWebContent.Duration"
-    units="ms" expires_after="2025-11-23">
+    units="ms" expires_after="2026-01-25">
   <owner>wenyufu@chromium.org</owner>
   <owner>clank-large-form-factors@google.com</owner>
   <summary>
@@ -1999,7 +1999,7 @@
 </histogram>
 
 <histogram name="Android.EdgeToEdge.Debugging.ConfigurationSwitchOutcome"
-    enum="EdgeToEdgeConfigurationSwitchOutcome" expires_after="2025-11-23">
+    enum="EdgeToEdgeConfigurationSwitchOutcome" expires_after="2026-01-25">
   <owner>clhager@google.com</owner>
   <owner>wenyufu@chromium.org</owner>
   <owner>edge-to-edge@chromium.org</owner>
@@ -2025,7 +2025,7 @@
 </histogram>
 
 <histogram name="Android.EdgeToEdge.DrawToEdgeInUnsupportedConfiguration"
-    enum="Boolean" expires_after="2025-11-23">
+    enum="Boolean" expires_after="2026-01-25">
   <owner>clhager@google.com</owner>
   <owner>wenyufu@chromium.org</owner>
   <owner>edge-to-edge@chromium.org</owner>
@@ -2676,7 +2676,7 @@
 </histogram>
 
 <histogram name="Android.InputOnViz.Viz.DroppedNonTouchActions"
-    enum="MotionEventAction" expires_after="2025-11-23">
+    enum="MotionEventAction" expires_after="2026-01-25">
   <owner>kartarsingh@google.com</owner>
   <owner>woa-performance-team@google.com</owner>
   <summary>
@@ -2705,7 +2705,7 @@
 </histogram>
 
 <histogram name="Android.InputOnViz.Viz.StateProcessingResult"
-    enum="InputOnVizStateProcessingResult" expires_after="2025-11-23">
+    enum="InputOnVizStateProcessingResult" expires_after="2026-01-25">
   <owner>kartarsingh@google.com</owner>
   <owner>woa-performance-team@google.com</owner>
   <summary>
@@ -3017,7 +3017,7 @@
 </histogram>
 
 <histogram name="Android.Messages.Enqueued.Hidden" enum="MessageIdentifier"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>lazzzis@chromium.org</owner>
   <owner>src/components/messages/OWNERS</owner>
   <summary>
@@ -3195,7 +3195,7 @@
 </histogram>
 
 <histogram name="Android.MultiInstance.MaxInstanceCount" units="instances"
-    expires_after="2025-10-26">
+    expires_after="2026-01-25">
   <owner>jinsukkim@chromium.org</owner>
   <owner>twellington@chromium.org</owner>
   <owner>clank-app-team@google.com</owner>
@@ -6164,26 +6164,6 @@
   </summary>
 </histogram>
 
-<histogram name="Android.WebView.AppDataDirectory.Size" units="KiB"
-    expires_after="2023-06-01">
-  <owner>xiaq@chromium.org</owner>
-  <owner>src/android_webview/OWNERS</owner>
-  <summary>
-    Size on disk taken by the embedding app's data directory, recorded once per
-    WebView startup after a small delay.
-  </summary>
-</histogram>
-
-<histogram name="Android.WebView.AppDataDirectory.TimeToComputeSize" units="ms"
-    expires_after="2023-06-01">
-  <owner>xiaq@chromium.org</owner>
-  <owner>src/android_webview/OWNERS</owner>
-  <summary>
-    Time to compute the size on disk taken by the embedding app's data
-    directory, recorded once per WebView startup after a small delay.
-  </summary>
-</histogram>
-
 <histogram name="Android.WebView.AssetPathWorkaroundUsed.FactoryInit"
     enum="Boolean" expires_after="2025-09-11">
   <owner>alexmitra@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/arc/histograms.xml b/tools/metrics/histograms/metadata/arc/histograms.xml
index 01965f0..7e324ad1 100644
--- a/tools/metrics/histograms/metadata/arc/histograms.xml
+++ b/tools/metrics/histograms/metadata/arc/histograms.xml
@@ -544,7 +544,7 @@
 </histogram>
 
 <histogram name="Arc.AppInstalledReason" enum="InstallationCounterReasonEnum"
-    expires_after="2025-09-14">
+    expires_after="2026-01-25">
   <owner>thanhdng@chromium.org</owner>
   <owner>tby@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml
index 32906e6..0e37482 100644
--- a/tools/metrics/histograms/metadata/ash/histograms.xml
+++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -631,7 +631,7 @@
 </histogram>
 
 <histogram name="Ash.AmbientMode.PhotoSource" enum="AmbientModePhotoSource"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>cowmoo@google.com</owner>
   <owner>cros-p13n-eng@google.com</owner>
   <summary>
@@ -686,7 +686,7 @@
 </histogram>
 
 <histogram name="Ash.AmbientMode.TopicSource" enum="AmbientModeTopicSource"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>cowmoo@google.com</owner>
   <owner>cros-p13n-eng@google.com</owner>
   <summary>
@@ -735,7 +735,7 @@
 </histogram>
 
 <histogram name="Ash.AmbientMode.VideoSmoothness.{Settings}" units="%"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>cowmoo@google.com</owner>
   <owner>cros-p13n-eng@chromium.org</owner>
   <summary>
@@ -2337,7 +2337,7 @@
 </histogram>
 
 <histogram name="Ash.DarkTheme.SystemTray.IsDarkModeEnabled" enum="Boolean"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>minch@chromium.org</owner>
   <owner>changmar@chromium.org</owner>
   <summary>
@@ -4076,7 +4076,7 @@
 </histogram>
 
 <histogram name="Ash.FullRestore.ShowInformedRestoreDialog" enum="BooleanHit"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>hewer@chromium.org</owner>
   <owner>xdai@chromium.org</owner>
   <summary>Emmited every time the informed restore dialog shows up.</summary>
@@ -8740,7 +8740,7 @@
 </histogram>
 
 <histogram name="Ash.StatusArea.TrayItemView.Show" units="%"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>leandre@chromium.org</owner>
   <owner>cros-status-area-eng@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/attribution_reporting/histograms.xml b/tools/metrics/histograms/metadata/attribution_reporting/histograms.xml
index d5e32fc..7fdb69d5 100644
--- a/tools/metrics/histograms/metadata/attribution_reporting/histograms.xml
+++ b/tools/metrics/histograms/metadata/attribution_reporting/histograms.xml
@@ -176,7 +176,7 @@
 </histogram>
 
 <histogram name="Conversions.AggregatableReport.FilteredTriggerDataPercentage"
-    units="%" expires_after="2025-11-21">
+    units="%" expires_after="2026-01-25">
   <owner>linnan@chromium.org</owner>
   <owner>measurement-api-dev+metrics@google.com</owner>
   <summary>
@@ -407,7 +407,7 @@
 </histogram>
 
 <histogram name="Conversions.ClearDataTime" units="ms"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>csharrison@chromium.org</owner>
   <owner>measurement-api-dev+metrics@google.com</owner>
   <summary>
@@ -824,7 +824,7 @@
 </histogram>
 
 <histogram name="Conversions.NamedBudgetsPer{Type}Registration"
-    units="named_budgets" expires_after="2025-11-23">
+    units="named_budgets" expires_after="2026-01-25">
   <owner>tquintanilla@chromium.org</owner>
   <owner>measurement-api-dev+metrics@google.com</owner>
   <summary>
@@ -838,7 +838,7 @@
 </histogram>
 
 <histogram name="Conversions.NavigationDataHostStatus3"
-    enum="ConversionNavigationDataHostStatus" expires_after="2025-11-23">
+    enum="ConversionNavigationDataHostStatus" expires_after="2026-01-25">
   <owner>linnan@chromium.org</owner>
   <owner>measurement-api-dev+metrics@google.com</owner>
   <summary>
@@ -1023,7 +1023,7 @@
 </histogram>
 
 <histogram name="Conversions.OsRegistrationsSkipBufferRegistrationsSize"
-    units="count" expires_after="2025-11-21">
+    units="count" expires_after="2026-01-25">
   <owner>linnan@chromium.org</owner>
   <owner>measurement-api-dev+metrics@google.com</owner>
   <summary>
@@ -1269,7 +1269,7 @@
 </histogram>
 
 <histogram name="Conversions.Storage.ClearDataWithFilterDuration" units="ms"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>csharrison@chromium.org</owner>
   <owner>measurement-api-dev+metrics@google.com</owner>
   <summary>
@@ -1535,7 +1535,7 @@
 </histogram>
 
 <histogram name="Conversions.ValuesPerFilter" units="values"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>linnan@chromium.org</owner>
   <owner>measurement-api-dev+metrics@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/autofill/enums.xml b/tools/metrics/histograms/metadata/autofill/enums.xml
index 819422c..a4d488f7 100644
--- a/tools/metrics/histograms/metadata/autofill/enums.xml
+++ b/tools/metrics/histograms/metadata/autofill/enums.xml
@@ -155,6 +155,17 @@
   <int value="2" label="Import with section union"/>
 </enum>
 
+<!-- LINT.IfChange(AutofillAiEntityType) -->
+
+<enum name="AutofillAiEntityType">
+  <int value="0" label="Passport"/>
+  <int value="1" label="Driver's License"/>
+  <int value="2" label="Vehicle Information"/>
+  <int value="3" label="National ID Card"/>
+</enum>
+
+<!-- LINT.ThenChange(//components/autofill/core/browser/data_model/autofill_ai/entity_type.cc:EntityType) -->
+
 <enum name="AutofillAiModelExecutionStatus">
   <int value="0"
       label="One or more field indices returned by the model are out of
diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml
index 76f9598..afe475ce 100644
--- a/tools/metrics/histograms/metadata/autofill/histograms.xml
+++ b/tools/metrics/histograms/metadata/autofill/histograms.xml
@@ -42,6 +42,20 @@
                to be filled and assigned to the control case."/>
 </variants>
 
+<!-- LINT.IfChange(Autofill.Ai.EntityType) -->
+
+<variants name="Autofill.Ai.EntityType">
+  <variant name="DriversLicense"
+      summary="Emitted for driver's license forms only."/>
+  <variant name="NationalIdCard"
+      summary="Emitted for national id card forms only."/>
+  <variant name="Passport" summary="Emitted for passport forms only."/>
+  <variant name="Vehicle"
+      summary="Emitted for vehicle information forms only."/>
+</variants>
+
+<!-- LINT.ThenChange(//components/autofill/core/browser/data_model/autofill_ai/entity_type.cc:EntityType) -->
+
 <variants name="Autofill.Ai.PromptTypes">
   <variant name="SavePrompt"
       summary="The prompt is asking users to save a new entity."/>
@@ -1119,16 +1133,34 @@
   </token>
 </histogram>
 
+<histogram name="Autofill.Ai.Funnel.{SubmissionState}.Eligibility2"
+    enum="AutofillAiEntityType" expires_after="2025-12-12">
+  <owner>jihadghanna@google.com</owner>
+  <owner>chrome-autofill-alerts@google.com</owner>
+  <summary>
+    Records the EntityType's for which a form is eligible for filling. Emitted
+    once per form submission/abandonment.
+  </summary>
+  <token key="SubmissionState">
+    <variant name="Abandoned"/>
+    <variant name="Aggregate"/>
+    <variant name="Submitted"/>
+  </token>
+</histogram>
+
 <histogram name="Autofill.Ai.Funnel.{SubmissionState}.{FunnelStage}"
     enum="Boolean" expires_after="2025-12-12">
   <owner>jihadghanna@google.com</owner>
   <owner>chrome-autofill-alerts@google.com</owner>
   <summary>
-    Records various stages of the Autofill AI funnel. The same metric is logged
-    for submitted and for abandoned forms, with an additional metric aggregating
-    both. The metric is recorded once per form per submission/abandonment.
+    (DEPRECATED) Records various stages of the Autofill AI funnel. The same
+    metric is logged for submitted and for abandoned forms, with an additional
+    metric aggregating both. The metric is recorded once per form per
+    submission/abandonment.
 
     {FunnelStage}
+
+    Deprecated in favor of the Funnel metric split by `EntityType`.
   </summary>
   <token key="SubmissionState">
     <variant name="Abandoned"/>
@@ -1157,7 +1189,46 @@
   </token>
 </histogram>
 
-<histogram name="Autofill.Ai.KeyMetrics{KeyMetric}{EntityGranularity}"
+<histogram
+    name="Autofill.Ai.Funnel.{SubmissionState}.{FunnelStage}.{EntityGranularity}"
+    enum="Boolean" expires_after="2025-12-12">
+  <owner>jihadghanna@google.com</owner>
+  <owner>chrome-autofill-alerts@google.com</owner>
+  <summary>
+    Records various stages of the Autofill AI funnel. The same metric is logged
+    for submitted and for abandoned forms, with an additional metric aggregating
+    both. The metric is recorded once per form per submission/abandonment.
+
+    {FunnelStage}
+
+    {EntityGranularity}
+  </summary>
+  <token key="SubmissionState">
+    <variant name="Abandoned"/>
+    <variant name="Aggregate"/>
+    <variant name="Submitted"/>
+  </token>
+  <token key="FunnelStage">
+    <variant name="CorrectionAfterFill"
+        summary="Given a form where the user filled an Autofill AI
+                 suggestion, records whether the filling was corrected or
+                 not."/>
+    <variant name="FillAfterSuggestion"
+        summary="Given a form where the user saw Autofill AI filling
+                 suggestions, records whether the suggestion was filled or
+                 not."/>
+    <variant name="ReadinessAfterEligibility"
+        summary="Given an Autofill-AI-eligible form, this metric records
+                 whether the user has stored data to fill the form."/>
+    <variant name="SuggestionAfterReadiness"
+        summary="Given an Autofill-AI-eligible form where the user has data
+                 stored to fill it, this metric records whether the user saw
+                 an Autofill AI suggestion or not."/>
+  </token>
+  <token key="EntityGranularity" variants="Autofill.Ai.EntityType"/>
+</histogram>
+
+<histogram name="Autofill.Ai.KeyMetrics{KeyMetric}.{EntityGranularity}"
     enum="Boolean" expires_after="2025-12-12">
   <owner>jihadghanna@google.com</owner>
   <owner>chrome-autofill-alerts@google.com</owner>
@@ -1185,17 +1256,7 @@
         summary="Records, at form submission, whether the user had Autofill
                  AI data to fill the form or not."/>
   </token>
-  <token key="EntityGranularity">
-    <variant name=""
-        summary="Emitted for all entities supported by Autofill AI."/>
-    <variant name=".DriversLicense"
-        summary="Emitted for driver's license forms only."/>
-    <variant name=".NationalIdCard"
-        summary="Emitted for national id card forms only."/>
-    <variant name=".Passport" summary="Emitted for passport forms only."/>
-    <variant name=".Vehicle"
-        summary="Emitted for vehicle information forms only."/>
-  </token>
+  <token key="EntityGranularity" variants="Autofill.Ai.EntityType"/>
 </histogram>
 
 <histogram name="Autofill.Ai.ModelExecutionStatus"
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml
index 81c92f8..5655c1a 100644
--- a/tools/metrics/histograms/metadata/blink/histograms.xml
+++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -894,7 +894,7 @@
 </histogram>
 
 <histogram name="Blink.CullRect.UpdateTime" units="microseconds"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>pdr@chromium.org</owner>
   <owner>wangxianzhu@chromium.org</owner>
   <owner>paint-dev@chromium.org</owner>
@@ -1882,7 +1882,7 @@
 </histogram>
 
 <histogram name="Blink.FedCm.SegmentationPlatform.UserAction"
-    enum="FedCmUserAction" expires_after="2025-11-23">
+    enum="FedCmUserAction" expires_after="2026-01-25">
   <owner>tanzachary@chromium.org</owner>
   <owner>web-identity-eng@google.com</owner>
   <summary>
@@ -2805,7 +2805,7 @@
 </histogram>
 
 <histogram name="Blink.HTMLParsing.IsParserPausingCalledAfterResuming"
-    enum="Boolean" expires_after="2025-10-08">
+    enum="Boolean" expires_after="2026-01-25">
   <owner>sisidovski@chromium.org</owner>
   <owner>chrome-loading@google.com</owner>
   <summary>
@@ -3927,7 +3927,7 @@
 </histogram>
 
 <histogram name="Blink.LinkHeader.LoadLinksFromHeaderMode"
-    enum="LoadLinksFromHeaderMode" expires_after="2025-11-23">
+    enum="LoadLinksFromHeaderMode" expires_after="2026-01-25">
   <owner>tnak@chromium.org</owner>
   <owner>chrome-loading@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/browser/histograms.xml b/tools/metrics/histograms/metadata/browser/histograms.xml
index b77b9c7a..2db978b8 100644
--- a/tools/metrics/histograms/metadata/browser/histograms.xml
+++ b/tools/metrics/histograms/metadata/browser/histograms.xml
@@ -1064,7 +1064,7 @@
 </histogram>
 
 <histogram name="Browser.WindowCount.Guest" units="units"
-    expires_after="2025-10-19">
+    expires_after="2026-01-25">
   <owner>rhalavati@chromium.org</owner>
   <owner>chrome-privacy-core@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/browsing_topics/histograms.xml b/tools/metrics/histograms/metadata/browsing_topics/histograms.xml
index fe9e110..e4ee4c70 100644
--- a/tools/metrics/histograms/metadata/browsing_topics/histograms.xml
+++ b/tools/metrics/histograms/metadata/browsing_topics/histograms.xml
@@ -305,7 +305,7 @@
 </histogram>
 
 <histogram name="BrowsingTopics.SiteDataStorage.FileSize.KB" units="KB"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>yaoxia@chromium.org</owner>
   <owner>jkarlin@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/chrome/histograms.xml b/tools/metrics/histograms/metadata/chrome/histograms.xml
index 68f9f6f..7978adf6 100644
--- a/tools/metrics/histograms/metadata/chrome/histograms.xml
+++ b/tools/metrics/histograms/metadata/chrome/histograms.xml
@@ -23,7 +23,7 @@
 <histograms>
 
 <histogram name="Chrome.AppMenu.MenuHostInitToNextFramePresented" units="ms"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>temao@chromium.org</owner>
   <owner>robliao@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/chromeos/histograms.xml b/tools/metrics/histograms/metadata/chromeos/histograms.xml
index e5e5a3ae..ca2192a 100644
--- a/tools/metrics/histograms/metadata/chromeos/histograms.xml
+++ b/tools/metrics/histograms/metadata/chromeos/histograms.xml
@@ -2427,7 +2427,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Intents.LinkCapturingEvent2"
-    enum="LinkCapturingEvent" expires_after="2025-11-23">
+    enum="LinkCapturingEvent" expires_after="2026-01-25">
   <owner>vpao@google.com</owner>
   <owner>chromeos-apps-foundation-team@google.com</owner>
   <summary>
@@ -3125,7 +3125,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Regmon.PolicyHandlerTime" units="ms"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>chiav@chromium.org</owner>
   <owner>crmullins@chromium.org</owner>
   <summary>
@@ -3135,7 +3135,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Regmon.PolicyViolation"
-    enum="NetworkAnnotationHashCodes" expires_after="2025-11-23">
+    enum="NetworkAnnotationHashCodes" expires_after="2026-01-25">
   <owner>chiav@chromium.org</owner>
   <owner>crmullins@chromium.org</owner>
   <summary>
@@ -3147,7 +3147,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Regmon.ReportViolationTime" units="ms"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>chiav@chromium.org</owner>
   <owner>crmullins@chromium.org</owner>
   <summary>
@@ -3232,7 +3232,7 @@
 </histogram>
 
 <histogram name="ChromeOS.SAML.Provider" enum="ChromeOSSamlProvider"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>mslus@chromium.org</owner>
   <owner>cros-3pidp@google.com</owner>
   <summary>Records SAML provider when SAML login flow is used.</summary>
diff --git a/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml b/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml
index 415f0cf..b4e754d 100644
--- a/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml
+++ b/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml
@@ -44,7 +44,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Settings.Accessibility.CaretBlinkInterval" units="ms"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>katie@chromium.org</owner>
   <owner>chrome-a11y-core@google.com</owner>
   <summary>
@@ -125,7 +125,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Settings.Accessibility.MagnifierFollowsChromeVox"
-    enum="BooleanToggled" expires_after="2025-11-23">
+    enum="BooleanToggled" expires_after="2026-01-25">
   <owner>aldietz@google.com</owner>
   <owner>chromeos-a11y-eng@google.com</owner>
   <summary>
@@ -135,7 +135,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Settings.Accessibility.{SettingType}.Enabled"
-    enum="BooleanToggled" expires_after="2025-11-23">
+    enum="BooleanToggled" expires_after="2026-01-25">
   <owner>katie@chromium.org</owner>
   <owner>chromeos-a11y-eng@google.com</owner>
   <summary>
@@ -896,7 +896,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Settings.SearchResultSectionSelected"
-    enum="OsSettingsSection" expires_after="2025-10-19">
+    enum="OsSettingsSection" expires_after="2026-01-25">
   <owner>wesokuhara@google.com</owner>
   <owner>xiaohuic@chromium.org</owner>
   <owner>cros-settings@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/commerce/histograms.xml b/tools/metrics/histograms/metadata/commerce/histograms.xml
index 8879c04..d5b0cde8 100644
--- a/tools/metrics/histograms/metadata/commerce/histograms.xml
+++ b/tools/metrics/histograms/metadata/commerce/histograms.xml
@@ -778,7 +778,7 @@
 </histogram>
 
 <histogram name="Commerce.PriceTracking.PriceInsightsSidePanel.{Action}"
-    enum="PriceInsightsPriceBucket" expires_after="2025-11-23">
+    enum="PriceInsightsPriceBucket" expires_after="2026-01-25">
   <owner>yuezhanggg@chromium.org</owner>
   <owner>mdjones@chromium.org</owner>
   <summary>
@@ -877,7 +877,7 @@
 </histogram>
 
 <histogram name="Commerce.ShoppingService.ProductInfo.ImageAvailability"
-    enum="ProductImageAvailability" expires_after="2025-11-23">
+    enum="ProductImageAvailability" expires_after="2026-01-25">
   <owner>ayman@chromium.org</owner>
   <owner>mdjones@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/compositing/histograms.xml b/tools/metrics/histograms/metadata/compositing/histograms.xml
index 90a4adff..d0cfdff7 100644
--- a/tools/metrics/histograms/metadata/compositing/histograms.xml
+++ b/tools/metrics/histograms/metadata/compositing/histograms.xml
@@ -744,7 +744,7 @@
 </histogram>
 
 <histogram name="Compositing.Scheduler.DeadlineMode"
-    enum="BeginImplFrameDeadlineMode" expires_after="2025-10-30">
+    enum="BeginImplFrameDeadlineMode" expires_after="2026-01-25">
   <owner>lizeb@chromium.org</owner>
   <owner>jonross@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/cookie/histograms.xml b/tools/metrics/histograms/metadata/cookie/histograms.xml
index 40b983f1..2be76ac 100644
--- a/tools/metrics/histograms/metadata/cookie/histograms.xml
+++ b/tools/metrics/histograms/metadata/cookie/histograms.xml
@@ -514,7 +514,7 @@
 </histogram>
 
 <histogram name="Cookie.GetCookieListWithOptions.Duration.Subsampled"
-    units="microseconds" expires_after="2025-11-23">
+    units="microseconds" expires_after="2026-01-25">
   <owner>anthonyvd@chromium.org</owner>
   <owner>chrome-catan@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/cras/histograms.xml b/tools/metrics/histograms/metadata/cras/histograms.xml
index 0b15ab9..312c685 100644
--- a/tools/metrics/histograms/metadata/cras/histograms.xml
+++ b/tools/metrics/histograms/metadata/cras/histograms.xml
@@ -466,7 +466,7 @@
 </histogram>
 
 <histogram name="Cras.DlcManagerStatus.ElapsedTimeHistogramOnSuccess.{DlcType}"
-    units="seconds" expires_after="2025-11-23">
+    units="seconds" expires_after="2026-01-25">
   <owner>hunghsienchen@google.com</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -830,7 +830,7 @@
 </histogram>
 
 <histogram name="Cras.RtcDevicePair" enum="CrasDevicePair"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>yuhsuan@chromium.org</owner>
   <owner>chromeos-audio@google.com</owner>
   <summary>
@@ -959,7 +959,7 @@
 </histogram>
 
 <histogram name="Cras.StreamCallbackThreshold{Cras_Direction}" units="frames"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
 <!-- Name completed by histogram_suffixes
      name="Cras.Direction" and
      name="Cras.ClientType" -->
@@ -1032,7 +1032,7 @@
 </histogram>
 
 <histogram name="Cras.StreamEffectsOnDestroy{Cras_Direction}" units="value"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
 <!-- Name completed by histogram_suffixes
      name="Cras.Direction" and
      name="Cras.ClientType" -->
diff --git a/tools/metrics/histograms/metadata/custom_tabs/histograms.xml b/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
index a60faa5..f8333da2 100644
--- a/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
+++ b/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
@@ -111,7 +111,7 @@
 </histogram>
 
 <histogram name="CustomTabs.AdaptiveToolbarButton.Shown"
-    enum="AdaptiveToolbarButtonVariant" expires_after="2025-09-25">
+    enum="AdaptiveToolbarButtonVariant" expires_after="2026-01-25">
   <owner>jinsukkiim@google.com</owner>
   <owner>clank-app-team@google.com</owner>
   <summary>
@@ -671,7 +671,7 @@
 </histogram>
 
 <histogram name="CustomTabs.PageNavigation.ErrorCode" enum="NetErrorCodes"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>jinsukkim@chromium.org</owner>
   <owner>chrome-connective-tissue@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/enterprise/histograms.xml b/tools/metrics/histograms/metadata/enterprise/histograms.xml
index a966e57d..ed2a813 100644
--- a/tools/metrics/histograms/metadata/enterprise/histograms.xml
+++ b/tools/metrics/histograms/metadata/enterprise/histograms.xml
@@ -1330,7 +1330,7 @@
 </histogram>
 
 <histogram name="Enterprise.Dlp.ActiveFileEventsCount" units="entries"
-    expires_after="2025-10-05">
+    expires_after="2026-01-25">
   <owner>accorsi@google.com</owner>
   <owner>chromeos-dlp@google.com</owner>
   <summary>
@@ -2291,7 +2291,7 @@
 </histogram>
 
 <histogram name="Enterprise.EventBasedLogUpload.{EventLogUploadType}"
-    enum="EnterpriseEventBasedLogUploadResult" expires_after="2025-11-25">
+    enum="EnterpriseEventBasedLogUploadResult" expires_after="2026-01-25">
   <owner>iremuguz@google.com</owner>
   <owner>chromeos-commercial-supportability@google.com</owner>
   <summary>
@@ -2344,7 +2344,7 @@
 </histogram>
 
 <histogram name="Enterprise.FileAnalysisRequest.PrintedPageSize" units="KB"
-    expires_after="2025-11-20">
+    expires_after="2026-01-25">
   <owner>eliashomsi@google.com</owner>
   <owner>nancylanxiao@google.com</owner>
   <owner>cbe-cep-eng@google.com</owner>
@@ -4067,7 +4067,7 @@
 </histogram>
 
 <histogram name="EnterpriseCheck.IsRunningOnManagedProfileDuration" units="ms"
-    expires_after="2025-11-01">
+    expires_after="2026-01-25">
   <owner>nafisabedin@google.com</owner>
   <improvement direction="LOWER_IS_BETTER"/>
   <summary>
diff --git a/tools/metrics/histograms/metadata/event/histograms.xml b/tools/metrics/histograms/metadata/event/histograms.xml
index fe4eaf7..281cf0f 100644
--- a/tools/metrics/histograms/metadata/event/histograms.xml
+++ b/tools/metrics/histograms/metadata/event/histograms.xml
@@ -220,7 +220,7 @@
 
 <histogram
     name="Event.Jank.ScrollUpdate.{ScrollSpeed}.{VsyncStatus}.FrameAboveJankyThreshold2"
-    units="ratio * 100" expires_after="2025-11-23">
+    units="ratio * 100" expires_after="2026-01-25">
   <owner>jonross@chromium.org</owner>
   <owner>woa-performance@google.com</owner>
   <improvement direction="LOWER_IS_BETTER"/>
diff --git a/tools/metrics/histograms/metadata/extensions/histograms.xml b/tools/metrics/histograms/metadata/extensions/histograms.xml
index 0479c93..99db5aa 100644
--- a/tools/metrics/histograms/metadata/extensions/histograms.xml
+++ b/tools/metrics/histograms/metadata/extensions/histograms.xml
@@ -4865,7 +4865,7 @@
 </histogram>
 
 <histogram name="Extensions.ZeroStatePromo.IphActionChromeWebStoreLink"
-    enum="WebStoreLinkClicked" expires_after="2025-09-27">
+    enum="WebStoreLinkClicked" expires_after="2026-01-25">
   <owner>uwyiming@chromium.org</owner>
   <owner>cws-consumer-team@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/glic/histograms.xml b/tools/metrics/histograms/metadata/glic/histograms.xml
index 7b25462..bb7ac49 100644
--- a/tools/metrics/histograms/metadata/glic/histograms.xml
+++ b/tools/metrics/histograms/metadata/glic/histograms.xml
@@ -92,7 +92,6 @@
     <variant name="LogInstantEvent"/>
     <variant name="MaybeRefreshUserStatus"/>
     <variant name="OnClosedCaptionsShown"/>
-    <variant name="OnRequestStarted"/>
     <variant name="OnResponseRated"/>
     <variant name="OnResponseStarted"/>
     <variant name="OnResponseStopped"/>
diff --git a/tools/metrics/histograms/metadata/gpu/histograms.xml b/tools/metrics/histograms/metadata/gpu/histograms.xml
index 630d11c..c9b0faf 100644
--- a/tools/metrics/histograms/metadata/gpu/histograms.xml
+++ b/tools/metrics/histograms/metadata/gpu/histograms.xml
@@ -1393,7 +1393,7 @@
 </histogram>
 
 <histogram name="GPU.TransferCache.ReusedTimes" units="Reuses"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>boliu@chromium.org</owner>
   <owner>chrome-gpu-metric-alerts@chromium.org</owner>
   <summary>
@@ -1986,7 +1986,7 @@
 </histogram>
 
 <histogram name="Viz.FrameIntervalDecider.ActualIntervalDefault" units="ms"
-    expires_after="M143">
+    expires_after="2026-01-25">
   <owner>boliu@chromium.org</owner>
   <owner>chrome-gpu-metric-alerts@chromium.org</owner>
   <summary>
@@ -2003,7 +2003,7 @@
 </histogram>
 
 <histogram name="Viz.FrameIntervalDecider.ActualIntervalFor{DecidedHz}hz"
-    units="ms" expires_after="M143">
+    units="ms" expires_after="2026-01-25">
   <owner>boliu@chromium.org</owner>
   <owner>chrome-gpu-metric-alerts@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/history/histograms.xml b/tools/metrics/histograms/metadata/history/histograms.xml
index 26b66ca..d549444 100644
--- a/tools/metrics/histograms/metadata/history/histograms.xml
+++ b/tools/metrics/histograms/metadata/history/histograms.xml
@@ -800,7 +800,7 @@
 </histogram>
 
 <histogram name="History.Clusters.Backend.QueryAnnotatedVisits.ThreadTime"
-    units="ms" expires_after="2025-11-23">
+    units="ms" expires_after="2026-01-25">
   <owner>sophiechang@chromium.org</owner>
   <owner>chrome-journeys@google.com</owner>
   <component>1457319</component>
@@ -2879,7 +2879,7 @@
 </histogram>
 
 <histogram name="History.VisitedLinks.TryToAddFingerprint"
-    enum="AddFingerprint" expires_after="2025-11-23">
+    enum="AddFingerprint" expires_after="2026-01-25">
   <owner>kyraseevers@chromium.org</owner>
   <owner>janiceliu@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/input/enums.xml b/tools/metrics/histograms/metadata/input/enums.xml
index fc3cd96..e82cc4e74 100644
--- a/tools/metrics/histograms/metadata/input/enums.xml
+++ b/tools/metrics/histograms/metadata/input/enums.xml
@@ -233,6 +233,7 @@
   <int value="45" label="FEATURE_BLOCKED_BY_UNSUPPORTED_CAPABILITY"/>
   <int value="46" label="FEATURE_BLOCKED_BY_UNKNOWN_CAPABILITY"/>
   <int value="47" label="FEATURE_BLOCKED_BY_POLICY"/>
+  <int value="48" label="FEATURE_BLOCKED_BY_INVALID_SELECTION"/>
 </enum>
 
 <enum name="IMEGrammarActions">
diff --git a/tools/metrics/histograms/metadata/ios/enums.xml b/tools/metrics/histograms/metadata/ios/enums.xml
index 503d56072..c29e6ab9 100644
--- a/tools/metrics/histograms/metadata/ios/enums.xml
+++ b/tools/metrics/histograms/metadata/ios/enums.xml
@@ -1586,6 +1586,16 @@
 
 <!-- LINT.ThenChange(/ios/chrome/browser/push_notification/model/constants.h:PushNotificationTargetProfileHandlingResult) -->
 
+<!-- LINT.IfChange(ReaderModeAccessPoint) -->
+
+<enum name="ReaderModeAccessPoint">
+  <int value="0" label="Contextual Chip"/>
+  <int value="1" label="Tools Menu"/>
+  <int value="2" label="AI Hub"/>
+</enum>
+
+<!-- LINT.ThenChange(/ios/chrome/browser/reader_mode/model/constants.h:ReaderModeAccessPoint) -->
+
 <!-- LINT.IfChange(ReaderModeCustomizationType) -->
 
 <enum name="ReaderModeCustomizationType">
diff --git a/tools/metrics/histograms/metadata/ios/histograms.xml b/tools/metrics/histograms/metadata/ios/histograms.xml
index 4435e61..205c798 100644
--- a/tools/metrics/histograms/metadata/ios/histograms.xml
+++ b/tools/metrics/histograms/metadata/ios/histograms.xml
@@ -2647,7 +2647,7 @@
 </histogram>
 
 <histogram name="IOS.MagicStack.Module.Disabled" enum="IOSMagicStackModuleType"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>thegreenfrog@chromium.org</owner>
   <owner>bling-pandamonium@google.com</owner>
   <summary>Records when a module was disabled.</summary>
@@ -3190,7 +3190,7 @@
 </histogram>
 
 <histogram name="IOS.MultiWindow.OpenInNewWindow" enum="WindowActivityOrigin"
-    expires_after="2025-11-09">
+    expires_after="2026-01-25">
   <owner>marq@chromium.org</owner>
   <owner>fedegermi@google.com</owner>
   <summary>
@@ -3263,7 +3263,7 @@
 </histogram>
 
 <histogram name="IOS.Notifications.SafetyCheck.Interaction"
-    enum="IOSSafetyCheckNotificationType" expires_after="2025-11-23">
+    enum="IOSSafetyCheckNotificationType" expires_after="2026-01-25">
   <owner>bwwilliams@google.com</owner>
   <owner>scottyoder@google.com</owner>
   <owner>bling-pandamonium@google.com</owner>
@@ -3341,7 +3341,7 @@
 </histogram>
 
 <histogram name="IOS.Notifications.Tips.Proactive.{Event}"
-    enum="IOSTipsNotificationType" expires_after="2025-11-23">
+    enum="IOSTipsNotificationType" expires_after="2026-01-25">
   <owner>scottyoder@google.com</owner>
   <owner>bling-gsu-pod@google.com</owner>
   <summary>Logs when a Proactive Tips notification {Event}.</summary>
@@ -4494,6 +4494,18 @@
   </summary>
 </histogram>
 
+<histogram name="IOS.ReaderMode.AccessPoint" enum="ReaderModeAccessPoint"
+    expires_after="2025-12-24">
+  <owner>fernandex@google.com</owner>
+  <owner>qpubert@google.com</owner>
+  <owner>bling-squid-squad@google.com</owner>
+  <summary>
+    Logs the access point where the user enabled Reading Mode UI on iOS, this
+    does not include situations when the user changes web state (e.g. by
+    switching tabs or closing the browser).
+  </summary>
+</histogram>
+
 <histogram name="IOS.ReaderMode.Customization"
     enum="ReaderModeCustomizationType" expires_after="2025-11-24">
   <owner>fernandex@google.com</owner>
@@ -4505,7 +4517,7 @@
 </histogram>
 
 <histogram name="IOS.ReaderMode.Distiller.Latency" units="ms"
-    expires_after="2025-11-24">
+    expires_after="2026-01-25">
   <owner>fernandex@google.com</owner>
   <owner>bling-squid-squad@google.com</owner>
   <summary>
@@ -4550,7 +4562,7 @@
 </histogram>
 
 <histogram name="IOS.ReaderMode.Heuristic.Latency" units="ms"
-    expires_after="2025-11-24">
+    expires_after="2026-01-25">
   <owner>fernandex@google.com</owner>
   <owner>bling-squid-squad@google.com</owner>
   <summary>
@@ -6349,7 +6361,7 @@
 
 <histogram
     name="ManualFallback.VisibleSuggestions.ExpandIcon.OpenPaymentMethods"
-    units="Suggestions" expires_after="2025-10-26">
+    units="Suggestions" expires_after="2026-01-25">
   <owner>noemies@google.com</owner>
   <owner>sugoi@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/kiosk/histograms.xml b/tools/metrics/histograms/metadata/kiosk/histograms.xml
index bfe902dd..ae534838 100644
--- a/tools/metrics/histograms/metadata/kiosk/histograms.xml
+++ b/tools/metrics/histograms/metadata/kiosk/histograms.xml
@@ -201,7 +201,7 @@
 </histogram>
 
 <histogram name="Kiosk.LaunchDuration.{KioskType}" units="ms"
-    expires_after="2025-10-12">
+    expires_after="2026-01-25">
   <owner>yixie@chromium.org</owner>
   <owner>chromeos-kiosk-eng@google.com</owner>
   <summary>Records the total duration it takes to launch a kiosk app.</summary>
diff --git a/tools/metrics/histograms/metadata/language/histograms.xml b/tools/metrics/histograms/metadata/language/histograms.xml
index 027b418..6036c72 100644
--- a/tools/metrics/histograms/metadata/language/histograms.xml
+++ b/tools/metrics/histograms/metadata/language/histograms.xml
@@ -332,7 +332,7 @@
 </histogram>
 
 <histogram name="LanguageUsage.AcceptLanguage.FirstAcceptLanguage"
-    enum="LanguageName" expires_after="2025-11-24">
+    enum="LanguageName" expires_after="2026-01-25">
   <owner>victortan@chromium.org</owner>
   <owner>katabolism-finch@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/login/histograms.xml b/tools/metrics/histograms/metadata/login/histograms.xml
index 88ac532..c853c20 100644
--- a/tools/metrics/histograms/metadata/login/histograms.xml
+++ b/tools/metrics/histograms/metadata/login/histograms.xml
@@ -117,7 +117,7 @@
 </histogram>
 
 <histogram name="Login.Flow.{UserVisibility}.{UserCount}"
-    enum="LoginFlowUserLoginType" expires_after="2025-11-23">
+    enum="LoginFlowUserLoginType" expires_after="2026-01-25">
   <owner>antrim@chromium.org</owner>
   <owner>cros-lurs@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/magic_stack/histograms.xml b/tools/metrics/histograms/metadata/magic_stack/histograms.xml
index db6245b..92c2f94 100644
--- a/tools/metrics/histograms/metadata/magic_stack/histograms.xml
+++ b/tools/metrics/histograms/metadata/magic_stack/histograms.xml
@@ -51,7 +51,7 @@
 </variants>
 
 <histogram name="MagicStack.Clank.NewTabPage.ContextMenu.OpenCustomizeSettings"
-    enum="ModuleType" expires_after="2025-11-26">
+    enum="ModuleType" expires_after="2026-01-25">
   <owner>hanxi@chromium.org</owner>
   <owner>xinyiji@chromium.org</owner>
   <summary>
@@ -62,7 +62,7 @@
 </histogram>
 
 <histogram name="MagicStack.Clank.NewTabPage.ContextMenu.RemoveModuleV2"
-    enum="ModuleType" expires_after="2025-11-26">
+    enum="ModuleType" expires_after="2026-01-25">
   <owner>hanxi@chromium.org</owner>
   <owner>xinyiji@chromium.org</owner>
   <summary>
@@ -72,7 +72,7 @@
 </histogram>
 
 <histogram name="MagicStack.Clank.NewTabPage.ContextMenu.ShownV2"
-    enum="ModuleType" expires_after="2025-11-26">
+    enum="ModuleType" expires_after="2026-01-25">
   <owner>hanxi@chromium.org</owner>
   <owner>xinyiji@chromium.org</owner>
   <summary>
@@ -82,7 +82,7 @@
 </histogram>
 
 <histogram name="MagicStack.Clank.NewTabPage.Module.Click" enum="ModuleType"
-    expires_after="2025-11-26">
+    expires_after="2026-01-25">
   <owner>hanxi@chromium.org</owner>
   <owner>xinyiji@chromium.org</owner>
   <summary>
@@ -94,7 +94,7 @@
 
 <histogram
     name="MagicStack.Clank.NewTabPage.Module.FetchDataDurationMs.{ModuleType}"
-    units="ms" expires_after="2025-11-26">
+    units="ms" expires_after="2026-01-25">
   <owner>hanxi@chromium.org</owner>
   <owner>xinyiji@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml
index 3f75bb1..6c26946 100644
--- a/tools/metrics/histograms/metadata/media/histograms.xml
+++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -605,7 +605,7 @@
 </histogram>
 
 <histogram name="Media.Audio.Autoplay" enum="AutoplaySource"
-    expires_after="2025-11-25">
+    expires_after="2026-01-25">
   <owner>evliu@google.com</owner>
   <owner>dalecurtis@chromium.org</owner>
   <owner>media-dev-uma@chromium.org</owner>
@@ -613,7 +613,7 @@
 </histogram>
 
 <histogram name="Media.Audio.Capture.DetectedMissingCallbacks"
-    enum="BooleanMissingCallbacks" expires_after="2025-11-23">
+    enum="BooleanMissingCallbacks" expires_after="2026-01-25">
   <owner>guidou@chromium.org</owner>
   <owner>olka@chromium.org</owner>
   <owner>webrtc-audio-uma@google.com</owner>
@@ -887,7 +887,7 @@
 </histogram>
 
 <histogram name="Media.Audio.Capture.Win.InitError" enum="Hresult"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>olka@chromium.org</owner>
   <owner>tommi@chromium.org</owner>
   <owner>guidou@chromium.org</owner>
@@ -6405,7 +6405,7 @@
 </histogram>
 
 <histogram name="Media.Video.Autoplay" enum="AutoplaySource"
-    expires_after="2025-11-25">
+    expires_after="2026-01-25">
   <owner>evliu@google.com</owner>
   <owner>dalecurtis@chromium.org</owner>
   <owner>media-dev-uma@chromium.org</owner>
@@ -6416,7 +6416,7 @@
 </histogram>
 
 <histogram name="Media.Video.Autoplay.Muted.PlayMethod.BecomesVisible"
-    enum="Boolean" expires_after="2025-11-25">
+    enum="Boolean" expires_after="2026-01-25">
   <owner>evliu@google.com</owner>
   <owner>dalecurtis@chromium.org</owner>
   <owner>media-dev-uma@chromium.org</owner>
@@ -6430,7 +6430,7 @@
 </histogram>
 
 <histogram name="Media.Video.Autoplay.Muted.PlayMethod.OffscreenDuration"
-    units="ms" expires_after="2025-11-25">
+    units="ms" expires_after="2026-01-25">
   <owner>evliu@google.com</owner>
   <owner>dalecurtis@chromium.org</owner>
   <owner>media-dev-uma@chromium.org</owner>
@@ -6441,7 +6441,7 @@
 </histogram>
 
 <histogram name="Media.Video.Autoplay.Muted.UnmuteAction" enum="BooleanSuccess"
-    expires_after="2025-11-25">
+    expires_after="2026-01-25">
   <owner>evliu@google.com</owner>
   <owner>dalecurtis@chromium.org</owner>
   <owner>media-dev-uma@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/memory/histograms.xml b/tools/metrics/histograms/metadata/memory/histograms.xml
index 8205eb5..4b12234 100644
--- a/tools/metrics/histograms/metadata/memory/histograms.xml
+++ b/tools/metrics/histograms/metadata/memory/histograms.xml
@@ -1314,7 +1314,7 @@
 
 <histogram
     name="Memory.Experimental.Browser2.Small{ProcessMemoryAllocatorSmall2}"
-    units="KB" expires_after="2025-11-23">
+    units="KB" expires_after="2026-01-25">
   <owner>erikchen@chromium.org</owner>
   <owner>ssid@chromium.org</owner>
   <owner>lizeb@chromium.org</owner>
@@ -1423,7 +1423,7 @@
 
 <histogram
     name="Memory.Experimental.Gpu2.Custom{ProcessMemoryAllocatorCustom2}"
-    units="bytes" expires_after="2025-11-23">
+    units="bytes" expires_after="2026-01-25">
   <owner>sashamcintosh@chromium.org</owner>
   <owner>chromeos-gfx@chromium.org</owner>
   <owner>erikchen@chromium.org</owner>
@@ -1674,7 +1674,7 @@
 
 <histogram
     name="Memory.Experimental.Renderer2.Small{ProcessMemoryAllocatorSmall2}"
-    units="KB" expires_after="2025-11-23">
+    units="KB" expires_after="2026-01-25">
   <owner>erikchen@chromium.org</owner>
   <owner>ssid@chromium.org</owner>
   <owner>lizeb@chromium.org</owner>
@@ -1689,7 +1689,7 @@
 
 <histogram
     name="Memory.Experimental.Renderer2.Tiny{ProcessMemoryAllocatorTiny2}"
-    units="bytes" expires_after="2025-11-23">
+    units="bytes" expires_after="2026-01-25">
   <owner>sashamcintosh@chromium.org</owner>
   <owner>chromeos-gfx@chromium.org</owner>
   <owner>erikchen@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/navigation/histograms.xml b/tools/metrics/histograms/metadata/navigation/histograms.xml
index 77e8605b..9381c2c 100644
--- a/tools/metrics/histograms/metadata/navigation/histograms.xml
+++ b/tools/metrics/histograms/metadata/navigation/histograms.xml
@@ -2780,7 +2780,7 @@
 </histogram>
 
 <histogram name="Navigation.URLLoader.HasClientHintsControllerDelegate"
-    enum="Boolean" expires_after="2025-10-26">
+    enum="Boolean" expires_after="2026-01-25">
   <owner>yyanagisawa@chromium.org</owner>
   <owner>chrome-loading@google.com</owner>
   <summary>
@@ -2987,7 +2987,7 @@
 </histogram>
 
 <histogram name="Navigation.{Stage}ToCompositorCreation" units="ms"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>rakina@chromium.org</owner>
   <owner>bfcache-dev@chromium.org</owner>
   <summary>
@@ -3525,6 +3525,20 @@
   </token>
 </histogram>
 
+<histogram
+    name="Prerender.Experimental.ReusePrerenderHost.PrerenderHostCount.Failed"
+    units="count" expires_after="2025-12-31">
+  <owner>suzukikeita@google.com</owner>
+  <owner>gjc@google.com</owner>
+  <owner>chrome-prerendering@google.com</owner>
+  <owner>chrome-loading@google.com</owner>
+  <summary>
+    Records the number of PrerenderHosts when we failed to find a reuseable
+    PrerenderHost. The UMA is recorded each time a new PrerenderHost is
+    constructed and we failed to find a reuseable PrerenderHost.
+  </summary>
+</histogram>
+
 <histogram name="Prerender.Experimental.Search.ResponseReuseCount"
     units="count" expires_after="2025-09-22">
   <owner>lingqi@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/net/enums.xml b/tools/metrics/histograms/metadata/net/enums.xml
index 4098882..2b55269 100644
--- a/tools/metrics/histograms/metadata/net/enums.xml
+++ b/tools/metrics/histograms/metadata/net/enums.xml
@@ -2920,6 +2920,21 @@
   <int value="3" label="imported from socket"/>
 </enum>
 
+<!-- LINT.IfChange(SqlDiskCacheFakeIndexFileError) -->
+
+<enum name="SqlDiskCacheFakeIndexFileError">
+  <int value="0" label="OkNew"/>
+  <int value="1" label="OkExisting"/>
+  <int value="2" label="CreateFileFailed"/>
+  <int value="3" label="WriteFileFailed"/>
+  <int value="4" label="WrongFileSize"/>
+  <int value="5" label="OpenFileFailed"/>
+  <int value="6" label="ReadFileFailed"/>
+  <int value="7" label="WrongMagicNumber"/>
+</enum>
+
+<!-- LINT.ThenChange(//net/disk_cache/sql/sql_backend_impl.h:FakeIndexFileError) -->
+
 <!-- LINT.IfChange(SqlDiskCacheStoreError) -->
 
 <enum name="SqlDiskCacheStoreError">
diff --git a/tools/metrics/histograms/metadata/net/histograms.xml b/tools/metrics/histograms/metadata/net/histograms.xml
index d6bfe0d..960ac52d 100644
--- a/tools/metrics/histograms/metadata/net/histograms.xml
+++ b/tools/metrics/histograms/metadata/net/histograms.xml
@@ -4134,7 +4134,7 @@
 </histogram>
 
 <histogram name="Net.QuicConnection.ServerAllowsActiveMigrationForMultiPort"
-    enum="BooleanEnabled" expires_after="2025-11-25">
+    enum="BooleanEnabled" expires_after="2026-01-25">
   <owner>renjietang@chromium.org</owner>
   <owner>src/net/OWNERS</owner>
   <summary>
@@ -6952,7 +6952,7 @@
 
 <histogram
     name="Net.SessionCreate.GoogleSearch.Preconnect2.{ProtocolType}.IsSessionReused"
-    enum="Boolean" expires_after="2025-11-23">
+    enum="Boolean" expires_after="2026-01-25">
   <owner>suzukikeita@chromium.org</owner>
   <owner>blink-network-stack@google.com</owner>
   <summary>
@@ -7529,7 +7529,7 @@
 </histogram>
 
 <histogram name="Net.SqlDiskCache.Backend.SqliteError"
-    enum="SqliteLoggedResultCode" expires_after="2025-09-09">
+    enum="SqliteLoggedResultCode" expires_after="2025-12-09">
   <owner>horo@chromium.org</owner>
   <owner>src/net/OWNERS</owner>
   <summary>
@@ -7539,7 +7539,7 @@
 </histogram>
 
 <histogram name="Net.SqlDiskCache.Backend.{MethodName}.Result"
-    enum="SqlDiskCacheStoreError" expires_after="2025-09-09">
+    enum="SqlDiskCacheStoreError" expires_after="2025-12-09">
   <owner>horo@chromium.org</owner>
   <owner>src/net/OWNERS</owner>
   <summary>
@@ -7551,7 +7551,7 @@
 </histogram>
 
 <histogram name="Net.SqlDiskCache.Backend.{MethodName}.ResultWithCorruption"
-    enum="SqlDiskCacheStoreError" expires_after="2025-09-09">
+    enum="SqlDiskCacheStoreError" expires_after="2025-12-09">
   <owner>horo@chromium.org</owner>
   <owner>src/net/OWNERS</owner>
   <summary>
@@ -7563,7 +7563,7 @@
 </histogram>
 
 <histogram name="Net.SqlDiskCache.Backend.{MethodName}.{TimeType}"
-    units="microseconds" expires_after="2025-09-09">
+    units="microseconds" expires_after="2025-12-09">
   <owner>horo@chromium.org</owner>
   <owner>src/net/OWNERS</owner>
   <summary>
@@ -7598,7 +7598,7 @@
 </histogram>
 
 <histogram name="Net.SqlDiskCache.ExclusiveOperationDelay" units="microseconds"
-    expires_after="2025-09-09">
+    expires_after="2025-12-09">
   <owner>horo@chromium.org</owner>
   <owner>src/net/OWNERS</owner>
   <summary>
@@ -7610,8 +7610,19 @@
   </summary>
 </histogram>
 
+<histogram name="Net.SqlDiskCache.FakeIndexFileError"
+    enum="SqlDiskCacheFakeIndexFileError" expires_after="2025-12-09">
+  <owner>horo@chromium.org</owner>
+  <owner>src/net/OWNERS</owner>
+  <summary>
+    Records the error status that can occur during the fake index file check of
+    the SQL-based disk cache. This check is performed during the cache
+    initialization.
+  </summary>
+</histogram>
+
 <histogram name="Net.SqlDiskCache.NormalOperationDelay" units="microseconds"
-    expires_after="2025-09-09">
+    expires_after="2025-12-09">
   <owner>horo@chromium.org</owner>
   <owner>src/net/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
index a3d2918f..b28ff4b 100644
--- a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
+++ b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
@@ -736,7 +736,7 @@
 </histogram>
 
 <histogram name="NewTabPage.Drive.FileClick" units="index"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>rtatum@google.com</owner>
   <owner>tiborg@chromium.org</owner>
   <owner>chrome-desktop-ntp@google.com</owner>
@@ -807,7 +807,7 @@
 </histogram>
 
 <histogram name="NewTabPage.Footer.Click" enum="FooterElement"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>temao@chromium.org</owner>
   <owner>tiborg@chromium.org</owner>
   <owner>chrome-desktop-ntp@google.com</owner>
@@ -823,7 +823,7 @@
 </histogram>
 
 <histogram name="NewTabPage.Footer.CustomizeChromeOpened"
-    enum="FooterCustomizeChromeEntryPoint" expires_after="2025-11-23">
+    enum="FooterCustomizeChromeEntryPoint" expires_after="2026-01-25">
   <owner>temao@chromium.org</owner>
   <owner>tiborg@chromium.org</owner>
   <owner>chrome-desktop-ntp@google.com</owner>
@@ -1713,7 +1713,7 @@
 </histogram>
 
 <histogram name="NewTabPage.MostVisited.NumberOfCustomTilesOnFirstNtp"
-    units="units" expires_after="2025-11-23">
+    units="units" expires_after="2026-01-25">
   <owner>fredmello@chromium.org</owner>
   <owner>huangs@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/notifications/histograms.xml b/tools/metrics/histograms/metadata/notifications/histograms.xml
index 575ea60..1f1f914 100644
--- a/tools/metrics/histograms/metadata/notifications/histograms.xml
+++ b/tools/metrics/histograms/metadata/notifications/histograms.xml
@@ -129,7 +129,7 @@
 </histogram>
 
 <histogram name="Notifications.Android.ImageMemorySizeInKB" units="KB"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>peilinwang@google.com</owner>
   <owner>clank-performance-team@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/omnibox/histograms.xml b/tools/metrics/histograms/metadata/omnibox/histograms.xml
index 0103598d..d9426fb1 100644
--- a/tools/metrics/histograms/metadata/omnibox/histograms.xml
+++ b/tools/metrics/histograms/metadata/omnibox/histograms.xml
@@ -1575,7 +1575,7 @@
 </histogram>
 
 <histogram name="Omnibox.KeywordCount{KeywordType}" units="count"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>mahmadi@chromium.org</owner>
   <owner>chrome-desktop-search@google.com</owner>
   <summary>
@@ -2391,7 +2391,7 @@
 </histogram>
 
 <histogram name="Omnibox.SearchPrefetch.DuplicateSearchTermsAge" units="ms"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>lingqi@chromium.org</owner>
   <owner>nhiroki@chromium.org</owner>
   <owner>chrome-prerendering@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/optimization/histograms.xml b/tools/metrics/histograms/metadata/optimization/histograms.xml
index 2b286347..3f4f5f0 100644
--- a/tools/metrics/histograms/metadata/optimization/histograms.xml
+++ b/tools/metrics/histograms/metadata/optimization/histograms.xml
@@ -1684,7 +1684,7 @@
 
 <histogram
     name="OptimizationGuide.PageContentAnnotations.GoogleSearchMetadataExtracted"
-    enum="Boolean" expires_after="2025-11-23">
+    enum="Boolean" expires_after="2026-01-25">
   <owner>sophiechang@chromium.org</owner>
   <owner>chrome-intelligence-core@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml
index 59b17af..54102d57 100644
--- a/tools/metrics/histograms/metadata/others/histograms.xml
+++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -651,7 +651,7 @@
 
 <histogram
     name="Ads.InterestGroup.Auction.BidderWorkletIsolateTotalHeapSizeKilobytes"
-    units="KB" expires_after="2025-11-23">
+    units="KB" expires_after="2026-01-25">
   <owner>abigailkatcoff@google.com</owner>
   <owner>privacy-sandbox-dev@chromium.org</owner>
   <summary>
@@ -1655,7 +1655,7 @@
 
 <histogram
     name="Ads.InterestGroup.Auction.{WorkletType}.RequestWorkletServiceOutcome"
-    enum="RequestWorkletServiceOutcome" expires_after="2025-11-23">
+    enum="RequestWorkletServiceOutcome" expires_after="2026-01-25">
   <owner>abigailkatcoff@chromium.org</owner>
   <owner>privacy-sandbox-dev@chromium.org</owner>
   <summary>
@@ -3402,7 +3402,7 @@
 </histogram>
 
 <histogram name="ComponentUpdater.Calls" enum="ComponentUpdaterCalls"
-    expires_after="2025-11-20">
+    expires_after="2026-01-25">
   <owner>sorin@chromium.org</owner>
   <owner>src/components/component_updater/OWNERS</owner>
   <summary>
@@ -3425,21 +3425,21 @@
 </histogram>
 
 <histogram name="ComponentUpdater.UpdateCompleteError"
-    enum="UpdateClientErrors" expires_after="2025-11-20">
+    enum="UpdateClientErrors" expires_after="2026-01-25">
   <owner>sorin@chromium.org</owner>
   <owner>src/components/component_updater/OWNERS</owner>
   <summary>The result of an install or an update check.</summary>
 </histogram>
 
 <histogram name="ComponentUpdater.UpdateCompleteResult" enum="BooleanError"
-    expires_after="2025-11-20">
+    expires_after="2026-01-25">
   <owner>sorin@chromium.org</owner>
   <owner>src/components/component_updater/OWNERS</owner>
   <summary>The result of an install or an update check.</summary>
 </histogram>
 
 <histogram name="ComponentUpdater.UpdateCompleteTime" units="ms"
-    expires_after="2025-11-20">
+    expires_after="2026-01-25">
   <owner>sorin@chromium.org</owner>
   <owner>src/components/component_updater/OWNERS</owner>
   <summary>
@@ -6074,7 +6074,7 @@
 </histogram>
 
 <histogram name="Mojo.Channel.WriteToReadLatencyUs" units="microseconds"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>lizeb@chromium.org</owner>
   <owner>rockot@google.com</owner>
   <summary>
@@ -7964,7 +7964,7 @@
 </histogram>
 
 <histogram name="ReadingList.Read.Number" units="count"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>gambard@chromium.org</owner>
   <owner>bling-team@google.com</owner>
   <summary>Number of read entries in reading list.</summary>
@@ -7980,7 +7980,7 @@
 </histogram>
 
 <histogram name="ReadingList.Unread.Number" units="count"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>gambard@chromium.org</owner>
   <owner>bling-team@google.com</owner>
   <summary>Number of unread entries in reading list.</summary>
@@ -8499,7 +8499,7 @@
 </histogram>
 
 <histogram name="Servicification.Startup3" enum="ServicificationStartupMode"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>hanxi@chromium.org</owner>
   <owner>yfriedman@chromium.org</owner>
   <owner>hnakashima@chromium.org</owner>
@@ -9803,7 +9803,7 @@
 </histogram>
 
 <histogram name="UpdateClient.Component.UpdateCheckResult"
-    enum="UpdateClientUpdateCheckResult" expires_after="2025-11-20">
+    enum="UpdateClientUpdateCheckResult" expires_after="2026-01-25">
   <owner>noahrose@google.com</owner>
   <owner>sorin@chromium.org</owner>
   <owner>waffles@chromium.org</owner>
@@ -9814,7 +9814,7 @@
 </histogram>
 
 <histogram name="UpdateClient.Component.Updated" enum="Boolean"
-    expires_after="2025-11-20">
+    expires_after="2026-01-25">
   <owner>noahrose@google.com</owner>
   <owner>sorin@chromium.org</owner>
   <owner>waffles@chromium.org</owner>
@@ -9822,7 +9822,7 @@
 </histogram>
 
 <histogram name="UpdateClient.CrxDownloader.DownloadCompleteSuccess"
-    enum="Boolean" expires_after="2025-11-20">
+    enum="Boolean" expires_after="2026-01-25">
   <owner>noahrose@google.com</owner>
   <owner>sorin@chromium.org</owner>
   <owner>waffles@chromium.org</owner>
@@ -9849,7 +9849,7 @@
 </histogram>
 
 <histogram name="UpdateClient.UnzipTime{AppID}" units="ms"
-    expires_after="2025-11-20">
+    expires_after="2026-01-25">
   <owner>noahrose@google.com</owner>
   <owner>sorin@chromium.org</owner>
   <owner>waffles@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/page/histograms.xml b/tools/metrics/histograms/metadata/page/histograms.xml
index df19b7b6..180c047 100644
--- a/tools/metrics/histograms/metadata/page/histograms.xml
+++ b/tools/metrics/histograms/metadata/page/histograms.xml
@@ -2778,7 +2778,7 @@
 
 <histogram
     name="PageLoad.Clients{ObservedNavigation}.Leakage2.RendererProcessCreatedBeforeNav{BackgroundSuffix}{HiddenSuffix}{IncognitoSuffix}{RTTBucketSuffix}"
-    enum="Boolean" expires_after="2025-08-10">
+    enum="Boolean" expires_after="2026-01-23">
   <owner>sisidovski@chromium.org</owner>
   <owner>rakina@chromium.org</owner>
   <owner>chrome-loading@google.com</owner>
@@ -2824,7 +2824,7 @@
 
 <histogram
     name="PageLoad.Clients{ObservedNavigation}.Leakage2.{NavigationType}To{NavigationAbandonReason}{BackgroundSuffix}{HiddenSuffix}{IncognitoSuffix}{RTTBucketSuffix}"
-    units="ms" expires_after="2025-08-10">
+    units="ms" expires_after="2026-01-23">
   <owner>sisidovski@chromium.org</owner>
   <owner>rakina@chromium.org</owner>
   <owner>chrome-loading@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/password/enums.xml b/tools/metrics/histograms/metadata/password/enums.xml
index e8b1f9c99..9a85374 100644
--- a/tools/metrics/histograms/metadata/password/enums.xml
+++ b/tools/metrics/histograms/metadata/password/enums.xml
@@ -50,6 +50,7 @@
   <int value="15" label="'Manage plus addresses' link in the password sheet"/>
   <int value="16" label="'Manage loyalty cards' link"/>
   <int value="17" label="'Verify it's you' link"/>
+  <int value="18" label="'Autofill suggestion from accessory sheet"/>
 </enum>
 
 <enum name="AccessorySheetTrigger">
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml
index 7c83a20..0765936 100644
--- a/tools/metrics/histograms/metadata/password/histograms.xml
+++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -171,13 +171,14 @@
   </summary>
 </histogram>
 
-<histogram name="KeyboardAccessory.AccessoryActionSelected"
-    enum="AccessoryAction" expires_after="2025-12-14">
+<histogram name="KeyboardAccessory.AccessoryActionSelected2"
+    enum="AccessoryAction" expires_after="2026-02-04">
   <owner>friedrichh@chromium.org</owner>
   <owner>ioanap@chromium.org</owner>
   <summary>
     Android only. Records whenever users select an action in the accessory bar
-    or one of its sheets.
+    or one of its sheets. Actions include autofill suggestions from bar and
+    accessory sheets.
   </summary>
 </histogram>
 
@@ -274,7 +275,7 @@
 </histogram>
 
 <histogram name="Passkeys.IOSMigration" enum="PasskeysMigrationStatus"
-    expires_after="2025-11-21">
+    expires_after="2026-01-25">
   <owner>sugoi@chromium.org</owner>
   <owner>tmartino@chromium.org</owner>
   <summary>
@@ -627,7 +628,7 @@
 </histogram>
 
 <histogram name="PasswordManager.AddCredentialFromSettings.UserAction2"
-    enum="AddCredentialFromSettingsUserInteractions" expires_after="2025-11-23">
+    enum="AddCredentialFromSettingsUserInteractions" expires_after="2026-01-25">
   <owner>vidhanj@google.com</owner>
   <summary>
     Records the user actions performed when a new credential is added from
@@ -1742,7 +1743,7 @@
 </histogram>
 
 <histogram name="PasswordManager.FirstWaitForUsernameReason"
-    enum="PasswordManagerFirstWaitForUsernameReason" expires_after="2025-11-23">
+    enum="PasswordManagerFirstWaitForUsernameReason" expires_after="2026-01-25">
   <owner>kazinova@google.com</owner>
   <owner>battre@chromium.org</owner>
   <summary>
@@ -2232,7 +2233,7 @@
 <histogram
     name="PasswordManager.LoginDatabase.ShouldDeleteUndecryptablePasswords"
     enum="LoginDatabaseShouldDeleteUndecryptablePasswords"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>sygiet@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -3228,7 +3229,7 @@
 
 <histogram name="PasswordManager.PasswordSharingIOS.UserAction"
     enum="PasswordManager.PasswordSharingIOSUserAction"
-    expires_after="2025-11-25">
+    expires_after="2026-01-25">
   <owner>rgod@google.com</owner>
   <owner>mamir@chromium.org</owner>
   <summary>
@@ -3660,7 +3661,7 @@
 <histogram
     name="PasswordManager.ProcessIncomingPasswordSharingInvitationResult"
     enum="PasswordManager.ProcessIncomingPasswordSharingInvitationResult"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>mamir@chromium.org</owner>
   <owner>rushans@google.com</owner>
   <component>1457410</component>
diff --git a/tools/metrics/histograms/metadata/performance_manager/histograms.xml b/tools/metrics/histograms/metadata/performance_manager/histograms.xml
index 06aa787..7b9de032 100644
--- a/tools/metrics/histograms/metadata/performance_manager/histograms.xml
+++ b/tools/metrics/histograms/metadata/performance_manager/histograms.xml
@@ -121,7 +121,7 @@
 </histogram>
 
 <histogram name="CPU.Experimental.EstimatedFrequencyAsPercentOfMax.{CoreType}"
-    units="%" expires_after="2025-11-23">
+    units="%" expires_after="2026-01-25">
   <owner>anthonyvd@chromium.org</owner>
   <owner>catan-team@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/platform/histograms.xml b/tools/metrics/histograms/metadata/platform/histograms.xml
index d6c6cc68..b08e5ab 100644
--- a/tools/metrics/histograms/metadata/platform/histograms.xml
+++ b/tools/metrics/histograms/metadata/platform/histograms.xml
@@ -699,7 +699,7 @@
 </histogram>
 
 <histogram name="Platform.DeviceManagement.InstallAttributesStatus"
-    enum="InstallAttributesStatus" expires_after="2025-11-23">
+    enum="InstallAttributesStatus" expires_after="2026-01-25">
   <owner>sadmansakib@google.com</owner>
   <owner>cros-hwsec-userland-eng+uma@google.com</owner>
   <summary>
@@ -2006,7 +2006,7 @@
 </histogram>
 
 <histogram name="Platform.Odml.CpuUsageMilliPercent" units="1/1000ths of %"
-    expires_after="2025-11-22">
+    expires_after="2026-01-25">
   <owner>yich@google.com</owner>
   <owner>cros-odml-foundations-eng@google.com</owner>
   <summary>
@@ -2026,7 +2026,7 @@
 </histogram>
 
 <histogram name="Platform.Odml.PeakTotalRssMemoryKb" units="KB"
-    expires_after="2025-11-22">
+    expires_after="2026-01-25">
   <owner>yich@google.com</owner>
   <owner>cros-odml-foundations-eng@google.com</owner>
   <summary>
@@ -2036,7 +2036,7 @@
 </histogram>
 
 <histogram name="Platform.Odml.PeakTotalSwapMemoryKb" units="KB"
-    expires_after="2025-11-22">
+    expires_after="2026-01-25">
   <owner>yich@google.com</owner>
   <owner>cros-odml-foundations-eng@google.com</owner>
   <summary>
@@ -2046,7 +2046,7 @@
 </histogram>
 
 <histogram name="Platform.Odml.TotalMallocMemoryKb" units="KB"
-    expires_after="2025-11-22">
+    expires_after="2026-01-25">
   <owner>yich@google.com</owner>
   <owner>cros-odml-foundations-eng@google.com</owner>
   <summary>
@@ -2055,7 +2055,7 @@
 </histogram>
 
 <histogram name="Platform.Odml.TotalRssMemoryKb" units="KB"
-    expires_after="2025-11-22">
+    expires_after="2026-01-25">
   <owner>yich@google.com</owner>
   <owner>cros-odml-foundations-eng@google.com</owner>
   <summary>
@@ -2065,7 +2065,7 @@
 </histogram>
 
 <histogram name="Platform.Odml.TotalSwapMemoryKb" units="KB"
-    expires_after="2025-11-22">
+    expires_after="2026-01-25">
   <owner>yich@google.com</owner>
   <owner>cros-odml-foundations-eng@google.com</owner>
   <summary>
@@ -3087,7 +3087,7 @@
 </histogram>
 
 <histogram name="Platform.{GSC}.FlashLog" enum="Cr50FlashLogs"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>apronin@chromium.org</owner>
   <owner>vbendeb@chromium.org</owner>
   <owner>cros-hwsec+uma@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/power/histograms.xml b/tools/metrics/histograms/metadata/power/histograms.xml
index f8f824c7..088ff955d 100644
--- a/tools/metrics/histograms/metadata/power/histograms.xml
+++ b/tools/metrics/histograms/metadata/power/histograms.xml
@@ -1550,7 +1550,7 @@
 </histogram>
 
 <histogram name="Power.KernelSuspendTimeOnBattery" units="ms"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>puthik@chromium.org</owner>
   <owner>mhiramat@google.com</owner>
   <owner>chromeos-platform-power@google.com</owner>
@@ -1787,7 +1787,7 @@
 </histogram>
 
 <histogram name="Power.SmartCharging.Messages" enum="SmartChargingMessages"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>alanlxl@chromium.org</owner>
   <owner>amoylan@chromium.org</owner>
   <summary>Type of messages that are reported by smart charging.</summary>
@@ -1853,7 +1853,7 @@
 </histogram>
 
 <histogram name="Power.SuspendResult" enum="SuspendResult"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>puthik@chromium.org</owner>
   <owner>chromeos-platform-power@google.com</owner>
   <summary>
@@ -1904,7 +1904,7 @@
 </histogram>
 
 <histogram name="Power.UserBrightnessAdjustmentsPerSessionOnBattery"
-    units="units" expires_after="2025-11-23">
+    units="units" expires_after="2026-01-25">
   <owner>alanlxl@chromium.org</owner>
   <owner>amoylan@chromium.org</owner>
   <owner>napper@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/printing/histograms.xml b/tools/metrics/histograms/metadata/printing/histograms.xml
index aa87a2c..ae0b50e 100644
--- a/tools/metrics/histograms/metadata/printing/histograms.xml
+++ b/tools/metrics/histograms/metadata/printing/histograms.xml
@@ -161,7 +161,7 @@
 </histogram>
 
 <histogram name="Printing.CUPS.IppDeviceReachable" enum="BooleanSuccess"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>bmgordon@chromium.org</owner>
   <owner>cros-printing-dev@chromium.org</owner>
   <summary>
@@ -231,7 +231,7 @@
 </histogram>
 
 <histogram name="Printing.CUPS.NearbyNetworkDiscoveredPrintersCount"
-    units="printers" expires_after="2025-11-23">
+    units="printers" expires_after="2026-01-25">
   <owner>bmgordon@chromium.org</owner>
   <owner>project-bolton@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/profile/histograms.xml b/tools/metrics/histograms/metadata/profile/histograms.xml
index b833d0a..8fc5fb9 100644
--- a/tools/metrics/histograms/metadata/profile/histograms.xml
+++ b/tools/metrics/histograms/metadata/profile/histograms.xml
@@ -898,7 +898,7 @@
 </histogram>
 
 <histogram name="ProfilePicker.FirstRun.OrganizationAvailableTiming" units="ms"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>dgn@chromium.org</owner>
   <owner>chrome-signin-team@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
index 22b7529d..d700d338 100644
--- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
+++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -2010,7 +2010,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.IOS.TotalDelay2{UserCategory}" units="ms"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>danieltwhite@google.com</owner>
   <owner>joemerramos@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
@@ -2254,7 +2254,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.PhishySite.{UserEvent}" units="count"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>skrakowi@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -2270,7 +2270,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.Pref.Daily.Extended" enum="BooleanEnabled"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -2492,7 +2492,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.RT.CacheManager.CleanupReachedThreshold"
-    units="entries" expires_after="2025-11-23">
+    units="entries" expires_after="2026-01-25">
   <owner>thefrog@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -3290,7 +3290,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.Triggers.SuspiciousSite.Event"
-    enum="SuspiciousSiteTriggerEvent" expires_after="2025-11-23">
+    enum="SuspiciousSiteTriggerEvent" expires_after="2026-01-25">
   <owner>vakh@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/sb_client/histograms.xml b/tools/metrics/histograms/metadata/sb_client/histograms.xml
index 0e7b542..6c8bb9f 100644
--- a/tools/metrics/histograms/metadata/sb_client/histograms.xml
+++ b/tools/metrics/histograms/metadata/sb_client/histograms.xml
@@ -520,7 +520,7 @@
 </histogram>
 
 <histogram name="SBClientPhishing.ClassifyThresholdsResult"
-    enum="SBClientDetectionClassifyThresholdsResult" expires_after="2025-11-23">
+    enum="SBClientDetectionClassifyThresholdsResult" expires_after="2026-01-25">
   <owner>andysjlim@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -790,7 +790,7 @@
 </histogram>
 
 <histogram name="SBClientPhishing.OnDeviceModelDownloadSuccess"
-    enum="BooleanSuccess" expires_after="2025-11-25">
+    enum="BooleanSuccess" expires_after="2026-01-25">
   <owner>andysjlim@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -836,7 +836,7 @@
 </histogram>
 
 <histogram name="SBClientPhishing.OnDeviceModelFetchTime" units="ms"
-    expires_after="2025-11-25">
+    expires_after="2026-01-25">
   <owner>andysjlim@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/security/histograms.xml b/tools/metrics/histograms/metadata/security/histograms.xml
index f480391c..cdc5921 100644
--- a/tools/metrics/histograms/metadata/security/histograms.xml
+++ b/tools/metrics/histograms/metadata/security/histograms.xml
@@ -342,7 +342,7 @@
 </histogram>
 
 <histogram name="Security.JSONParser.ParsingTime" units="microseconds"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>djmitche@chromium.org</owner>
   <owner>chrome-platform-security@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/service/enums.xml b/tools/metrics/histograms/metadata/service/enums.xml
index a57de340..1b61120e 100644
--- a/tools/metrics/histograms/metadata/service/enums.xml
+++ b/tools/metrics/histograms/metadata/service/enums.xml
@@ -229,6 +229,22 @@
   <int value="2" label="Read data error"/>
 </enum>
 
+<!-- LINT.IfChange(ServiceWorkerRegistrationDeleteInitiator) -->
+
+<enum name="ServiceWorkerRegistrationDeleteInitiator">
+  <int value="0" label="Triggered by navigator.serviceWorker.unregister()"/>
+  <int value="1" label="Triggered by clearing site data"/>
+  <int value="2" label="Triggered by an emergency force-delete"/>
+  <int value="3" label="Triggered by a registration failure"/>
+  <int value="4"
+      label="Triggered via the public C++ API (e.g., extensions, DevTools)"/>
+  <int value="5"
+      label="Triggered by a user action on chrome://serviceworker-internals"/>
+  <int value="6" label="Triggered from a test"/>
+</enum>
+
+<!-- LINT.ThenChange(//content/browser/service_worker/service_worker_registration.h:DeleteInitiator) -->
+
 <enum name="ServiceWorkerRouterEvaluatorErrorEnums">
   <int value="0" label="kNoError"/>
   <int value="1" label="kInvalidType"/>
diff --git a/tools/metrics/histograms/metadata/service/histograms.xml b/tools/metrics/histograms/metadata/service/histograms.xml
index be111270..2949a0a 100644
--- a/tools/metrics/histograms/metadata/service/histograms.xml
+++ b/tools/metrics/histograms/metadata/service/histograms.xml
@@ -526,7 +526,7 @@
 
 <histogram
     name="ServiceWorker.FetchEvent.{Resource}.RaceNetworkRequest.Redirect"
-    enum="Boolean" expires_after="2025-11-23">
+    enum="Boolean" expires_after="2026-01-25">
   <owner>sisidovski@chromium.org</owner>
   <owner>chrome-worker@google.com</owner>
   <summary>
@@ -1336,7 +1336,7 @@
 </histogram>
 
 <histogram name="ServiceWorker.RegisteredStorageKeyCount" units="origins"
-    expires_after="2025-11-20">
+    expires_after="2026-01-25">
   <owner>yyanagisawa@chromium.org</owner>
   <owner>chikamune@chromium.org</owner>
   <owner>chrome-worker@google.com</owner>
@@ -1346,6 +1346,50 @@
   </summary>
 </histogram>
 
+<histogram name="ServiceWorker.Registration.Delete.Initiator"
+    enum="ServiceWorkerRegistrationDeleteInitiator" expires_after="2026-01-25">
+  <owner>yyanagisawa@chromium.org</owner>
+  <owner>chrome-worker@google.com</owner>
+  <summary>
+    The initiator of a service worker registration deletion. This is recorded
+    when a deletion is triggered.
+  </summary>
+</histogram>
+
+<histogram name="ServiceWorker.Registration.Delete.Result.{DeleteInitiator}"
+    enum="ServiceWorkerStatusCode" expires_after="2026-01-23">
+  <owner>yyanagisawa@chromium.org</owner>
+  <owner>chrome-worker@google.com</owner>
+  <summary>
+    The result of deleting a service worker registration. This is recorded when
+    the deletion from the database is complete. The histogram is broken down by
+    the initiator of the deletion.
+  </summary>
+  <token key="DeleteInitiator">
+    <variant name="ByContentPublicApi"
+        summary="Triggered via the public C++ API
+                 (ServiceWorkerContext::UnregisterServiceWorker and
+                 ServiceWorkerContext::UnregisterServiceWorkerImmediately),
+                 typically by extensions or DevTools."/>
+    <variant name="ByDeleteForStorageKey"
+        summary="Triggered by clearing site data."/>
+    <variant name="ByForceDelete"
+        summary="Triggered by an emergency force-delete mechanism (e.g., when
+                 the script can't be read from the disk)."/>
+    <variant name="ByRegistrationFailure"
+        summary="Triggered by a registration failure (e.g., when a
+                 resurrected uninstalling registration fails to be
+                 re-registered)."/>
+    <variant name="ByTest" summary="Triggered from a test."/>
+    <variant name="ByUnregister"
+        summary="Triggered by an explicit call to
+                 navigator.serviceWorker.unregister()."/>
+    <variant name="ByWebUI"
+        summary="Triggered by a user action on the
+                 chrome://serviceworker-internals page."/>
+  </token>
+</histogram>
+
 <histogram name="ServiceWorker.RouterEvaluator.ConditionDepth" units="count"
     expires_after="2025-12-14">
   <owner>yyanagisawa@chromium.org</owner>
@@ -1385,7 +1429,7 @@
 </histogram>
 
 <histogram name="ServiceWorker.RouterEvaluator.MatchedFirstSourceType"
-    enum="ServiceWorkerRouterSourceType" expires_after="2025-08-24">
+    enum="ServiceWorkerRouterSourceType" expires_after="2026-01-23">
   <owner>sisidovski@chromium.org</owner>
   <owner>chrome-worker@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/settings/histograms.xml b/tools/metrics/histograms/metadata/settings/histograms.xml
index 6741c279..22a2b0b 100644
--- a/tools/metrics/histograms/metadata/settings/histograms.xml
+++ b/tools/metrics/histograms/metadata/settings/histograms.xml
@@ -241,7 +241,7 @@
 </histogram>
 
 <histogram name="Settings.ClearBrowsingData.OpenMyActivity"
-    enum="ClearBrowsingDataMyActivityNavigation" expires_after="2025-11-23">
+    enum="ClearBrowsingDataMyActivityNavigation" expires_after="2026-01-25">
   <owner>andzaytsev@google.com</owner>
   <owner>chrome-privacy-controls@google.com</owner>
   <summary>
@@ -250,7 +250,7 @@
 </histogram>
 
 <histogram name="Settings.Cookies.TrackingProtectionRedirect"
-    enum="BooleanRedirected" expires_after="2025-11-20">
+    enum="BooleanRedirected" expires_after="2026-01-25">
   <owner>mjenn@google.com</owner>
   <owner>koilos@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/signin/histograms.xml b/tools/metrics/histograms/metadata/signin/histograms.xml
index 691b9885..b387098 100644
--- a/tools/metrics/histograms/metadata/signin/histograms.xml
+++ b/tools/metrics/histograms/metadata/signin/histograms.xml
@@ -463,7 +463,7 @@
 </histogram>
 
 <histogram name="Signin.AccountManagementType"
-    enum="AccountManagedStatusFinderOutcome" expires_after="2025-11-25">
+    enum="AccountManagedStatusFinderOutcome" expires_after="2026-01-25">
   <owner>msarda@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <owner>chrome-signin-team@google.com</owner>
@@ -477,7 +477,7 @@
 </histogram>
 
 <histogram name="Signin.AccountManagementTypesSummary"
-    enum="AccountManagementTypesSummary" expires_after="2025-11-25">
+    enum="AccountManagementTypesSummary" expires_after="2026-01-25">
   <owner>msarda@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <owner>chrome-signin-team@google.com</owner>
@@ -510,7 +510,7 @@
 </histogram>
 
 <histogram name="Signin.AccountProfileStartupState2"
-    enum="AccountProfileStartupState" expires_after="2025-11-01">
+    enum="AccountProfileStartupState" expires_after="2026-01-25">
   <owner>jood@google.com</owner>
   <owner>treib@chromium.org</owner>
   <owner>chrome-signin-team@google.com</owner>
@@ -1839,7 +1839,7 @@
 </histogram>
 
 <histogram name="Signin.IOSAccountsOnDeviceManagementTypesHadUnknownTypes"
-    enum="BooleanPresent" expires_after="2025-11-25">
+    enum="BooleanPresent" expires_after="2026-01-25">
   <owner>msarda@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <owner>chrome-signin-team@google.com</owner>
@@ -1850,7 +1850,7 @@
 </histogram>
 
 <histogram name="Signin.IOSAccountsOnDeviceManagementTypesSummary{DeviceType}"
-    enum="AccountManagementTypesSummary" expires_after="2025-11-25">
+    enum="AccountManagementTypesSummary" expires_after="2026-01-25">
   <owner>msarda@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <owner>chrome-signin-team@google.com</owner>
@@ -1896,7 +1896,7 @@
 </histogram>
 
 <histogram name="Signin.IOSChangeProfileReason" enum="IOSChangeProfileReason"
-    expires_after="2025-11-25">
+    expires_after="2026-01-25">
   <owner>jlebel@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <owner>chrome-signin-mobile-team@google.com</owner>
@@ -2541,7 +2541,7 @@
 
 <histogram
     name="Signin.Reconciler.RejectedRequestsDueToThrottler.{RequestType}"
-    units="requests" expires_after="2025-11-23">
+    units="requests" expires_after="2026-01-25">
   <owner>droger@chromium.org</owner>
   <owner>msarda@chromium.org</owner>
   <owner>msalama@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/storage/histograms.xml b/tools/metrics/histograms/metadata/storage/histograms.xml
index 18602d5..ab0cb2a 100644
--- a/tools/metrics/histograms/metadata/storage/histograms.xml
+++ b/tools/metrics/histograms/metadata/storage/histograms.xml
@@ -690,7 +690,7 @@
 </histogram>
 
 <histogram name="LocalStorage.MojoSizeInKB" units="KB"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>fergal@chromium.org</owner>
   <owner>chrome-owp-storage@google.com</owner>
   <summary>
@@ -700,7 +700,7 @@
 </histogram>
 
 <histogram name="LocalStorage.MojoTimeToPrime" units="ms"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>fergal@chromium.org</owner>
   <owner>chrome-owp-storage@google.com</owner>
   <summary>
@@ -710,7 +710,7 @@
 </histogram>
 
 <histogram name="LocalStorage.MojoTimeToPrimeAblationDelay" units="ms"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>fergal@chromium.org</owner>
   <owner>chrome-owp-storage@google.com</owner>
   <summary>
@@ -720,7 +720,7 @@
 </histogram>
 
 <histogram name="LocalStorage.MojoTimeToPrimeFor{LocalStorageSizes}" units="ms"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>fergal@chromium.org</owner>
   <owner>chrome-owp-storage@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/structured_metrics/histograms.xml b/tools/metrics/histograms/metadata/structured_metrics/histograms.xml
index c359298f..6c6e1d1 100644
--- a/tools/metrics/histograms/metadata/structured_metrics/histograms.xml
+++ b/tools/metrics/histograms/metadata/structured_metrics/histograms.xml
@@ -242,7 +242,7 @@
 </histogram>
 
 <histogram name="StructuredMetrics.StorageManager.DiskQuotaExceededDelta"
-    units="KB" expires_after="2025-11-23">
+    units="KB" expires_after="2026-01-25">
   <owner>andrewbregger@google.com</owner>
   <owner>troywang@google.com</owner>
   <owner>chromeos-data-eng@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/sync/histograms.xml b/tools/metrics/histograms/metadata/sync/histograms.xml
index 70c1ca6..3e34f4b 100644
--- a/tools/metrics/histograms/metadata/sync/histograms.xml
+++ b/tools/metrics/histograms/metadata/sync/histograms.xml
@@ -532,7 +532,7 @@
 </histogram>
 
 <histogram name="Sync.ConfigureDataTypeManager.IsGaiaAccountId" enum="Boolean"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>rushans@google.com</owner>
   <owner>mastiz@chromium.org</owner>
   <summary>
@@ -882,7 +882,7 @@
 </histogram>
 
 <histogram name="Sync.DataTypeMetadataConsistency{SyncDataType}"
-    enum="SyncMetadataConsistency" expires_after="2025-11-23">
+    enum="SyncMetadataConsistency" expires_after="2026-01-25">
   <owner>rushans@google.com</owner>
   <owner>mastiz@chromium.org</owner>
   <summary>
@@ -1583,7 +1583,7 @@
 </histogram>
 
 <histogram name="Sync.PendingInvalidationStatus"
-    enum="PendingInvalidationStatus" expires_after="2025-10-12">
+    enum="PendingInvalidationStatus" expires_after="2026-01-25">
   <owner>shabdan@google.com</owner>
   <owner>rushans@google.com</owner>
   <summary>
@@ -2006,7 +2006,7 @@
 </histogram>
 
 <histogram name="Sync.SyncableServiceStartTime{SyncDataType}" units="ms"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>ankushkush@google.com</owner>
   <owner>treib@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/tab/histograms.xml b/tools/metrics/histograms/metadata/tab/histograms.xml
index bbf1bca5..2fcd498a 100644
--- a/tools/metrics/histograms/metadata/tab/histograms.xml
+++ b/tools/metrics/histograms/metadata/tab/histograms.xml
@@ -970,7 +970,7 @@
 </histogram>
 
 <histogram name="TabGroups.NumberOfRootIdsFixed" units="groups"
-    expires_after="2025-11-26">
+    expires_after="2026-01-25">
   <owner>ckitagawa@chromium.org</owner>
   <owner>clank-tab-dev@chromium.org</owner>
   <summary>
@@ -1329,7 +1329,7 @@
 </histogram>
 
 <histogram name="TabGroups.Shortcuts" enum="TabGroupShortcut"
-    expires_after="2025-11-24">
+    expires_after="2026-01-25">
   <owner>dljames@chromium.org</owner>
   <owner>top-chrome-desktop-ui@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/ui/histograms.xml b/tools/metrics/histograms/metadata/ui/histograms.xml
index 2ea8d818..62d6f812 100644
--- a/tools/metrics/histograms/metadata/ui/histograms.xml
+++ b/tools/metrics/histograms/metadata/ui/histograms.xml
@@ -110,7 +110,7 @@
 </variants>
 
 <histogram name="Bubble.{BubbleName}.CloseReason" enum="WidgetClosedReason"
-    expires_after="2025-11-16">
+    expires_after="2026-01-25">
   <owner>kerenzhu@chromium.org</owner>
   <owner>dayeung@chromium.org</owner>
   <owner>temao@chromium.org</owner>
@@ -122,7 +122,7 @@
 </histogram>
 
 <histogram name="Bubble.{BubbleName}.CreateToPresentationTime" units="ms"
-    expires_after="2025-11-16">
+    expires_after="2026-01-25">
   <owner>temao@chromium.org</owner>
   <owner>yuhengh@chromium.org</owner>
   <owner>kerenzhu@chromium.org</owner>
@@ -137,7 +137,7 @@
 </histogram>
 
 <histogram name="Bubble.{BubbleName}.CreateToVisibleTime" units="ms"
-    expires_after="2025-11-16">
+    expires_after="2026-01-25">
   <owner>temao@chromium.org</owner>
   <owner>yuhengh@chromium.org</owner>
   <owner>kerenzhu@chromium.org</owner>
@@ -152,7 +152,7 @@
 </histogram>
 
 <histogram name="Bubble.{BubbleName}.TimeVisible" units="ms"
-    expires_after="2025-11-16">
+    expires_after="2026-01-25">
   <owner>yuhengh@chromium.org</owner>
   <owner>kerenzhu@chromium.org</owner>
   <owner>dayeung@chromium.org</owner>
@@ -611,7 +611,7 @@
 </histogram>
 
 <histogram name="WebUI.TopChrome.Preload.Reason" enum="WebUIPreloadReason"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>kerenzhu@chromium.org</owner>
   <owner>tluk@chromium.org</owner>
   <owner>robliao@chromium.org</owner>
@@ -621,7 +621,7 @@
 </histogram>
 
 <histogram name="WebUI.TopChrome.Preload.Result" enum="WebUIPreloadResult"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>kerenzhu@chromium.org</owner>
   <owner>dayeung@chromium.org</owner>
   <owner>elainechien@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/user_education/histograms.xml b/tools/metrics/histograms/metadata/user_education/histograms.xml
index 851b84c..329fc593 100644
--- a/tools/metrics/histograms/metadata/user_education/histograms.xml
+++ b/tools/metrics/histograms/metadata/user_education/histograms.xml
@@ -216,7 +216,7 @@
 </histogram>
 
 <histogram name="UserEducation.MessageNotShown.TimeInQueue" units="ms"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>dfried@chromium.org</owner>
   <owner>frizzle-team@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/web_core/histograms.xml b/tools/metrics/histograms/metadata/web_core/histograms.xml
index bcf05a4..80270c6c 100644
--- a/tools/metrics/histograms/metadata/web_core/histograms.xml
+++ b/tools/metrics/histograms/metadata/web_core/histograms.xml
@@ -63,7 +63,7 @@
 </variants>
 
 <histogram name="WebCore.DistillabilityUs" units="microseconds"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>wychen@chromium.org</owner>
   <owner>gilmanmh@google.com</owner>
   <summary>
@@ -494,7 +494,7 @@
 </histogram>
 
 <histogram name="WebCore.IndexedDB.RequestDuration2.{RequestType}.Foreground"
-    units="ms" expires_after="2025-11-23">
+    units="ms" expires_after="2026-01-25">
   <owner>estade@chromium.org</owner>
   <owner>chrome-owp-storage@google.com</owner>
   <summary>
@@ -538,7 +538,7 @@
 
 <histogram
     name="WebCore.IndexedDB.Transaction.{TransactionType}.TimeActive2.Foreground"
-    units="ms" expires_after="2025-11-23">
+    units="ms" expires_after="2026-01-25">
   <owner>estade@chromium.org</owner>
   <owner>chrome-owp-storage@google.com</owner>
   <summary>
@@ -568,7 +568,7 @@
 
 <histogram
     name="WebCore.IndexedDB.Transaction.{TransactionType}.TimeQueued.Foreground"
-    units="ms" expires_after="2025-11-23">
+    units="ms" expires_after="2026-01-25">
   <owner>estade@chromium.org</owner>
   <owner>chrome-owp-storage@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/web_rtc/histograms.xml b/tools/metrics/histograms/metadata/web_rtc/histograms.xml
index 48d946e..95bc529 100644
--- a/tools/metrics/histograms/metadata/web_rtc/histograms.xml
+++ b/tools/metrics/histograms/metadata/web_rtc/histograms.xml
@@ -1113,7 +1113,7 @@
 </histogram>
 
 <histogram name="WebRTC.DesktopCapture.Win.WgcCapturerResult"
-    enum="WebRtcWgcCapturerResult" expires_after="2025-11-19">
+    enum="WebRtcWgcCapturerResult" expires_after="2026-01-25">
   <owner>alcooper@chromium.org</owner>
   <owner>henrika@chromium.org</owner>
   <owner>edgecapabilitiesdev@microsoft.com</owner>
@@ -1124,7 +1124,7 @@
 </histogram>
 
 <histogram name="WebRTC.DesktopCapture.Win.WgcCaptureSessionGetFrameResult"
-    enum="WebRtcWgcCaptureSessionGetFrameResult" expires_after="2025-11-19">
+    enum="WebRtcWgcCaptureSessionGetFrameResult" expires_after="2026-01-25">
   <owner>alcooper@chromium.org</owner>
   <owner>henrika@chromium.org</owner>
   <owner>edgecapabilitiesdev@microsoft.com</owner>
@@ -1741,7 +1741,7 @@
 </histogram>
 
 <histogram name="WebRTC.Screenshare.DesktopCapturerFullscreenDetector"
-    enum="Boolean" expires_after="2025-11-16">
+    enum="Boolean" expires_after="2026-01-25">
   <owner>kron@chromium.org</owner>
   <owner>agpalak@chromium.org</owner>
   <owner>rtc-meet-in-chrome@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/webapps/histograms.xml b/tools/metrics/histograms/metadata/webapps/histograms.xml
index 8afddae1..c3c8846 100644
--- a/tools/metrics/histograms/metadata/webapps/histograms.xml
+++ b/tools/metrics/histograms/metadata/webapps/histograms.xml
@@ -1663,7 +1663,7 @@
 </histogram>
 
 <histogram name="WebApp.Isolated.UpdateError" enum="IsolatedWebAppUpdateError"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>giovax@chromium.org</owner>
   <owner>pwa-commercial@google.com</owner>
   <owner>src/chrome/browser/web_applications/isolated_web_apps/OWNERS</owner>
@@ -1678,7 +1678,7 @@
 </histogram>
 
 <histogram name="WebApp.Isolated.UpdateSuccess" enum="BooleanSuccess"
-    expires_after="2025-11-23">
+    expires_after="2026-01-25">
   <owner>giovax@chromium.org</owner>
   <owner>pwa-commercial@google.com</owner>
   <owner>src/chrome/browser/web_applications/isolated_web_apps/OWNERS</owner>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index 2e6dcf8..a4c82a16 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -9342,6 +9342,14 @@
       https://fetch.spec.whatwg.org/#http-redirect-fetch.
     </summary>
   </metric>
+  <metric name="NumRetries">
+    <summary>
+      The number of retries a fetch keepalive request loader has experienced so
+      far when the event is logged.
+
+      Note that the maximum value is 10.
+    </summary>
+  </metric>
   <metric name="PreviousStage" enum="FetchKeepAliveRequestStage">
     <summary>
       An enum representing the previous stage of the fetch keepalive request
@@ -9365,6 +9373,20 @@
       network::URLLoaderCompletionStatus.extended_error_code.
     </summary>
   </metric>
+  <metric name="RequestRetried.ErrorCode">
+    <summary>
+      An integer representing the error code of the request when it reaches the
+      kRequestRetried stage. This comes from
+      network::URLLoaderCompletionStatus.error_code.
+    </summary>
+  </metric>
+  <metric name="RequestRetried.ExtendedErrorCode">
+    <summary>
+      An integer representing the extended error code of the request when it
+      reaches the kRequestRetried stage. This comes from
+      network::URLLoaderCompletionStatus.extended_error_code.
+    </summary>
+  </metric>
   <metric name="RequestType" enum="FetchKeepAliveRequestType">
     <summary>
       An enum representing the type of the fetch keepalive request. It tells
@@ -9438,6 +9460,14 @@
       Only set when the stage is reached.
     </summary>
   </metric>
+  <metric name="TimeDelta.RequestRetried">
+    <summary>
+      The time difference (in milliseconds) between the
+      &quot;RequestRetried&quot; stage and the &quot;LoaderCreated&quot; stage.
+
+      Only set when the stage is reached.
+    </summary>
+  </metric>
   <metric name="TimeDelta.RequestStarted">
     <summary>
       The time difference (in milliseconds) between the
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml
index 15b6171..161d371 100644
--- a/tools/traffic_annotation/summary/annotations.xml
+++ b/tools/traffic_annotation/summary/annotations.xml
@@ -306,7 +306,7 @@
  <item id="fast_pair_image_decoder" added_in_milestone="103" content_hash_code="03a98cf1" os_list="chromeos" file_path="ash/quick_pair/repository/fast_pair/fast_pair_image_decoder_impl.cc" />
  <item id="drivefs_http_client" added_in_milestone="104" content_hash_code="042b8f2c" os_list="chromeos" file_path="chromeos/ash/components/drivefs/drivefs_http_client.cc" />
  <item id="printing_server_printers_query" added_in_milestone="106" content_hash_code="06f4759c" os_list="chromeos" file_path="chrome/browser/ash/printing/server_printers_fetcher.cc" />
- <item id="download_bubble_retry_download" added_in_milestone="105" content_hash_code="000b1439" os_list="linux,windows,chromeos" file_path="chrome/browser/download/bubble/download_bubble_ui_controller.cc" />
+ <item id="download_bubble_retry_download" added_in_milestone="105" content_hash_code="000b1439" os_list="linux,windows" file_path="chrome/browser/download/bubble/download_bubble_ui_controller.cc" />
  <item id="quick_answers_loader" added_in_milestone="105" content_hash_code="06f129c2" os_list="chromeos" file_path="chromeos/components/quick_answers/result_loader.cc" />
  <item id="chrome_search_suggest_service" added_in_milestone="105" content_hash_code="04d973c6" os_list="linux,windows,android,chromeos" file_path="components/search/start_suggest_service.cc" />
  <item id="speculation_rules_prefetch_probe" added_in_milestone="105" content_hash_code="04341e21" os_list="linux,windows,android,chromeos" file_path="content/browser/preloading/prefetch/prefetch_origin_prober.cc" />
@@ -373,7 +373,7 @@
  <item id="glanceables_classroom_integration" added_in_milestone="115" content_hash_code="048f5ccb" os_list="chromeos" file_path="chrome/browser/ui/ash/glanceables/glanceables_classroom_client_impl.cc" />
  <item id="promise_app_service_download_icon" added_in_milestone="115" content_hash_code="00521032" os_list="chromeos" file_path="chrome/browser/apps/app_service/promise_apps/promise_app_service.cc" />
  <item id="iwa_update_manifest_fetcher" added_in_milestone="116" type="completing" content_hash_code="0031297e" os_list="linux,windows,chromeos" semantics_fields="4,5,7,8,9" policy_fields="-1" file_path="chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest_fetcher.cc" />
- <item id="iwa_bundle_downloader" added_in_milestone="116" type="completing" content_hash_code="03aab028" os_list="linux,windows,chromeos" semantics_fields="4,5,7,8,9" policy_fields="-1" file_path="chrome/browser/web_applications/isolated_web_apps/isolated_web_app_downloader.cc" />
+ <item id="iwa_bundle_downloader" added_in_milestone="116" type="completing" content_hash_code="03aab028" os_list="linux,windows,chromeos" semantics_fields="4,5,7,8,9" policy_fields="-1" file_path="components/webapps/isolated_web_apps/download/bundle_downloader.cc" />
  <item id="bidding_and_auction_server_key_fetch" added_in_milestone="116" content_hash_code="07667a22" os_list="linux,windows,android,chromeos" file_path="content/browser/interest_group/bidding_and_auction_server_key_fetcher.cc" />
  <item id="ip_protection_service_get_token" added_in_milestone="116" content_hash_code="0717bc1e" os_list="windows,android,linux,chromeos" file_path="components/ip_protection/common/ip_protection_config_http.cc" />
  <item id="supervised_user_request_blocked_site_permission" added_in_milestone="116" content_hash_code="04f49427" os_list="linux,windows,android,chromeos" file_path="components/supervised_user/core/browser/fetcher_config.cc" />
diff --git a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
index 6220bfc1..5d10b10 100644
--- a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
+++ b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
@@ -42,7 +42,6 @@
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.Callback;
 import org.chromium.base.ContextUtils;
-import org.chromium.base.DeviceInfo;
 import org.chromium.base.Log;
 import org.chromium.base.ObserverList;
 import org.chromium.base.PackageManagerUtils;
@@ -296,13 +295,10 @@
     }
 
     private boolean shouldTrackOcclusion() {
-        // Enable occlusion only for desktop Android. For non-desktop Android, occlusion signals
-        // from Android should be the same as the Activity lifecycle signals that already control
-        // web contents occlusion. Also, on rotate Android seems to send a spurious occlusion
-        // signal. See crbug.com/380209799 for details.
+        // On rotate Android seems to send a spurious occlusion signal. See crbug.com/380209799 for
+        // details.
         return mTrackOcclusion
                 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM
-                && DeviceInfo.isDesktop()
                 && UiAndroidFeatureList.sAndroidWindowOcclusion.isEnabled();
     }
 
diff --git a/ui/views/accessibility/view_ax_platform_node_delegate_unittest.cc b/ui/views/accessibility/view_ax_platform_node_delegate_unittest.cc
index 9df9640..3f0dfeb 100644
--- a/ui/views/accessibility/view_ax_platform_node_delegate_unittest.cc
+++ b/ui/views/accessibility/view_ax_platform_node_delegate_unittest.cc
@@ -1122,17 +1122,22 @@
 }
 
 TEST_F(ViewAXPlatformNodeDelegateTest, SetIsEnabled) {
-  // Initially, the button should be enabled.
+  // Initially, the button and label should be enabled.
   EXPECT_TRUE(button_accessibility()->GetIsEnabled());
   EXPECT_TRUE(button_accessibility()->IsAccessibilityFocusable());
+  EXPECT_TRUE(label_accessibility()->GetIsEnabled());
 
   button_->SetEnabled(false);
   EXPECT_FALSE(button_accessibility()->GetIsEnabled());
   EXPECT_FALSE(button_accessibility()->IsAccessibilityFocusable());
+  // child label should be disabled for accessibility, as child of disabled
+  // button.
+  EXPECT_FALSE(label_accessibility()->GetIsEnabled());
 
   button_->SetEnabled(true);
   EXPECT_TRUE(button_accessibility()->GetIsEnabled());
   EXPECT_TRUE(button_accessibility()->IsAccessibilityFocusable());
+  EXPECT_TRUE(label_accessibility()->GetIsEnabled());
 
   // `ViewAccessibility::SetIsEnabled` should have priority over
   // `View::SetEnabled`.
@@ -1147,6 +1152,8 @@
   EXPECT_TRUE(button_accessibility()->GetIsEnabled());
   EXPECT_TRUE(button_accessibility()->IsAccessibilityFocusable());
 
+  // Restore button original state.
+  button_->SetEnabled(true);
   // Initially, the label should be enabled. It should never be focusable
   // because it is not an interactive control like the button.
   EXPECT_TRUE(label_accessibility()->GetIsEnabled());
diff --git a/ui/views/view.cc b/ui/views/view.cc
index b4bc17a..56e3879 100644
--- a/ui/views/view.cc
+++ b/ui/views/view.cc
@@ -697,9 +697,7 @@
   }
 
   enabled_ = enabled;
-  GetViewAccessibility().SetIsEnabled(enabled);
-
-  AdvanceFocusIfNecessary();
+  UpdateEnabledInViewsSubtreeState();
   OnPropertyChanged(&enabled_, kPropertyEffectsPaint);
 }
 
@@ -708,6 +706,17 @@
   return AddPropertyChangedCallback(&enabled_, std::move(callback));
 }
 
+bool View::GetEnabledInViewsSubtree() const {
+  return enabled_in_views_subtree_;
+}
+
+[[nodiscard]] base::CallbackListSubscription
+View::AddEnabledInViewsSubtreeChangedCallback(
+    PropertyChangedCallback callback) {
+  return AddPropertyChangedCallback(&enabled_in_views_subtree_,
+                                    std::move(callback));
+}
+
 View::Views View::GetChildrenInZOrder() {
   if (HasLayoutManager()) {
     const auto result = GetLayoutManager()->GetChildViewsInPaintOrder(this);
@@ -1635,6 +1644,15 @@
   return false;
 }
 
+void View::OnEvent(ui::Event* event) {
+  if (!GetEnabledInViewsSubtree()) {
+    // if this view or any of it parent is disabled, we should "eat" events
+    // without processing
+    return;
+  }
+  ui::EventHandler::OnEvent(event);
+}
+
 void View::OnKeyEvent(ui::KeyEvent* event) {
   bool consumed = (event->type() == ui::EventType::kKeyPressed)
                       ? OnKeyPressed(*event)
@@ -1812,7 +1830,8 @@
 
 bool View::CanHandleAccelerators() const {
   const Widget* widget = GetWidget();
-  if (!GetEnabled() || !IsDrawn() || !widget || !widget->IsVisible()) {
+  if (!GetEnabledInViewsSubtree() || !IsDrawn() || !widget ||
+      !widget->IsVisible()) {
     return false;
   }
 #if BUILDFLAG(ENABLE_DESKTOP_AURA)
@@ -1975,8 +1994,8 @@
 }
 
 bool View::IsFocusable() const {
-  return GetFocusBehavior() == FocusBehavior::ALWAYS && GetEnabled() &&
-         IsDrawn();
+  return GetFocusBehavior() == FocusBehavior::ALWAYS &&
+         GetEnabledInViewsSubtree() && IsDrawn();
 }
 
 FocusManager* View::GetFocusManager() {
@@ -3055,6 +3074,7 @@
   }
 
   view->PropagateAddNotifications(details, widget && widget != old_widget);
+  view->UpdateEnabledInViewsSubtreeState();
 
   UpdateTooltip();
 
@@ -3343,6 +3363,25 @@
   has_default_fill_layout_ = true;
 }
 
+void View::UpdateEnabledInViewsSubtreeState() {
+  bool new_state = GetEnabled();
+  if (parent() && !parent()->GetEnabledInViewsSubtree()) {
+    // Inherit disabled state from parent.
+    new_state = false;
+  }
+  if (enabled_in_views_subtree_ == new_state) {
+    return;
+  }
+  enabled_in_views_subtree_ = new_state;
+  GetViewAccessibility().SetIsEnabled(enabled_in_views_subtree_);
+  AdvanceFocusIfNecessary();
+  internal::ScopedChildrenLock lock(this);
+  for (views::View* child : base::Reversed(children_)) {
+    child->UpdateEnabledInViewsSubtreeState();
+  }
+  OnPropertyChanged(&enabled_in_views_subtree_, kPropertyEffectsPaint);
+}
+
 void View::SetLayerBounds(const gfx::Size& size,
                           const LayerOffsetData& offset_data) {
   const gfx::Rect bounds = gfx::Rect(size) + offset_data.offset();
@@ -3873,6 +3912,7 @@
 ADD_PROPERTY_METADATA(std::unique_ptr<Border>, Border)
 ADD_READONLY_PROPERTY_METADATA(std::string_view, ClassName)
 ADD_PROPERTY_METADATA(bool, Enabled)
+ADD_READONLY_PROPERTY_METADATA(bool, EnabledInViewsSubtree)
 ADD_PROPERTY_METADATA(View::FocusBehavior, FocusBehavior)
 ADD_PROPERTY_METADATA(bool, FlipCanvasOnPaintForRTLUI)
 ADD_PROPERTY_METADATA(int, Group)
diff --git a/ui/views/view.h b/ui/views/view.h
index 4e53169..b3fa15b 100644
--- a/ui/views/view.h
+++ b/ui/views/view.h
@@ -711,6 +711,16 @@
   [[nodiscard]] base::CallbackListSubscription AddEnabledChangedCallback(
       PropertyChangedCallback callback);
 
+  // Returns whether the views subtree is enabled.
+  // "true" means: This view AND ALL ancestor views are enabled.
+  // "false" means: This view OR ANY of ancestor views is disabled.
+  bool GetEnabledInViewsSubtree() const;
+
+  // Adds a callback associated with the above |EnabledInViewsSubtree| property.
+  // The callback will be invoked whenever the property changes.
+  [[nodiscard]] base::CallbackListSubscription
+  AddEnabledInViewsSubtreeChangedCallback(PropertyChangedCallback callback);
+
   // Returns the child views ordered in reverse z-order. That is, views later in
   // the returned vector have a higher z-order (are painted later) than those
   // early in the vector. The returned vector has exactly the same number of
@@ -1309,6 +1319,7 @@
   gfx::PointF GetScreenLocationF(const ui::LocatedEvent& event) const override;
 
   // Overridden from ui::EventHandler:
+  void OnEvent(ui::Event* event) override;
   void OnKeyEvent(ui::KeyEvent* event) override;
   void OnMouseEvent(ui::MouseEvent* event) override;
   void OnScrollEvent(ui::ScrollEvent* event) override;
@@ -2165,6 +2176,8 @@
 
   void SetToDefaultFillLayout();
 
+  void UpdateEnabledInViewsSubtreeState();
+
   // Transformations -----------------------------------------------------------
 
   // Returns in |transform| the transform to get from coordinates of |ancestor|
@@ -2413,6 +2426,9 @@
   // Whether this view is enabled.
   bool enabled_ = true;
 
+  // Whether this view is enabled in views subtree.
+  bool enabled_in_views_subtree_ = true;
+
   // When this flag is on, a View receives a mouse-enter and mouse-leave event
   // even if a descendant View is the event-recipient for the real mouse
   // events. When this flag is turned on, and mouse moves from outside of the
diff --git a/ui/views/view_targeter_delegate.cc b/ui/views/view_targeter_delegate.cc
index 811d7b6..fb42e94 100644
--- a/ui/views/view_targeter_delegate.cc
+++ b/ui/views/view_targeter_delegate.cc
@@ -46,7 +46,7 @@
   View::Views children = root->GetChildrenInZOrder();
   DCHECK_EQ(root->children().size(), children.size());
   for (views::View* child : base::Reversed(children)) {
-    if (!child->GetCanProcessEventsWithinSubtree() || !child->GetEnabled()) {
+    if (!child->GetCanProcessEventsWithinSubtree()) {
       continue;
     }
 
diff --git a/ui/views/view_targeter_unittest.cc b/ui/views/view_targeter_unittest.cc
index 99c9625..7bd577db 100644
--- a/ui/views/view_targeter_unittest.cc
+++ b/ui/views/view_targeter_unittest.cc
@@ -40,6 +40,15 @@
   bool TestDoesIntersectRect(const View* target, const gfx::Rect& rect) const {
     return DoesIntersectRect(target, rect);
   }
+
+  bool OnMousePressed(const ui::MouseEvent& event) override {
+    ++mouse_press_count_;
+    return false;
+  }
+  int mouse_press_count() const { return mouse_press_count_; }
+
+ private:
+  int mouse_press_count_ = 0;
 };
 
 BEGIN_METADATA(TestingView)
@@ -653,5 +662,47 @@
   EXPECT_EQ(child, targeter->FindTargetForEvent(root_view, &tap));
 }
 
+TEST_F(ViewTargeterTest, DisabledViewShouldBlockEvents) {
+  auto widget = std::make_unique<Widget>();
+  Widget::InitParams init_params = CreateParams(
+      Widget::InitParams::CLIENT_OWNS_WIDGET, Widget::InitParams::TYPE_POPUP);
+  init_params.bounds = gfx::Rect(0, 0, 200, 200);
+  widget->Init(std::move(init_params));
+
+  View* content = widget->SetContentsView(std::make_unique<View>());
+  content->SetBounds(0, 0, 50, 50);
+  View* child_enabled = content->AddChildView(std::make_unique<View>());
+  TestingView* child_disabled =
+      content->AddChildView(std::make_unique<TestingView>());
+  child_disabled->SetEnabled(false);
+
+  const gfx::Rect child_bounds(2, 2, 50, 50);
+  // Disabled child fully overlaps enabled child.
+  child_enabled->SetBoundsRect(child_bounds);
+  child_disabled->SetBoundsRect(child_bounds);
+
+  internal::RootView* root_view =
+      static_cast<internal::RootView*>(widget->GetRootView());
+  auto* targeter = static_cast<views::ViewTargeter*>(root_view->targeter());
+
+  gfx::Rect event_bounds = child_disabled->bounds();
+  event_bounds.ClampToCenteredSize({10, 10});
+  const views::View* target_view =
+      targeter->TargetForRect(root_view, event_bounds);
+  // Overrlapped (by disabled view) child view should not be target for event.
+  EXPECT_NE(child_enabled, target_view);
+  // Parent view should not be target for event.
+  EXPECT_NE(content, target_view);
+
+  // Disabled view should be target for event.
+  EXPECT_EQ(child_disabled, target_view);
+
+  ui::MouseEvent event(ui::EventType::kMousePressed, gfx::Point(10, 10),
+                       gfx::Point(10, 10), ui::EventTimeForNow(), 0, 0);
+  child_disabled->OnEvent(&event);
+  // Disabled view should ignore events.
+  EXPECT_EQ(0, child_disabled->mouse_press_count());
+}
+
 }  // namespace test
 }  // namespace views
diff --git a/ui/views/view_unittest.cc b/ui/views/view_unittest.cc
index c6fdbfb..76777c23 100644
--- a/ui/views/view_unittest.cc
+++ b/ui/views/view_unittest.cc
@@ -6785,6 +6785,29 @@
   EXPECT_FALSE(test_view->GetEnabled());
 }
 
+TEST_F(ViewTest, TestEnabledInViewsSubtreeChangedCallback) {
+  auto test_view = std::make_unique<View>();
+  auto* test_child = test_view->AddChildView(std::make_unique<View>());
+  int enabled_vs_changed_count = 0;
+  auto callback = base::BindRepeating(
+      [](int* enabled_vs_changed_count) { ++(*enabled_vs_changed_count); },
+      &enabled_vs_changed_count);
+  auto subscription_1 =
+      test_view->AddEnabledInViewsSubtreeChangedCallback(callback);
+  auto subscription_2 =
+      test_child->AddEnabledInViewsSubtreeChangedCallback(callback);
+  test_view->SetEnabled(false);
+  EXPECT_EQ(2, enabled_vs_changed_count);
+
+  EXPECT_FALSE(test_view->GetEnabled());
+  EXPECT_FALSE(test_view->GetEnabledInViewsSubtree());
+
+  // The child view should save its enabled state, but should be in disabled
+  // visual state.
+  EXPECT_TRUE(test_child->GetEnabled());
+  EXPECT_FALSE(test_child->GetEnabledInViewsSubtree());
+}
+
 TEST_F(ViewTest, TestVisibleChangedCallback) {
   auto test_view = std::make_unique<View>();
   bool visibility_changed = false;
diff --git a/ui/views/widget/root_view.cc b/ui/views/widget/root_view.cc
index e9c418a..542ccf03 100644
--- a/ui/views/widget/root_view.cc
+++ b/ui/views/widget/root_view.cc
@@ -221,7 +221,7 @@
       v = owner_->GetFocusManager()->GetFocusedView();
     }
     // Special case to handle keyboard-triggered context menus.
-    if (v && v->GetEnabled() &&
+    if (v && v->GetEnabledInViewsSubtree() &&
         ((event->key_code() == ui::VKEY_APPS) ||
          (event->key_code() == ui::VKEY_F10 && event->IsShiftDown()))) {
       // Clamp the menu location within the visible bounds of each ancestor view
@@ -265,6 +265,9 @@
     }
 
     View* target = static_cast<View*>(event->target());
+    if (!target->GetEnabledInViewsSubtree()) {
+      return;
+    }
 
     gfx::Point location = event->location();
     if (touch_dnd_enabled_ &&
@@ -538,7 +541,6 @@
        mouse_pressed_handler_ = mouse_pressed_handler_->parent()) {
     DVLOG(1) << "OnMousePressed testing "
              << mouse_pressed_handler_->GetClassName();
-    DCHECK(mouse_pressed_handler_->GetEnabled());
 
     // See if this view wants to handle the mouse press.
     ui::MouseEvent mouse_pressed_event(event, static_cast<View*>(this),
@@ -860,7 +862,7 @@
   // disabled while handling moves, it's wrong to suddenly send
   // EventType::kMouseExited and EventType::kMouseEntered events, because the
   // mouse hasn't actually exited yet.
-  if (mouse_move_handler_ && !mouse_move_handler_->GetEnabled() &&
+  if (mouse_move_handler_ && !mouse_move_handler_->GetEnabledInViewsSubtree() &&
       v->Contains(mouse_move_handler_)) {
     v = mouse_move_handler_;
   }
diff --git a/v8 b/v8
index c7e3044..e26dcb6 160000
--- a/v8
+++ b/v8
@@ -1 +1 @@
-Subproject commit c7e3044597527a99e33d7f08695ac0229c8d8da1
+Subproject commit e26dcb68002a524d342cbac01e8e605dbea7e18a